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&#39;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&#39;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++   -dynamiclib -Wl,-headerpad_max_install_names   -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++    -Wl,-search_paths_first -Wl,-headerpad_max_install_names<br>
&gt;&gt;&gt; CMakeFiles/run.dir/run.cpp.o  -o run  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.  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++   -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++   -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++    CMakeFiles/run.dir/run.cpp.o  -o run  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&#39;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 &quot;void a(){}\n&quot;)<br>
ADD_LIBRARY(A STATIC a.cxx)<br>
FILE(WRITE ${CMAKE_BINARY_DIR}/b.cxx &quot;void b(){}\n&quot;)<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 &quot;void c(){}\n&quot;)<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 &quot;int main(){}\n&quot;)<br>
ADD_EXECUTABLE(main main.cxx)<br>
TARGET_LINK_LIBRARIES(main C)<br>
<br>
The main target&#39;s link command line reads:<br>
<br>
.../c++ .../main.cxx.o -o main ... libC.so ...  # No libB.so!<br>
<br>
Do you actually get different results with the above-noted project?<br>
<br>
In general, CMake&#39;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&#39;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++    -Wl,-search_paths_first -Wl,-headerpad_max_install_names   CMakeFiles/main.dir/main.cxx.o  -o main  libC.dylib libB.dylib <br>

<br>Perhaps this is some Mac specific behavior that isn&#39;t showing up on other systems.<br><br>The main reason I wanted it was to prevent build failures.  I specified a library path (-L) in one subdirectory to correctly link in the set of external static libraries.  CMake tried to drag those libraries on to the &quot;next&quot; project which didn&#39;t have the library path and link failed.  This is why I started to look into why those static libraries were linked in the first place.  As far as I&#39;m concerned once you link an executable module, you don&#39;t need its dependencies anymore.  Those dependencies should be satisfied within the library itself.  I&#39;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>