<html><head></head><body bgcolor="#FFFFFF"><div><br><br>On Nov 19, 2011, at 2:02 AM, James Bigler &lt;<a href="mailto:jamesbigler@gmail.com">jamesbigler@gmail.com</a>&gt; wrote:<br><br></div><div></div><blockquote type="cite"><div>On Fri, Nov 18, 2011 at 5:51 PM, Michael Hertling <span dir="ltr">&lt;<a href="mailto:mhertling@online.de">mhertling@online.de</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="HOEnZb"><div class="h5">On 11/18/2011 10:03 PM, James Bigler wrote:<br>
&gt; 2011/11/18 Alexander Neundorf &lt;<a href="mailto:a.neundorf-work@gmx.net">a.neundorf-work@gmx.net</a>&gt;<br>
&gt;<br>
&gt;&gt; On Friday 18 November 2011, James Bigler wrote:<br>
&gt;&gt;&gt; I thought CMake knew how to not drag all the dependent libraries once you<br>
&gt;&gt;&gt; linked an executable module.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; add_library(A STATIC a.cpp)<br>
&gt;&gt;&gt; add_library(B SHARED b.cpp)<br>
&gt;&gt;&gt; target_link_libraries(B A)<br>
&gt;&gt;&gt; add_library(C SHARED c.cpp)<br>
&gt;&gt;&gt; target_link_libraries(C B)<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; add_executable(run run.cpp)<br>
&gt;&gt;&gt; target_link_libraries(run C)<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; At this point I'm seeing that C links against B and A when I think it<br>
&gt;&gt;&gt; should only link against B since A shouldn't be needed to link against B.<br>
&gt;&gt;&gt; In addition when compiling run, it links against B and A.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; /usr/bin/c++ &nbsp; -dynamiclib -Wl,-headerpad_max_install_names &nbsp; -o<br>
&gt;&gt; libC.dylib<br>
&gt;&gt;&gt; -install_name /Users/jbigler/tmp/code/cmake/translinking/build/libC.dylib<br>
&gt;&gt;&gt; CMakeFiles/C.dir/c.cpp.o libB.dylib libA.a<br>
&gt;&gt;&gt; /usr/bin/c++ &nbsp; &nbsp;-Wl,-search_paths_first -Wl,-headerpad_max_install_names<br>
&gt;&gt;&gt; CMakeFiles/run.dir/run.cpp.o &nbsp;-o run &nbsp;libC.dylib libB.dylib libA.a<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Is this the expected behavior?<br>
&gt;&gt;<br>
&gt;&gt; Yes.<br>
&gt;&gt; If you want to limit this, use target_link_libraries( C<br>
&gt;&gt; LINK_INTERFACE_LIBRARIES ... ), with this you can specify the transitively<br>
&gt;&gt; linked libraries when linking against C.<br>
&gt;&gt;<br>
&gt;&gt; Alex<br>
&gt;&gt;<br>
&gt;<br>
&gt; OK, so propagating the libraries is the default behavior. &nbsp;I tried to use<br>
&gt; LINK_INTERFACE_LIBRARIES, but it only seemed to work for static libraries:<br>
&gt;<br>
&gt; add_library(A STATIC a.cpp)<br>
&gt; add_library(B SHARED b.cpp)<br>
&gt; target_link_libraries(B A)<br>
&gt; target_link_libraries(B LINK_INTERFACE_LIBRARIES)<br>
&gt; add_library(C SHARED c.cpp)<br>
&gt; target_link_libraries(C B)<br>
&gt; target_link_libraries(C LINK_INTERFACE_LIBRARIES)<br>
&gt;<br>
&gt; add_executable(run run.cpp)<br>
&gt; target_link_libraries(run C)<br>
&gt;<br>
&gt; During build:<br>
&gt;<br>
&gt; Build B (this is fine)<br>
&gt; /usr/bin/c++ &nbsp; -dynamiclib -o libB.dylib CMakeFiles/B.dir/b.cpp.o libA.a<br>
&gt; Build C (this is fine too, no A in the list)<br>
&gt; /usr/bin/c++ &nbsp; -dynamiclib -o libC.dylib CMakeFiles/C.dir/c.cpp.o libB.dylib<br>
&gt; Build run (this is weird, it linked both B and C)<br>
&gt; /usr/bin/c++ &nbsp; &nbsp;CMakeFiles/run.dir/run.cpp.o &nbsp;-o run &nbsp;libC.dylib libB.dylib<br>
&gt;<br>
&gt; Did I specify something wrong or does this property only consider static<br>
&gt; libraries?<br>
<br>
</div></div>On *nix, I can't confirm this:<br>
<br>
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)<br>
PROJECT(TRANSLINK CXX)<br>
SET(CMAKE_VERBOSE_MAKEFILE ON)<br>
FILE(WRITE ${CMAKE_BINARY_DIR}/a.cxx "void a(){}\n")<br>
ADD_LIBRARY(A STATIC a.cxx)<br>
FILE(WRITE ${CMAKE_BINARY_DIR}/b.cxx "void b(){}\n")<br>
ADD_LIBRARY(B SHARED b.cxx)<br>
TARGET_LINK_LIBRARIES(B A)<br>
TARGET_LINK_LIBRARIES(B LINK_INTERFACE_LIBRARIES)<br>
FILE(WRITE ${CMAKE_BINARY_DIR}/c.cxx "void c(){}\n")<br>
ADD_LIBRARY(C SHARED c.cxx)<br>
TARGET_LINK_LIBRARIES(C B)<br>
TARGET_LINK_LIBRARIES(C LINK_INTERFACE_LIBRARIES)<br>
FILE(WRITE ${CMAKE_BINARY_DIR}/main.cxx "int main(){}\n")<br>
ADD_EXECUTABLE(main main.cxx)<br>
TARGET_LINK_LIBRARIES(main C)<br>
<br>
The main target's link command line reads:<br>
<br>
.../c++ .../main.cxx.o -o main ... libC.so ... &nbsp;# No libB.so!<br>
<br>
Do you actually get different results with the above-noted project?<br>
<br>
In general, CMake's transitive handling of target dependencies causes<br>
no harm since no library is loaded unnecessarily, although there may be<br>
libraries which are specified unnecessarily. E.g., main would be linked<br>
against libB.so without immediately referring to the latter, i.e. it is<br>
formally overlinked, but whether libB.so is loaded on behalf of main or<br>
on behalf of libC.so does not matter, and overlinking w.r.t. a static<br>
library is not possible. Do you have particular requirements why you<br>
want to reduce a target's references to the immediate dependencies?<br>
<br>
Regards,<br>
<br>
Michael<br>
<span class="HOEnZb"><font color="#888888">--<br>
<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" target="_blank">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.cmake.org/mailman/listinfo/cmake" target="_blank">http://www.cmake.org/mailman/listinfo/cmake</a><br>
</font></span></blockquote></div><br>I tried your script, and it seems to exhibit the same behavior as my script:<br><br>/usr/bin/c++&nbsp;&nbsp;&nbsp; -Wl,-search_paths_first -Wl,-headerpad_max_install_names&nbsp;&nbsp; CMakeFiles/main.dir/main.cxx.o&nbsp; -o main&nbsp; libC.dylib libB.dylib <br>

<br>Perhaps this is some Mac specific behavior that isn't showing up on other systems.<br><br>The main reason I wanted it was to prevent build failures.&nbsp; I specified a library path (-L) in one subdirectory to correctly link in the set of external static libraries.</div></blockquote><div><br></div>Are you using "link_directories" to do this? If you used full paths to the libraries in target_link_libraries instead and avoid link_directories, then CMake would be able to construct the right link lines for you, even in other directories.<div><br></div><div>As Andreas pointed out in his other reply to this thread, CMake brings along all linked libs by default "just in case" -- not all developers are as careful as they should be when deciding what to expose from their shared libraries.</div><div><br></div><div><br></div><div>David</div><div><br></div><div><br><blockquote type="cite"><div>&nbsp; CMake tried to drag those libraries on to the "next" project which didn't have the library path and link failed.&nbsp; This is why I started to look into why those static libraries were linked in the first place.&nbsp; As far as I'm concerned once you link an executable module, you don't need its dependencies anymore.&nbsp; Those dependencies should be satisfied within the library itself.&nbsp; I'm not exactly sure why CMake implements this behavior by default, since it seems to go against the philosophy of shared library linkage.<br>

<br>BTW, since the LINK_INTERFACE_LIBRARIES seems to work for static libraries it did solve my immediate problem, but the behavior for the shared libraries seems wrong to me.<br><br>James<br>
</div></blockquote><blockquote type="cite"><div><span>--</span><br><span></span><br><span>Powered by <a href="http://www.kitware.com">www.kitware.com</a></span><br><span></span><br><span>Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html">http://www.kitware.com/opensource/opensource.html</a></span><br><span></span><br><span>Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ">http://www.cmake.org/Wiki/CMake_FAQ</a></span><br><span></span><br><span>Follow this link to subscribe/unsubscribe:</span><br><span><a href="http://www.cmake.org/mailman/listinfo/cmake">http://www.cmake.org/mailman/listinfo/cmake</a></span></div></blockquote></div></body></html>