<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 17 juin 2019 à 02:01, 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">On Sun, 2019-06-16 at 21:42 +0200, Eric Noulard wrote:<br>
> Le dim. 16 juin 2019 à 18:26, Paul Smith <<a href="mailto:paul@mad-scientist.net" target="_blank">paul@mad-scientist.net</a>> a<br>
> écrit :<br>
> > But, that's not the only way to use shared libraries.  I'm trying<br>
> > to collect a number of static libraries with different interfaces<br>
> > into a single shared library that can be linked with executables. <br>
> <br>
> Correct me if I'm wrong but I guess that if your goal is to "collect"<br>
> all those static libs *into* a shared lib then what you need is to<br>
> make your STATIC libs,  OBJECT libs and then I think you'll get what<br>
> you expect.<br>
<br>
Yep, I'm familiar with OBJECT libs and if I could use them they would<br>
give the correct behavior, you're right.  Unfortunately it's not the<br>
case that OBJECT libraries are completely "drop-in" replaceable for<br>
STATIC libraries, and they cannot be substituted in my environment.<br>
<br>
See, for one example:<br>
<a href="https://gitlab.kitware.com/cmake/cmake/issues/19388" rel="noreferrer" target="_blank">https://gitlab.kitware.com/cmake/cmake/issues/19388</a><br>
<br>
I am not able to rework my system comprehensively enough to remove all<br>
mutual references between all my current libraries.  And there are<br>
other issues where OBJECT libraries aren't the equivalent of STATIC<br>
libraries.<br></blockquote><div><br></div><div>Yes 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">
> Otherwise (at least in the way CMake currently works) any symbols<br>
> defined in foo.a STATIC lib will *stay* in it. So in the end when you<br>
> link an executable using bar.so SHARED lib only (which is using<br>
> foo.a) then you won't have the symbol you need from foo unless foo.a<br>
> is added to the link line ? Am I right?<br>
<br>
No, that's not right.<br>
<br>
The visibility of symbols depends on how your code is compiled and has<br>
nothing to do with cmake and whether cmake links into a shared or<br>
static library.<br>
<br>
On POSIX systems (gcc and clang), all symbols are public by default<br>
regardless of whether you are compiling them for a static or shared<br>
library.<br>
<br>
On Windows it's all more complicated, but in my situation I've added<br>
the WINDOWS_EXPORT_ALL_SYMBOLS property to my libraries.<br></blockquote><div><br></div><div>Yes you are right and I know that, but AFAIK when (with CMake) you TLL a</div><div>shared lib to a static lib. You do not end up with any of the static lib symbol in the shared lib.</div><div>At least none of them are visible with nm. (I did only test that on Linux).</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">
> But how can you do that without either:<br>
>  <br>
> 1) adding the static lib to any link line (including the one using bar)<br>
> 2) *merging* foo.a *into* bar.so which should be what you achieve by<br>
>     making foo an OBJECT lib.<br>
<br>
I'm not sure what you mean by "merging foo.a into bar.so": you can't<br>
merge something into a shared library any more than you can merge<br>
something into an executable.  By putting "foo" into the TLL of "bar",<br>
I've added the static library to the creation of the shared library:<br>
<br>
  cc -shared -o bar.so bar.o libfoo.a<br>
<br>
Now when bar.so is created it will have the required contents of<br>
libfoo.a in it.<br></blockquote><div><br></div><div>You mean that the part of libfoo.a which is actually used by some part of bar.o gets in bar.so</div><div>or any [exported] symbol found in libfoo.a gets in bar.so with the same export rule?</div><div><br></div><div>My test showed me something different but I'll check again, I must have done something wrong.</div><div><br></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<br>
> > a PUBLIC TLL for a shared library.<br>
> <br>
> Exactly my point. I understand what you say, but if ever CMake was<br>
> doing that you simply couldn't switch (GLOBALLY) from SHARED to<br>
> STATIC using <br>
> <a href="https://cmake.org/cmake/help/v3.14/variable/BUILD_SHARED_LIBS.html" rel="noreferrer" target="_blank">https://cmake.org/cmake/help/v3.14/variable/BUILD_SHARED_LIBS.html</a><br>
> is a single SHARED lib was explicitely specified.<br>
<br>
I wasn't familiar with that option, but I don't think it makes a<br>
difference whether the libraries are made SHARED via this option or<br>
whether they are made SHARED via direct specification: the behavior is<br>
the same.<br>
<br>
> My opinion is that CMake may handle TLL(SHARED STATIC) differently<br>
> than TLL(SHARED SHARED) but forbidding the first would be a major<br>
> headache when you want to go from STATIC to SHARED lib one step after<br>
> another (I have a concrete example in mind in a legacy project).<br>
<br>
I didn't say it should be forbidden!!<br>
<br>
I said that as cmake is currently implemented it doesn't make sense to<br>
do it, implying that cmake might want to change its behavior in this<br>
area to be more useful.<br></blockquote><div><br></div><div>OK now I get your point, thank you for clarifying.</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">
However, after more investigation I see that I was wrong about how<br>
linkers resolve symbols at least in POSIX systems (I'm not sure about<br>
DLLs on Windows... I haven't gotten there yet).<br>
<br>
For some reason I remembered that a linker would prefer symbols found<br>
in static libraries over those found in shared libraries, but in fact<br>
the linker will always choose the implementation of the symbol in the<br>
first library it's defined in regardless of the type of library.<br></blockquote><div><br></div><div>Yes that's right, note however that this behavior may vary between linkers</div><div>(GNU ld, gold, llvm LLD, ...) as their respective speed:</div><div>See e.g. <a href="https://lld.llvm.org/#performance">https://lld.llvm.org/#performance</a></div><div>I know that LLD advertise to be a "drop-in" replacement for ld but I have some nasty legacy project</div><div>example which show this to be wrong, but that another story.</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, as long as the shared library appears first on the link line it<br>
shouldn't matter that the static library also appears there.<br>
<br>
I still think it's incorrect to add the static library to the link<br>
line, but (at least for linkers with semantics as above) it probably<br>
doesn't actually hurt anything.<br></blockquote><div><br></div><div>This may be true w.r.t. the semantic, but it may (from my experience) vary concerning the link performance,</div><div>but again this is another subject.</div><div><br></div><div>If there is effectively no need to have static lib on the line because a shared lib depending on this static lib was</div><div>already linked to it, then it ought to be suppressed and not rely on some linker policy to tidy up the whole set</div><div>of shared and static libs. </div></div><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Eric<br></div></div></div></div></div></div>