CMake Fortran design patterns
CMake is excellent for building very complex Fortran projects across operating systems and computing platforms from embedded systems to HPC. Here are a few common Fortran CMake patterns.
specify linker options for all targets using add_link_options()
add_link_options(-myflag)
or for a particular target (or static linkers) with
set_property(TARGET myexe PROPERTY STATIC_LIBRARY_OPTIONS -myflag)
For hand-written Makefile the order of libraries matters completely. CMake attempts to determine the graph for library files, starting from the user specified order. CMake will try a finite multiplicity to resolve the graph, but in tough cases of library interdependency library ordering may need to be influenced by add_dependencies() or even object libraries.
“Undefined reference to” occurs at linking of main executable: be sure the library is actually linked to the user library with
cmake --build build -v
Fortran module include: be sure the *.mod file directory is included, particularly to the main executable by setting the target properties like:
include(GNUInstallDirs)
target_include_directories(mymod INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
set_property(TARGET mymod PROPERTY Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
this can be done for numerous targets in a loop instead of repeatedly specifying by a foreach() loop:
foreach(t foo bar biz baz)
target_include_directories(${t} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
set_property(TARGET ${t} PROPERTY Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR})
endforeach()
To ensure the build system is completely updated, do
cmake --build build --clean-first