Object libraries and the Ninja generator

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

There were a number of issues from a reworking of some dependency paths in the collation step (most/all discovered and reported by @scivision). Please try CMake 3.27.6.

Thanks! CMake version 3.27.6 does indeed resolve the issues I was having :+1: