<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le dim. 16 juin 2019 à 18:26, Paul Smith <<a href="mailto:paul@mad-scientist.net">paul@mad-scientist.net</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Let me just mention up-front that I spent about 2 weeks earlier this<br>
year completely converting our circa-2011 cmake environment to ultra-<br>
modern cmake: switching completely to TLL, interfaces, removing<br>
virtually all if-statements and converting them into generator<br>
expressions, etc. So I'm very familiar with CMake's model for PRIVATE,<br>
PUBLIC, and INTERFACE and how inheritance works.<br>
<br>
And, I see the paradigm you're operating under where a shared library<br>
provides a single "interface" that is public.<br>
<br>
But, that's not the only way to use shared libraries. I'm trying to<br>
collect a number of static libraries with different interfaces into a<br>
single shared library that can be linked with executables (in my case I<br>
have 220 unit test programs which, when linked statically, not only<br>
take a very long time and a lot of memory, but use about 45G of disk<br>
space per build--I am collecting these into a shared library that can<br>
be linked with our unit tests. In my testing this reduces the size of<br>
a sample unit test executable from 400M down to about 8M).<br></blockquote><div><br></div><div>Correct me if I'm wrong but I guess that if your goal is to "collect" all those static libs *into* a shared </div><div>lib then what you need is to make your STATIC libs, OBJECT libs and then I think you'll get what you expect.</div><div>I.e. in your CMakeLists.txt</div><div>replace </div><div>add_library(foo STATIC foo.c)<br></div><div>with</div><div>add_library(foo OBJECT foo.c)<br></div><div><br></div><div>Otherwise (at least in the way CMake currently works) any symbols defined</div><div>in foo.a STATIC lib will *stay* in it. So in the end when you link an executable</div><div>using bar.so SHARED lib only (which is using foo.a) then you won't have the symbol</div><div>you need from foo unless foo.a is added to the link line ? Am I right ?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
So: I need my shared library to export a combination of ALL the public<br>
interfaces of the static libraries it was built from, but not,<br>
obviously, export the static libraries themselves.<br></blockquote><div><br></div><div>But how can you do that without either:<br> </div><div>1) adding the static lib to any link line (including the one using bar)</div><div>2) *merging* foo.a *into* bar.so which should be what you achieve by</div><div> making foo an OBJECT lib.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
On Sat, 2019-06-15 at 23:10 -0700, Craig Scott wrote:<br>
> The behaviour is correct according to what you are telling CMake to<br>
> do. If you use PUBLC in a target_link_libraries() call, you are<br>
> saying that anything that links to your shared library should also<br>
> link to the static library.<br>
<br>
That simply does not make sense, from the point of view of how a<br>
program and a linker work (I understand it's how CMake works).<br>
<br>
Let me work backwards, starting with a fact that hopefully we can all<br>
agree on:<br>
<br>
It is NEVER appropriate to put a static library into the<br>
INTERFACE_LINK_LIBRARIES of a shared library.<br>
<br>
I'd be interested to hear counter-arguments, but even if there are any<br>
reasons for it my position is that in those very rare cases you should<br>
be listing the static library in the TLL of the executable directly.<br></blockquote><div><br></div><div>Correct me if I'm wrong but you are saying that TLL(bar.so foo.a) should merge foo.a into bar.so ?</div><div>But TLL(myexe foo.a) should add foo.a in the link line of myexe? </div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
If we can agree on that, then using the current rules of CMake<br>
inheritance this implies that we can NEVER add a static library as a<br>
PUBLIC TLL for a shared library.<br></blockquote><div><br></div><div>Exactly my point. I understand what you say, but if ever CMake was doing that </div><div>you simply couldn't switch (GLOBALLY) from SHARED to STATIC</div><div>using <a href="https://cmake.org/cmake/help/v3.14/variable/BUILD_SHARED_LIBS.html">https://cmake.org/cmake/help/v3.14/variable/BUILD_SHARED_LIBS.html</a></div><div>is a single SHARED lib was explicitely specified.</div><div><br></div><div>My opinion is that CMake may handle TLL(SHARED STATIC) differently than</div><div>TLL(SHARED SHARED) but forbidding the first would be a major headache when</div><div>you want to go from STATIC to SHARED lib one step after another (I have a concrete</div><div>example in mind in a legacy project).</div><div><br></div><div>Even if I agree that this is a very bad idea </div><div>"to put a static library into the INTERFACE_LINK_LIBRARIES of a shared library"</div><div><br></div><div>it currently works with CMake a may be saving a lot of time to many people switching</div><div>gradually from a legacy build system doing just that.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Which seems, to me, quite ridiculous because why shouldn't you want to<br>
allow INTERFACE_COMPILE_DEFINITIONS, INTERFACE_COMPILE_OPTIONS, and<br>
INTERFACE_COMPILE_DIRECTORIES of the static library to be inherited by<br>
the shared library into its PUBLIC interface? That seems like a quite<br>
reasonable thing to want to do.<br></blockquote><div><br></div><div>I don't follow, it seems to be that case when the shared lib TLL publicly to the static lib? </div><div>I really think think the behavior you are expecting already works if you replace your static lib with object lib.</div><div><a href="https://cmake.org/cmake/help/v3.14/command/target_link_libraries.html#linking-object-libraries">https://cmake.org/cmake/help/v3.14/command/target_link_libraries.html#linking-object-libraries</a><br></div><div><br></div><div>But may be I missed something?</div><div><br></div></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Eric<br></div></div></div></div></div></div>