We have four CMakeLists.txt instances to look at: one root and tree leaves. Let us start with the root CMakeLists.txt:
- We declare a mixed-language Fortran and C project:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-01 LANGUAGES Fortran C)
- We direct CMake to save static and shared libraries under the lib subdirectory of the build directory. Executables will be saved under bin, while Fortran compiled module files will be saved under modules:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
set(CMAKE_Fortran_MODULE_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}/modules)
- Next, we move on to the first leaf, CMakeLists.txt, by adding the src subdirectory:
add_subdirectory(src)
- The src/CMakeLists.txt file adds two more subdirectories:
add_subdirectory(interfaces)
add_subdirectory(utils)
In the interfaces subdirectory, we do the following:
- We include the FortranCInterface.cmake module and verify that the C and Fortran compilers can talk properly to each other:
include(FortranCInterface)
FortranCInterface_VERIFY()
- Next, we find the backtrace system library, since we want to use it within our Fortran code:
find_package(Backtrace REQUIRED)
- We then create a shared library target with the source files for the backtrace wrapper, the random number generator, and its Fortran wrapper:
add_library(bt-randomgen-wrap SHARED "")
target_sources(bt-randomgen-wrap
PRIVATE
interface_backtrace.f90
interface_randomgen.f90
randomgen.c
)
- We also set the link libraries for the newly generated library target. We use the PUBLIC attribute, so that additional targets linking to our libraries will see dependencies properly:
target_link_libraries(bt-randomgen-wrap
PUBLIC
${Backtrace_LIBRARIES}
)
In the utils subdirectory, we have one more CMakeLists.txt. This is a one-liner: we create a new library target into which the source file in this subdirectory will be compiled. There are no dependencies for this target:
add_library(utils SHARED util_strings.f90)
Let us return to src/CMakeLists.txt:
- We add an executable target, with bt-randomgen-example.f90 as source file:
add_executable(bt-randomgen-example bt-randomgen-example.f90)
- Finally, we link the library targets, generated in the CMakeLists.txt leaf, into our executable target:
target_link_libraries(bt-randomgen-example
PRIVATE
bt-randomgen-wrap
utils
)