[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Linking one library against another + static vs. shared
From: |
Sander Niemeijer |
Subject: |
Re: Linking one library against another + static vs. shared |
Date: |
Sat, 25 Jul 2009 20:42:51 +0200 |
Hi Ralf,
Thank you for answering my email.
On 25 jul 2009, at 11:45, Ralf Wildenhues wrote:
* Issue 1
When compiling libbar, libtool includes libfoo.a when linking the
shared version of libbar, but for the static version of libbar the
libfoo library is *not* included.
This seems ok to me.
Furthermore, the libfoo library is
also not included as a dependency in the libbar.la file.
This would seem to be a bug.
But, if the dependency is included, does that dependency then only
relate to the static version of libbar or also to the shared version?
The shared version of libbar already has libfoo linked in, so it has
no 'external' dependency on libfoo anymore. The libbar.la file should
therefore not include any 'external' dependency information on libfoo
for the shared version of libbar.
Fixing this should also fix linking
against the static version of libfoo (iff the libfoo.la file is used
for linking).
Why wouldn't this also work for the case of my issue 2? Shouldn't
linking against libfoo.a (with no libfoo.la present) also include
libfoo.a as dependency?
* Issue 2
This resulted in a very weird call to ar:
---
libtool: link: ar cru .libs/libbar.a $(SOMEPATH)/lib/libfoo.a bar.o
Yup, seems weird, and broken.
If libtool has a public bug-tracker and you want me to add a report on
this, let me know.
Now, I know that linking a static library against a shared library
is not portable, but:
1) I am doing this only on a Linux and Mac OS X system and both
systems produce PIC objects by default (also for static libraries),
Wrong. OS X produces PIC objects by default. On GNU/Linux, PIC is
not
produced by default; however, specifically x86 allows you to relocate
non-PIC code through expensive, killing-page-sharing text relocations.
Try on x86_64 and it will fail.
Ah. That is good to know. I wasn't aware of that.
so it should be allowed.
That's yet another question, and I acknowledge that libtool's answer
to this is about as inconsistent as all demands have been on this list
throughout the years. ;-)
I must say that libtool is doing a pretty fine job already,
considering the difficulity with shared/static and pic/no-pic mixing.
As a side note, I assume that the 'pic-only' option could help out
here? The documentation does not explicitly say that libtool will then
also try to create 'pic' objects for static libraries, but I assume
this is the case, right?
2) libtool only presents a warning about linking a static library
against a shared library for the setup of issue 2 (linking against
libfoo.a), but *not* for the setup of issue 1 (link using -L<path> -
lfoo), which seems inconsistent to me.
Well, one thing could be that libtool might not actually be able to
know
which -lfoo the linker uses to actually link. So yes, a QoI issue.
In general, you are right. But in this case there is a libfoo.la file,
and that .la file only contains a reference to a static libfoo
library, so libtool should theoretically know.
What I would have expected is that in all cases (both for linking
against libfoo.a and for linking using '-L<path> -lfoo') libfoo
would be included as a dependency in the libbar.la file. And under
no circumstance should the libfoo.a contents be linked into the
libbar libraries.
Yes and yes. Having two instances of the same code in different
installed libraries is a recipe for disaster.
But, I just realised, libfoo.a actually gets linked into the shared
version of libbar. Does this mean we have cooked some disaster? ;)
I know that you will have to link in libfoo.a into bar, if bar is a
module (otherwise the module will never work)
But I am not a shared library guru enough to understand the
implications of linking libfoo.a into a shared libbar library. What
happens if we have another (shared) libmetoo that also depends on
libfoo and if an executable then tries to link (dynamically) against
both libbar and libmetoo? And what if that executable also uses libfoo
functionality (and links to it)?
It is, in my opinion, the final link step (i.e.
when creating the executable) that should, by investigating the
libbar dependencies (either a libfoo.la or a libfoo.a reference),
pick up the appropriate libfoo library (either static or shared,
whichever is available/needed) and include it in the link line.
Yes.
I was thinking on this some more and there are quite a few switches
that need to be considered:
- libfoo could be build normally, or with disable-static (i.e. only
shared library) or with disable-shared (i.e. only static library)
- for libbar we have the same 3 options
- libbar could be a module instead of a library (which may have
different consequences when it gets hooked up in the executable)
- if libbar is a library and linked into an executable, that
executable may want to link either dynamically or statically (-all-
static) against libbar (and its dependencies).
I was just interested to see what would happen if e.g. the executable
would link statically against its libraries (-all-static), libbar was
build with --disable-shared, and libfoo was build with with --disable-
static. Fortunately libtool seems to behave as I would have expected:
give a warning that complete static linking is impossible, but still
link against the shared version of liboo.
However, I haven't tested all combinations, and it might be difficult
to keep track of them. So, as a suggestion, it might be good to
introduce 'make check' tests for the less obvious combinations (if
technically possible) in the libtool package as regression tests.
Best regards,
Sander