[CMake] intercomponent link dependencies?

Michael Wild themiwi at gmail.com
Wed Jan 13 08:03:37 EST 2010


On 13. Jan, 2010, at 13:51 , Nico Schlömer wrote:

>> Overlinking is actually only an issue for dynamic libraries. So as long as you're absolutely sure that you only have static libraries, you're fine.
> 
> Oh, I was thinking it is *unclean* to have a link line like
> 
> -llibrarya /usr/local/local/liblapack.a --llibraryb
> /usr/local/local/liblapack.a     (1)
> 
> -- which (disappointingly?) is exactly what happens now that I have
> FindLibraryA.cmake and FindLibraryB.cmake, both equipped with
> 
>  SET_TARGET_PROPERTIES(A PROPERTIES
>                         IMPORTED_LOCATION "${A_LIBRARY}"
>                         IMPORTED_LINK_INTERFACE_LIBRARIES
> "${A_LINK_INTERFACE_LIBRARIES}"
>                       )
> 
> where both ${A_LINK_INTERFACE_LIBRARIES} and
> ${B_LINK_INTERFACE_LIBRARIES} contain /usr/local/local/liblapack.a.


No, for static linking you often NEED to specify a library multiple times, e.g. if you have mutually dependent libraries.

Problem with static linking is this: The linker keeps a running list of unresolved symbols. Then, when a static library comes along, it tries to resolve as many symbols as possible, but ONLY takes the required ones, discarding the ones not used. If the newly imported symbols again contain unresolved references, they are added to the list. And then it continues its way until the input is exhausted. If all the symbols are now resolved, everything is fine, otherwise it will complain to the user.

So, in static linking the ordering on the command line is important, and if you have mutually dependent libraries, you might need to list some libraries multiple times. The thing which works for me (usually) is this:

gcc -o myexe src1.o src2.o src3.o /usr/lib/liba.a /usr/lib/libb.a /usr/libc.a /usr/lib/libb.a /usr/lib/liba.a

As you can see, the libraries are listed as  a b c b a such that if b and c need symbols from a, they appear after a (the same for c needing symbols from b). If a needs symbols from b or c, that is covered in the "first" pass.

With static linking, the linker just picks what is needed. No information is retained from which library these symbols came (after all, they are now part of the final product)

> 
> 
>> Does the IMPORTED_LINK_INTERFACE_LIBRARIES thing work?
> So, yeap, it works, but I expected CMake to clean up after me
> dependency-wise -- instead of (1), this
> 
> -llibrarya --llibraryb /usr/local/local/liblapack.a     (1')

You shouldn't use -l flag, better specify the full path (CMake automatically adds the -l flag if a library name is not a target or a path). Further, I either it's a typo or really strange, but when using -l, the lib prefix must be dropped (and the --l is definitely a typo).

> 
> would be sufficient. My knowledge on the linking process itself is
> unfortunately not deep enough to tell if that makes an actual
> difference.
> 

In your case, it might be, but that CMake can't know that (as I explained above).

HTH

Michael



More information about the CMake mailing list