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.

Linker options

specify linker options for all targets using add_link_options()

add_link_options(-myflag)

or for a particular target (or static linkers) with

set_target_properties(myexe PROPERTIES STATIC_LIBRARY_OPTIONS -myflag)

Order of libraries

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:

target_include_directories(mymod INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/include)
set_target_properties(mymod PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include)

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}/include)
  set_target_properties(${t} PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include)
endforeach()

To ensure the build system is completely updated, do

cmake --build build --clean-first