Fortran uses so-called mod files. They work similarly to a library. They are, however, important during compile stage of the objects. Now I am writing a CMake build for an older Fortran project. CMake luckily can recognise module dependencies. When CMake is compiling objects for a target they are stored in separed folder like:
CMakeFiles/target_name.dir/src/
Mod files are not. Instead, they are stored in the compiler execution directory. In order to make compile and link stage work I add:
target_include_directories( ${EXECUTABLE}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
So in the end *.o files are stored in separate directories and *.mod are in the build directory. This has worked well for me for some time. But now I have a project where it is not possible. I have multiple targets that are compiled out of the same source files using different precompiled options. There are no problems with *.o files because they are stored in separate directories. But if *.mod files are changed by these directives they cannot be stored in the same build directory.
I was thinking to move *.mod files into a separate directory after each compile stage and linking them with ${CMAKE_CURRENT_LIST_DIR}/PRECOMPILER_OPTION_A
, but still I would have a problem with race conditions if I would use parallel make.
Is there a solution where I can specify the compiler execution path per target? Or are you aware of some other solution that would work?
I found a solution here.
Basically the easiest solution is to manage Fortran_MODULE_DIRECTORY
separatly for each target:
add_library(A OBJECT source.f90)
set_target_properties(A PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/A)
target_include_directories(A PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/A)
add_library(B OBJECT source.f90)
set_target_properties(B PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/B)
target_include_directories(B PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/B)