[cmake-developers] Setting the link interface and dependencies in one command

Clinton Stimpson clinton at elemtech.com
Sun Oct 2 00:51:55 EDT 2011


On Oct 1, 2011, at 4:48 PM, Rolf Eike Beer wrote:

> On Sa.,   1. Okt. 2011 18:40:09 CEST, Alexander Neundorf <neundorf at kde.org> wrote:
> 
>> If library bar internally uses symbols from foo,
>> it needs to link against foo.
> 
> Correct.
> 
>> But if bar doesn't expose symbols from foo in its
>> interface, and my executable   hello links against bar, it doesn't also
>> have to be linked against foo. This saves startup time and other things.
>> Packagers also like that.
> 
> No, you got something wrong here. Packagers hate that. That's exactly the reason why e.g. Fedora and others introduced -Wl,no-unneeded (or how that's called) in their default linker flags.
> 
> If your hello needs foo and bar, and is only linked to bar because that one is already linked against foo, that your package will not work any longer if you replace foo 1.0 with foo 1.1 which is totally binary compatible but doesn't need foo internally any longer because your hello then misses symbols on startup. This is called unterlinking of hello and should be avoided whereever possible.
> 
> The opposite is overlinking and that was what I tried to avoid: my hello did not need any symbols from foo itself, so I wanted to get rid of them (which worked by forcing the implicit dependencies to empty). But CMake still did not want to allow me to export the bar target without also exporting foo even if the linkage to foo was only an internal detail and the user was not even allowed to use foo directly.


Can you consider this example as a demonstration for why cmake wants information about foo in the exports file even though its an internal detail?

project(test)
set(CMAKE_SKIP_RPATH 1)

add_library(foo SHARED test.cpp)
set_target_properties(foo PROPERTIES LIBRARY_OUTPUT_DIRECTORY "foo")

add_library(bar SHARED test.cpp)
target_link_libraries(bar foo)
set_target_properties(bar PROPERTIES LIBRARY_OUTPUT_DIRECTORY "bar" LINK_INTERFACE_LIBRARIES "")

add_executable(baz test.cpp)
# 1) link giving target name
#target_link_libraries(baz bar)
# 2) link giving the path to the library
target_link_libraries(baz "${CMAKE_CURRENT_BINARY_DIR}/bar/libbar.so")

If I do #2, I get a link warning 
/usr/bin/ld: warning: libfoo.so, needed by bar/libbar.so, not found (try using -rpath or -rpath-link)

If I do #1, then I don't get that warning and if I turn on verbose output, I see that cmake wasn't linking foo into baz anyway.  Apparently the linker wants to have a look at dependent shared libraries, and cmake is using the -rpath-link flag for that.
This information is passed into the exports file, and cmake needs the dependent shared libraries for that.

Clint




More information about the cmake-developers mailing list