I’m struggling with using the Ninja generator for a project that contains an object library. This seems to be exactly what’s been discussed in Issue 24411 and in How to add dependencies to an object library [for ninja generator]?. If I understand those posts correctly then the conclusion is that for object libraries, target_link_libraries
or add_dependencies
should only make a link time dependency between the object library and the target it depends on and not a compile time dependency.
For classic C++ projects this seems to be fair, but I cannot see that this is enough for a Fortran project where the compilation step of a library might produce .mod files which again might be needed by other sources which use
this module. I don’t know C++ modules well enough, but if I understand them correctly then this is an issue there as well.
So my questions are: Am I overseeing something or is this a limitation in the current CMake implementation of object libraries? Is there a way to force compilation of object library dependencies before the object library itself even for the Ninja generator?
Here’s a minimal example:
CMakeListst.txt:
cmake_minimum_required(VERSION 3.27 FATAL_ERROR)
project(objlib_test LANGUAGES Fortran)
add_library(static_lib STATIC static_lib.f90)
add_library(obj_lib OBJECT obj_lib.f90)
target_link_libraries(obj_lib static_lib)
static_lib.f90:
module static_lib
implicit none
integer, parameter :: answer = 42
end module
obj_lib.f90:
module obj_lib
use static_lib, only: answer
implicit none
private
public print_answer
contains
subroutine print_answer
write(*,*) 'The answer is ', answer
end subroutine
end module
Building obj_lib
with make
works:
$ cmake ../ && make obj_lib
-- The Fortran compiler identification is GNU 9.4.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /usr/bin/f95 - skipped
-- Configuring done (11.4s)
-- Generating done (0.2s)
-- Build files have been written to: /mnt/c/Users/palle/dev/fortran-cosimulation/test-proj/build/make
[ 33%] Building Fortran object CMakeFiles/static_lib.dir/static_lib.f90.o
[ 66%] Linking Fortran static library libstatic_lib.a
[ 66%] Built target static_lib
[100%] Building Fortran object CMakeFiles/obj_lib.dir/obj_lib.f90.o
[100%] Built target obj_lib
Building obj_lib
with ninja
fails:
$ cmake ../ -GNinja && ninja obj_lib
-- The Fortran compiler identification is GNU 9.4.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /usr/bin/f95 - skipped
-- Configuring done (10.5s)
-- Generating done (0.1s)
-- Build files have been written to: /mnt/c/Users/palle/dev/fortran-cosimulation/test-proj/build/ninja
[3/3] Building Fortran object CMakeFiles/obj_lib.dir/obj_lib.f90.o
FAILED: CMakeFiles/obj_lib.dir/obj_lib.f90.o obj_lib.mod
/usr/bin/f95 -I/mnt/c/Users/palle/dev/fortran-cosimulation/test-proj -fpreprocessed -c CMakeFiles/obj_lib.dir/obj_lib.f90-pp.f90
-o CMakeFiles/obj_lib.dir/obj_lib.f90.o
/mnt/c/Users/palle/dev/fortran-cosimulation/test-proj/obj_lib.f90:2:8:
2 | use static_lib, only: answer
| 1
Fatal Error: Cannot open module file ‘static_lib.mod’ for reading at (1): No such file or directory
compilation terminated.
ninja: build stopped: subcommand failed.
Note: Building the all
target with ninja
works in this case, but fails for my proper project.
Software versions I’ve used:
- CMake: 3.27.2
- Make: 4.2.1
- Ninja 1.10.2