[CMake] How do you handle recursive dependencies in CMake

Sven Baars s.baars at rug.nl
Thu Jun 30 04:59:54 EDT 2016


This is a reply to the options that Ray gave. Here I will use the
package dependencies C -> B -> A{1,2}:

1)  The "ad-hoc" method I first mentioned by setting
CMAKE_LIBRARY_OUTPUT_DIRECTORY.

As far as I understand, this would mean that every user of all of the
different projects would have to be forced to use this, and would not be
allowed to "install" anything anywhere else, which doesn't seem nice.

2)  ExternalProject which will grab a repository and build it.

This will not work. One of the projects I use is Trilinos, which has
build of around 1GB. I don't want to pull and build that for every
project I have. Also the build flags that are used sometimes differ per
machine, not per project, so it would be nice if I could build it only
once per machine.

Also, in a more generalized sense, this would also mean that every
project I pull with ExtenalProject should also pull its own dependencies
with ExternalProject. So then if every project on my system used CMake,
this would mean that I would recursively rebuild my entire system for
every project I have. This doesn't seem right.

3)  Some Find_Package () mechanism that will do a search for it.

The point I had is that we actually try to use this. However, the
find_package does not find all dependencies. And we don't know in
package C whether it depends on A1 or A2, because of build flags/CMake
checks that were used for project B. So we can't just do a find_package
for either A1 or A2, because we don't know which one was used unless we
perform all the CMake checks that were done in project B (in some cases
10k+ lines of CMake code).

4)  Your option of including *.cmake files that provide the paths
[sorry, I might have misunderstood it].

This, so far, is the only option, because then B can tell us that it
used A2, not A1. This can just be done by providing absolute paths to
the libraries that were used in the compilation of B. But we are looking
for a standardized way to do this. I'd prefer to not have a lot of
custom code in all of my libraries.

Now some more information:

On supercomputers it is very common that every library on the system is
installed in a different directory. This is so every user can load their
own version of the library without breaking the system for others.
Therefore, you will never find libraries that are installed in the
standard system directories where CMake looks for the libraries. By
using PATH you can make it able to find the place where to look for the
FoobarConfig.cmake files, which is great when you want to build project
B, and this is also done automatically on all supercomputers I work on,
but those config files do not contain information on where the actual
libraries of project A are when you build project C. I guess Cfyz and me
think they should in some standardized way.

Sven


More information about the CMake mailing list