[CMake] Problem on an "external" library depending on an "internal" one

Marco Corvo marco.corvo at pd.infn.it
Thu Dec 22 13:08:38 EST 2011


Hi all,

I have a big project which can be used in two ways: either the user 
checks out all the packages and makes a big "make" or he checks out only 
a subset and build them linking against a given release, which is 
installed somewhere else on his machine.

In this last option the libraries "installed somewhere" are trated as 
"external" dependencies by the working packages. The problem I have 
comes out when I have a transitive dependency.
To make an example, I check out two packages: package A, which builds a 
static library and a binary and depends on an external library B, and a 
package C.
The cmake code to make A know where to find libB.a is the following:

add_library(B STATIC IMPORTED)
set_target_properties(B PROPERTIES IMPORTED_LOCATION 
"/path/to/external/lib/libB.a"
IMPORTED_LINK_INTERFACE_LIBRARIES "C D"
)

which is read inside my CMakeLists.txt with:

import(MyFile.cmake)
add_library(A foo.cc)
add_executable(bar bar.cc)
target_link_libraries(bar A B)

Here's the point. My library B depends on C, which I checked out with A 
and so is kind of "local" to my build, in fact I have:

add_directory(A)
add_directory(C)

in my main CMakeLists.txt, but when I build the packages I always get:

No rule to make target `../../lib/libC.a', needed by `../../bin/bar'.  Stop.

Looking into the link.txt file generated by cmake, I see that the 
dependencies are correct, that is the command is:

g++ .... -o bar ../../lib/libA.a /path/to/external/lib/libB.a 
../../lib/libC.a /path/to/external/lib/libD.a

So this is not a problem of how I declare my dependencies among 
packages, rather something related to the way cmake deals with the 
targets. What sounds strange to me is that package C is perfectly known 
to cmake, as I put add_directory(C) to my CMakeLists.txt. In fact libC.a 
is built, but always *after* bar, like cmake were not aware that C, on 
which bar depends, must be built before it.

I suspect that cmake thinks that, since B is "external", it's up to the 
user to provide a rule to force the build of dependencies. Put it 
another way: if you have packages A and C locally and B is an "external" 
but depends on C, then cmake has no means to write the target libC.a 
that triggers the build of C before linking A with B.

Is there a way, if any, to instruct cmake to write the targets so that 
the dependencies chain is preserved and if an external depends on an 
internal, the internal is built before the link stage?

Thanks in advance.

Marco

-- 
Marco Corvo
SuperB Experiment
CNRS - Orsay
c/o INFN Padova



More information about the CMake mailing list