<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jun 15, 2019 at 5:01 PM Paul Smith <<a href="mailto:paul@mad-scientist.net">paul@mad-scientist.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I have a situation where I create a number of static libraries, then I<br>
create a shared library from them, then I create an executable from the<br>
shared library.<br>
<br>
This seems straightforward, but I can't get it do work as I want.  The<br>
behavior of STATIC -> SHARED for target property inheritance seems<br>
incorrect to me.<br>
<br>
I'm using CMake 3.14.5 on GNU/Linux for this test.<br>
<br>
I need the compile properties of the static library (include<br>
directories etc.) to be public for all users of the shared library as<br>
well.  But obviously I don't want users of the shared library to also<br>
link the static library!!  That defeats the whole purpose of the shared<br>
library.<br>
<br>
If I set up like this:<br>
<br>
  $ touch foo.c bar.c<br>
  $ echo 'int main() { return 0; }' > run.c<br>
<br>
then write my CMakeFiles.txt like this:<br>
<br>
  cmake_minimum_required(VERSION 3.13)<br>
  project(Test C)<br>
<br>
  add_library(foo STATIC foo.c)<br>
  target_include_directories(foo PUBLIC /tmp)<br>
<br>
  add_library(bar SHARED bar.c)<br>
  target_link_libraries(bar PUBLIC foo)<br>
<br>
  add_executable(run run.c)<br>
  target_link_libraries(run PUBLIC bar)<br>
<br>
Then, I DO get the -I/tmp forwarded up to run.c:<br>
<br>
  cc -I/tmp -o CMakeFiles/run.dir/run.c.o -c run.c<br>
     ^^^^^^<br>
<br>
But libfoo.a is ALSO added to my link line, which is really wrong!<br>
<br>
  cc CMakeFiles/run.dir/run.c.o  -o run -Wl,-rpath,. libbar.so libfoo.a<br>
                                                               ^^^^^^^^<br>
<br>
On the other hand if I change the link of foo to be PRIVATE instead of<br>
PUBLIC:<br>
<br>
  target_link_libraries(bar PRIVATE foo)<br>
<br>
then the link doesn't include libfoo.a, which is good, but I also don't<br>
have the -I/tmp when I compile run.c, which is wrong:<br>
<br>
  cc -o CMakeFiles/run.dir/run.c.o -c run.c<br>
  cc CMakeFiles/run.dir/run.c.o -o run -Wl,-rpath,. libbar.so<br>
<br>
Does this seem wrong to anyone else?  Is there some trick to it?<br></blockquote><div><br></div><div>The behaviour is correct according to what you are telling CMake to do. If you use PUBLC in a target_link_libraries() call, you are saying that anything that links to your shared library should also link to the static library. PRIVATE would mean that the shared library uses the static library internally but doesn't expose anything from the static library in the shared library's interface or header files. If your executable needs to know about the static library in any way (which means it includes any of the static library's headers directly or any of the shared library's headers pull them in), then the static library is no longer a private dependency and has to be PUBLIC.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Or do I have to resort to by-hand forwarding of build properties rather<br>
than relying on a straightforward target_link_libraries() line?<br>
</blockquote></div><div><br></div><div>Look at your interfaces and header files carefully. Can you avoid referring to anything from the static library in any of the shared library's public headers (or any headers that those public headers pull in)? If so, then do that and you can use target_link_libraries(bar PRIVATE foo). None of the transitive properties of foo should be needed then either, so you'd have nothing left to forward on. If you can't avoid it, then the static library really is a public dependency and anything linking to bar should rightly also be linking to foo.</div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr">Craig Scott<br><div>Melbourne, Australia</div><div><a href="https://crascit.com" target="_blank">https://crascit.com</a><br></div><div><br></div><div>Get the hand-book for every CMake user: <a href="https://crascit.com/professional-cmake/" target="_blank">Professional CMake: A Practical Guide</a><br></div></div></div></div></div></div></div></div></div></div></div></div></div></div>