5

We have a (C++) program that's set up as a series of shared libraries with a nested hierarchy. That is, libB.so uses functions from and thus links against libA.so, libC.so uses functions from and links against both libB.so and libA.so, etc.

For our current CMake+Ninja build system I've noticed that parallel building does not seem to happen across libraries. That is, while Ninja will normally use 12 cores to build, if I've touched a single source file from libA but multiple in libC, ninja will use only a single processor to build just the libA source file until libA.so is linked, at which point it will use 12 processors to compile the libC source files. - And if there's an error in compilation in the libA source, it won't even try to compile the libC files into object files, even if I pass -k to ninja.

Certainly, the linking of libC.so needs to be delayed until libA.so is linked, but the compilation of the source files into object files for the libC sources shouldn't need to be delayed for the linking of libA.

Is there something I'm missing about the optimal way to set up our CMake files to express the dependencies between the libraries? Or is this an insurmountable limitation of how Ninja works?

R.M.
  • 3,461
  • 1
  • 21
  • 41
  • I've noticed the same @R.M. Have you found a solution in the meantime? At first I thought perhaps ninja isn't sure whether compilation of libA is going to generate something that libC needs (perhaps header files). But I think this is only true in the case of a full rebuild (when the generated header files don't exist yet). And that case needs to be solved anyway by libC by depending on the target in libA that generates the header files. So I don't think that's the reason, but I can't come up with any suitable explanation – thelamb Jul 17 '16 at 11:31

1 Answers1

8

This was asked recently on the CMake mailing list. The response from one of the devs confirms that the behaviour you report is intentional:

This is unfortunately necessary to get correct builds for CMake projects in general because we support cases where add_custom_command is used in library "foo" to generate a header file that is included during compilation in library "bar" that links to "foo", but we have no good way to express this dependency besides the ordering dependency of bar on foo.

While it may be possible for CMake to be improved to relaxed that constraint in some circumstances, this doesn't appear to have been done yet (as of CMake 3.6). There's an open ticket for this in the Kitware issue tracker already.

Update: This appears to have been fixed in CMake 3.9.0, although that change led to a regression which was then subsequently fixed in 3.12.0, or possibly 3.11.2.

Erkin Alp Güney
  • 218
  • 6
  • 15
Craig Scott
  • 9,238
  • 5
  • 56
  • 85
  • Looks like this has now been fixed. – Adam Casey Jun 20 '17 at 11:01
  • do you know in what version? Thanks! – mystery_doctor Sep 05 '18 at 05:29
  • @mystery_doctor Answer updated with details about when it was fixed – Craig Scott Sep 05 '18 at 13:26
  • I had similar problems with CMake 3.18. Turns out this works only with ninja-build (https://gitlab.kitware.com/cmake/cmake/-/issues/20361). In addition it breaks when using Qt along with CMAKE_AUTOMOC/RCC/UIC ON). I don't need these tools in my project, so I just removed that setting and it started working. – Adam Dec 02 '20 at 22:09