I have a project with a directory structure that looks like this
└── Project/
├── build/
│ ├── common/
│ ├── case/
│ └── case2/
├── common/
│ ├── CMakeLists.txt
│ └── Mod*.F90
├── examples/
│ ├── case/
│ │ ├── CMakeLists.txt
│ │ ├── exe1.F90
│ │ └── exe2.F90
│ └── case2/
│ ├── exe3.F90
│ └── exe4.F90
└── CMakeLists.txt
I'm writing a CMakeLists.txt to compile the project. I want to be able to run make common
and make case
on each case inside Project/build
separately, so my build directory should look like that, but I'm having trouble implementing this version. Currently, only trying to handle Projects/case
and will extend it once that works.
This is the part of Project/CMakeLists.txt
that handles that. I've been trying to follow this
add_subdirectory(common)
install(TARGETS common LIBRARY DESTINATION "bin")
add_subdirectory(examples/case case)
This is Project/common/CMakeLists.txt
:
file(GLOB common_F90s "*.F90")
add_library(common "${common_F90s}")
target_include_directories(common PRIVATE ${PETSC_INCLUDE_DIRS} ${NETCDF_INCLUDE})
target_link_libraries(common PRIVATE ${PETSC_LINK_LIBRARIES} ${SPHPK_LIB} ${FFTW_LIB} ${NETCDF_LIB})
And this is Project/examples/case
:
file(GLOB case_F90s "*.F90")
cmake_print_variables(case_F90s)
foreach(F90_filepath ${case_F90s})
get_filename_component(file_target ${F90_filepath} NAME_WE)
add_executable(${file_target} ${F90_filepath})
cmake_print_variables(file_target)
target_include_directories(${file_target} PRIVATE ${PETSC_INCLUDE_DIRS})
target_link_libraries(${file_target} PRIVATE common ${PETSC_LINK_LIBRARIES})
message("HERE")
endforeach()
Executing make
in Project/build
makes common
successfully, but results in a similar error for all of the case
F90 files of not being able to find common
modules. Also, make common
works but not make case
for some reason.
[ 90%] Building Fortran object CMakeFiles/initcond.dir/examples/case/initcond.F90.o
~Project/examples/case/initcond.F90:4:7:
4 | use ModDataTypes
| 1
Fatal Error: Cannot open module file 'moddatatypes.mod' for reading at (1): No such file or directory
compilation terminated.
make[2]: *** [CMakeFiles/initcond.dir/examples/case/initcond.F90.o] Error 1
make[1]: *** [CMakeFiles/initcond.dir/all] Error 2
This old version with no nested CMakeLists.txt
works for Projects/case
, but I can't make cases individually. Any ideas on how to resolve this?
# build common
file(GLOB common_F90s "common/*.F90")
add_library(common "${common_F90s}")
target_include_directories(common PRIVATE ${PETSC_INCLUDE_DIRS} ${NETCDF_INCLUDE})
target_link_libraries(common PRIVATE ${PETSC_LINK_LIBRARIES} ${SPHPK_LIB} ${FFTW_LIB} ${NETCDF_LIB})
file(GLOB case_F90s "examples/case/*.F90")
foreach(F90_filepath ${case_F90s})
get_filename_component(file_target ${F90_filepath} NAME_WE)
add_executable(${file_target} ${F90_filepath})
target_include_directories(${file_target} PRIVATE ${PETSC_INCLUDE_DIRS})
target_link_libraries(${file_target} PRIVATE common ${PETSC_LINK_LIBRARIES})
message("HERE")
endforeach()
I've tried changing this line add_library(common "${common_F90s}")
of Project/common/CMakeLists.txt
to STATIC or SHARED, but SHARED results in errors and STATIC does not help.
Adding this to my top-level CMake file include_directories("${CMAKE_CURRENT_BINARY_DIR}/common")
fixed it.