Why do executables link static libs that shared libs were built from?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Why do executables link static libs that shared libs were built from?

Paul Smith
I have a situation where I create a number of static libraries, then I
create a shared library from them, then I create an executable from the
shared library.

This seems straightforward, but I can't get it do work as I want.  The
behavior of STATIC -> SHARED for target property inheritance seems
incorrect to me.

I'm using CMake 3.14.5 on GNU/Linux for this test.

I need the compile properties of the static library (include
directories etc.) to be public for all users of the shared library as
well.  But obviously I don't want users of the shared library to also
link the static library!!  That defeats the whole purpose of the shared
library.

If I set up like this:

  $ touch foo.c bar.c
  $ echo 'int main() { return 0; }' > run.c

then write my CMakeFiles.txt like this:

  cmake_minimum_required(VERSION 3.13)
  project(Test C)

  add_library(foo STATIC foo.c)
  target_include_directories(foo PUBLIC /tmp)

  add_library(bar SHARED bar.c)
  target_link_libraries(bar PUBLIC foo)

  add_executable(run run.c)
  target_link_libraries(run PUBLIC bar)

Then, I DO get the -I/tmp forwarded up to run.c:

  cc -I/tmp -o CMakeFiles/run.dir/run.c.o -c run.c
     ^^^^^^

But libfoo.a is ALSO added to my link line, which is really wrong!

  cc CMakeFiles/run.dir/run.c.o  -o run -Wl,-rpath,. libbar.so libfoo.a
                                                               ^^^^^^^^

On the other hand if I change the link of foo to be PRIVATE instead of
PUBLIC:

  target_link_libraries(bar PRIVATE foo)

then the link doesn't include libfoo.a, which is good, but I also don't
have the -I/tmp when I compile run.c, which is wrong:

  cc -o CMakeFiles/run.dir/run.c.o -c run.c
  cc CMakeFiles/run.dir/run.c.o -o run -Wl,-rpath,. libbar.so

Does this seem wrong to anyone else?  Is there some trick to it?

Or do I have to resort to by-hand forwarding of build properties rather
than relying on a straightforward target_link_libraries() line?

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Why do executables link static libs that shared libs were built from?

Craig Scott-3


On Sat, Jun 15, 2019 at 5:01 PM Paul Smith <[hidden email]> wrote:
I have a situation where I create a number of static libraries, then I
create a shared library from them, then I create an executable from the
shared library.

This seems straightforward, but I can't get it do work as I want.  The
behavior of STATIC -> SHARED for target property inheritance seems
incorrect to me.

I'm using CMake 3.14.5 on GNU/Linux for this test.

I need the compile properties of the static library (include
directories etc.) to be public for all users of the shared library as
well.  But obviously I don't want users of the shared library to also
link the static library!!  That defeats the whole purpose of the shared
library.

If I set up like this:

  $ touch foo.c bar.c
  $ echo 'int main() { return 0; }' > run.c

then write my CMakeFiles.txt like this:

  cmake_minimum_required(VERSION 3.13)
  project(Test C)

  add_library(foo STATIC foo.c)
  target_include_directories(foo PUBLIC /tmp)

  add_library(bar SHARED bar.c)
  target_link_libraries(bar PUBLIC foo)

  add_executable(run run.c)
  target_link_libraries(run PUBLIC bar)

Then, I DO get the -I/tmp forwarded up to run.c:

  cc -I/tmp -o CMakeFiles/run.dir/run.c.o -c run.c
     ^^^^^^

But libfoo.a is ALSO added to my link line, which is really wrong!

  cc CMakeFiles/run.dir/run.c.o  -o run -Wl,-rpath,. libbar.so libfoo.a
                                                               ^^^^^^^^

On the other hand if I change the link of foo to be PRIVATE instead of
PUBLIC:

  target_link_libraries(bar PRIVATE foo)

then the link doesn't include libfoo.a, which is good, but I also don't
have the -I/tmp when I compile run.c, which is wrong:

  cc -o CMakeFiles/run.dir/run.c.o -c run.c
  cc CMakeFiles/run.dir/run.c.o -o run -Wl,-rpath,. libbar.so

Does this seem wrong to anyone else?  Is there some trick to it?

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.

 
Or do I have to resort to by-hand forwarding of build properties rather
than relying on a straightforward target_link_libraries() line?

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.


--
Craig Scott
Melbourne, Australia

Get the hand-book for every CMake user: Professional CMake: A Practical Guide

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Why do executables link static libs that shared libs were built from?

Paul Smith
Let me just mention up-front that I spent about 2 weeks earlier this
year completely converting our circa-2011 cmake environment to ultra-
modern cmake: switching completely to TLL, interfaces, removing
virtually all if-statements and converting them into generator
expressions, etc.  So I'm very familiar with CMake's model for PRIVATE,
PUBLIC, and INTERFACE and how inheritance works.

And, I see the paradigm you're operating under where a shared library
provides a single "interface" that is public.

But, that's not the only way to use shared libraries.  I'm trying to
collect a number of static libraries with different interfaces into a
single shared library that can be linked with executables (in my case I
have 220 unit test programs which, when linked statically, not only
take a very long time and a lot of memory, but use about 45G of disk
space per build--I am collecting these into a shared library that can
be linked with our unit tests.  In my testing this reduces the size of
a sample unit test executable from 400M down to about 8M).

So: I need my shared library to export a combination of ALL the public
interfaces of the static libraries it was built from, but not,
obviously, export the static libraries themselves.


On Sat, 2019-06-15 at 23:10 -0700, Craig Scott wrote:
> 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.

That simply does not make sense, from the point of view of how a
program and a linker work (I understand it's how CMake works).

Let me work backwards, starting with a fact that hopefully we can all
agree on:

   It is NEVER appropriate to put a static library into the
   INTERFACE_LINK_LIBRARIES of a shared library.

I'd be interested to hear counter-arguments, but even if there are any
reasons for it my position is that in those very rare cases you should
be listing the static library in the TLL of the executable directly.

If we can agree on that, then using the current rules of CMake
inheritance this implies that we can NEVER add a static library as a
PUBLIC TLL for a shared library.

Which seems, to me, quite ridiculous because why shouldn't you want to
allow INTERFACE_COMPILE_DEFINITIONS, INTERFACE_COMPILE_OPTIONS, and
INTERFACE_COMPILE_DIRECTORIES of the static library to be inherited by
the shared library into its PUBLIC interface?  That seems like a quite
reasonable thing to want to do.

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Why do executables link static libs that shared libs were built from?

Eric Noulard


Le dim. 16 juin 2019 à 18:26, Paul Smith <[hidden email]> a écrit :
Let me just mention up-front that I spent about 2 weeks earlier this
year completely converting our circa-2011 cmake environment to ultra-
modern cmake: switching completely to TLL, interfaces, removing
virtually all if-statements and converting them into generator
expressions, etc.  So I'm very familiar with CMake's model for PRIVATE,
PUBLIC, and INTERFACE and how inheritance works.

And, I see the paradigm you're operating under where a shared library
provides a single "interface" that is public.

But, that's not the only way to use shared libraries.  I'm trying to
collect a number of static libraries with different interfaces into a
single shared library that can be linked with executables (in my case I
have 220 unit test programs which, when linked statically, not only
take a very long time and a lot of memory, but use about 45G of disk
space per build--I am collecting these into a shared library that can
be linked with our unit tests.  In my testing this reduces the size of
a sample unit test executable from 400M down to about 8M).

Correct me if I'm wrong but I guess that if your goal is to "collect" all those static libs *into* a shared 
lib then what you need is to make your STATIC libs,  OBJECT libs and then I think you'll get what you expect.
I.e. in your CMakeLists.txt
replace 
add_library(foo STATIC foo.c)
with
add_library(foo OBJECT foo.c)

Otherwise (at least in the way CMake currently works) any symbols defined
in foo.a STATIC lib will *stay* in it. So in the end when you link an executable
using bar.so SHARED lib only (which is using foo.a) then you won't have the symbol
you need from foo unless foo.a is added to the link line ? Am I right ?
  
So: I need my shared library to export a combination of ALL the public
interfaces of the static libraries it was built from, but not,
obviously, export the static libraries themselves.

But how can you do that without either:
 
1) adding the static lib to any link line (including the one using bar)
2) *merging* foo.a *into* bar.so which should be what you achieve by
    making foo an OBJECT lib.

 
On Sat, 2019-06-15 at 23:10 -0700, Craig Scott wrote:
> 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.

That simply does not make sense, from the point of view of how a
program and a linker work (I understand it's how CMake works).

Let me work backwards, starting with a fact that hopefully we can all
agree on:

   It is NEVER appropriate to put a static library into the
   INTERFACE_LINK_LIBRARIES of a shared library.

I'd be interested to hear counter-arguments, but even if there are any
reasons for it my position is that in those very rare cases you should
be listing the static library in the TLL of the executable directly.

Correct me if I'm wrong but you are saying that TLL(bar.so foo.a)  should merge foo.a into bar.so ?
But TLL(myexe foo.a) should add foo.a in the link line of myexe? 
 
If we can agree on that, then using the current rules of CMake
inheritance this implies that we can NEVER add a static library as a
PUBLIC TLL for a shared library.

Exactly my point. I understand what you say, but if ever CMake was doing that 
you simply couldn't switch (GLOBALLY) from SHARED to STATIC
is a single SHARED lib was explicitely specified.

My opinion is that CMake may handle TLL(SHARED STATIC) differently than
TLL(SHARED SHARED) but forbidding the first would be a major headache when
you want to go from STATIC to SHARED lib one step after another (I have a concrete
example in mind in a legacy project).

Even if I agree that this is a very bad idea 
"to put a static library into the INTERFACE_LINK_LIBRARIES of a shared library"

it currently works with CMake a may be saving a lot of time to many people switching
gradually from a legacy build system doing just that.
 
Which seems, to me, quite ridiculous because why shouldn't you want to
allow INTERFACE_COMPILE_DEFINITIONS, INTERFACE_COMPILE_OPTIONS, and
INTERFACE_COMPILE_DIRECTORIES of the static library to be inherited by
the shared library into its PUBLIC interface?  That seems like a quite
reasonable thing to want to do.

I don't follow, it seems to be that case when the shared lib TLL publicly to the static lib? 
I really think think the behavior you are expecting already works if you replace your static lib with object lib.

But may be I missed something?

--
Eric

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Why do executables link static libs that shared libs were built from?

Paul Smith
On Sun, 2019-06-16 at 21:42 +0200, Eric Noulard wrote:

> Le dim. 16 juin 2019 à 18:26, Paul Smith <[hidden email]> a
> écrit :
> > But, that's not the only way to use shared libraries.  I'm trying
> > to collect a number of static libraries with different interfaces
> > into a single shared library that can be linked with executables.
>
> Correct me if I'm wrong but I guess that if your goal is to "collect"
> all those static libs *into* a shared lib then what you need is to
> make your STATIC libs,  OBJECT libs and then I think you'll get what
> you expect.

Yep, I'm familiar with OBJECT libs and if I could use them they would
give the correct behavior, you're right.  Unfortunately it's not the
case that OBJECT libraries are completely "drop-in" replaceable for
STATIC libraries, and they cannot be substituted in my environment.

See, for one example:
https://gitlab.kitware.com/cmake/cmake/issues/19388

I am not able to rework my system comprehensively enough to remove all
mutual references between all my current libraries.  And there are
other issues where OBJECT libraries aren't the equivalent of STATIC
libraries.

> Otherwise (at least in the way CMake currently works) any symbols
> defined in foo.a STATIC lib will *stay* in it. So in the end when you
> link an executable using bar.so SHARED lib only (which is using
> foo.a) then you won't have the symbol you need from foo unless foo.a
> is added to the link line ? Am I right?

No, that's not right.

The visibility of symbols depends on how your code is compiled and has
nothing to do with cmake and whether cmake links into a shared or
static library.

On POSIX systems (gcc and clang), all symbols are public by default
regardless of whether you are compiling them for a static or shared
library.

On Windows it's all more complicated, but in my situation I've added
the WINDOWS_EXPORT_ALL_SYMBOLS property to my libraries.

> But how can you do that without either:
>  
> 1) adding the static lib to any link line (including the one using bar)
> 2) *merging* foo.a *into* bar.so which should be what you achieve by
>     making foo an OBJECT lib.

I'm not sure what you mean by "merging foo.a into bar.so": you can't
merge something into a shared library any more than you can merge
something into an executable.  By putting "foo" into the TLL of "bar",
I've added the static library to the creation of the shared library:

  cc -shared -o bar.so bar.o libfoo.a

Now when bar.so is created it will have the required contents of
libfoo.a in it.
 
> > If we can agree on that, then using the current rules of CMake
> > inheritance this implies that we can NEVER add a static library as
> > a PUBLIC TLL for a shared library.
>
> Exactly my point. I understand what you say, but if ever CMake was
> doing that you simply couldn't switch (GLOBALLY) from SHARED to
> STATIC using
> https://cmake.org/cmake/help/v3.14/variable/BUILD_SHARED_LIBS.html
> is a single SHARED lib was explicitely specified.

I wasn't familiar with that option, but I don't think it makes a
difference whether the libraries are made SHARED via this option or
whether they are made SHARED via direct specification: the behavior is
the same.

> My opinion is that CMake may handle TLL(SHARED STATIC) differently
> than TLL(SHARED SHARED) but forbidding the first would be a major
> headache when you want to go from STATIC to SHARED lib one step after
> another (I have a concrete example in mind in a legacy project).

I didn't say it should be forbidden!!

I said that as cmake is currently implemented it doesn't make sense to
do it, implying that cmake might want to change its behavior in this
area to be more useful.


However, after more investigation I see that I was wrong about how
linkers resolve symbols at least in POSIX systems (I'm not sure about
DLLs on Windows... I haven't gotten there yet).

For some reason I remembered that a linker would prefer symbols found
in static libraries over those found in shared libraries, but in fact
the linker will always choose the implementation of the symbol in the
first library it's defined in regardless of the type of library.

So, as long as the shared library appears first on the link line it
shouldn't matter that the static library also appears there.

I still think it's incorrect to add the static library to the link
line, but (at least for linkers with semantics as above) it probably
doesn't actually hurt anything.

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Why do executables link static libs that shared libs were built from?

Eric Noulard


Le lun. 17 juin 2019 à 02:01, Paul Smith <[hidden email]> a écrit :
On Sun, 2019-06-16 at 21:42 +0200, Eric Noulard wrote:
> Le dim. 16 juin 2019 à 18:26, Paul Smith <[hidden email]> a
> écrit :
> > But, that's not the only way to use shared libraries.  I'm trying
> > to collect a number of static libraries with different interfaces
> > into a single shared library that can be linked with executables.
>
> Correct me if I'm wrong but I guess that if your goal is to "collect"
> all those static libs *into* a shared lib then what you need is to
> make your STATIC libs,  OBJECT libs and then I think you'll get what
> you expect.

Yep, I'm familiar with OBJECT libs and if I could use them they would
give the correct behavior, you're right.  Unfortunately it's not the
case that OBJECT libraries are completely "drop-in" replaceable for
STATIC libraries, and they cannot be substituted in my environment.

See, for one example:
https://gitlab.kitware.com/cmake/cmake/issues/19388

I am not able to rework my system comprehensively enough to remove all
mutual references between all my current libraries.  And there are
other issues where OBJECT libraries aren't the equivalent of STATIC
libraries.

Yes right.
 
> Otherwise (at least in the way CMake currently works) any symbols
> defined in foo.a STATIC lib will *stay* in it. So in the end when you
> link an executable using bar.so SHARED lib only (which is using
> foo.a) then you won't have the symbol you need from foo unless foo.a
> is added to the link line ? Am I right?

No, that's not right.

The visibility of symbols depends on how your code is compiled and has
nothing to do with cmake and whether cmake links into a shared or
static library.

On POSIX systems (gcc and clang), all symbols are public by default
regardless of whether you are compiling them for a static or shared
library.

On Windows it's all more complicated, but in my situation I've added
the WINDOWS_EXPORT_ALL_SYMBOLS property to my libraries.

Yes you are right and I know that, but AFAIK when (with CMake) you TLL a
shared lib to a static lib. You do not end up with any of the static lib symbol in the shared lib.
At least none of them are visible with nm. (I did only test that on Linux).

> But how can you do that without either:

> 1) adding the static lib to any link line (including the one using bar)
> 2) *merging* foo.a *into* bar.so which should be what you achieve by
>     making foo an OBJECT lib.

I'm not sure what you mean by "merging foo.a into bar.so": you can't
merge something into a shared library any more than you can merge
something into an executable.  By putting "foo" into the TLL of "bar",
I've added the static library to the creation of the shared library:

  cc -shared -o bar.so bar.o libfoo.a

Now when bar.so is created it will have the required contents of
libfoo.a in it.

You mean that the part of libfoo.a which is actually used by some part of bar.o gets in bar.so
or any [exported] symbol found in libfoo.a gets in bar.so with the same export rule?

My test showed me something different but I'll check again, I must have done something wrong.


> > If we can agree on that, then using the current rules of CMake
> > inheritance this implies that we can NEVER add a static library as
> > a PUBLIC TLL for a shared library.
>
> Exactly my point. I understand what you say, but if ever CMake was
> doing that you simply couldn't switch (GLOBALLY) from SHARED to
> STATIC using
> https://cmake.org/cmake/help/v3.14/variable/BUILD_SHARED_LIBS.html
> is a single SHARED lib was explicitely specified.

I wasn't familiar with that option, but I don't think it makes a
difference whether the libraries are made SHARED via this option or
whether they are made SHARED via direct specification: the behavior is
the same.

> My opinion is that CMake may handle TLL(SHARED STATIC) differently
> than TLL(SHARED SHARED) but forbidding the first would be a major
> headache when you want to go from STATIC to SHARED lib one step after
> another (I have a concrete example in mind in a legacy project).

I didn't say it should be forbidden!!

I said that as cmake is currently implemented it doesn't make sense to
do it, implying that cmake might want to change its behavior in this
area to be more useful.

OK now I get your point, thank you for clarifying.
 
However, after more investigation I see that I was wrong about how
linkers resolve symbols at least in POSIX systems (I'm not sure about
DLLs on Windows... I haven't gotten there yet).

For some reason I remembered that a linker would prefer symbols found
in static libraries over those found in shared libraries, but in fact
the linker will always choose the implementation of the symbol in the
first library it's defined in regardless of the type of library.

Yes that's right, note however that this behavior may vary between linkers
(GNU ld, gold, llvm LLD, ...) as their respective speed:
I know that LLD advertise to be a "drop-in" replacement for ld but I have some nasty legacy project
example which show this to be wrong, but that another story.
 
So, as long as the shared library appears first on the link line it
shouldn't matter that the static library also appears there.

I still think it's incorrect to add the static library to the link
line, but (at least for linkers with semantics as above) it probably
doesn't actually hurt anything.

This may be true w.r.t. the semantic, but it may (from my experience) vary concerning the link performance,
but again this is another subject.

If there is effectively no need to have static lib on the line because a shared lib depending on this static lib was
already linked to it, then it ought to be suppressed and not rely on some linker policy to tidy up the whole set
of shared and static libs. 

--
Eric

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Why do executables link static libs that shared libs were built from?

Paul Smith
On Mon, 2019-06-17 at 11:43 +0200, Eric Noulard wrote:
> Yes you are right and I know that, but AFAIK when (with CMake) you
> TLL a shared lib to a static lib. You do not end up with any of the
> static lib symbol in the shared lib.

That can't be true, unless cmake is adding fancy linker options to the
command line (it doesn't :)).  The decision of what goes into the
library is up to how the linker works and what flags it's given.

However, note I said "it will have the _required_ contents" (emphasis
added).  As you noted, the .so will only pull in symbols from the .a
which are needed to link the .so.  That may not be all the symbols in
the .a, so in your test make sure you have that reference.

Alternatively you can configure the link of the shared library to use
"whole archive" mode which pulls in the entire contents of the .a
regardless of whether they are referenced.

> > I've added the static library to the creation of the shared
> > library:
> >
> >   cc -shared -o bar.so bar.o libfoo.a
> >
> > Now when bar.so is created it will have the required contents of
> > libfoo.a in it.
>
> You mean that the part of libfoo.a which is actually used by some
> part of bar.o gets in bar.so or any [exported] symbol found in
> libfoo.a gets in bar.so with the same export rule?

The former (the part that is actually used).  However again, you can
force the linker to include everything, even unused symbols.

> If there is effectively no need to have static lib on the line
> because a shared lib depending on this static lib was already linked
> to it, then it ought to be suppressed and not rely on some linker
> policy to tidy up the whole set of shared and static libs.

I did come across a real problem that I don't know how to solve, caused
by this behavior.

I'm going to start a new thread about it since this one is long and
convoluted.

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake