[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: inter-library linking
From: |
Ralf Wildenhues |
Subject: |
Re: inter-library linking |
Date: |
Fri, 12 Oct 2007 17:53:11 +0200 |
User-agent: |
Mutt/1.5.16 (2007-10-11) |
Hello Joachim,
* Joachim Worringen wrote on Fri, Oct 12, 2007 at 02:39:16PM CEST:
>
> "libshared" needs to be a shared library, as it will be used with
> LD_RELOAD. It builds from its own sources, but also depends on two other
> libraries that are built within the same source three: "libnoinst" and
> "libfoo". libnoinst is a static convenience library, while libfoo is just
> another shared library.
First a general question: why do you use (need to use?) LD_PRELOAD,
as oppposed to, say, just linking your programs against the libraries?
(I can imagine two prime use cases: dealing with programs one cannot
recompile like binary-only software, or symbol interpose "hacks" for
programs like valgrind or other malloc debug stuff.)
Another general remark: convenience libraries don't enter the picture
here much; think of them as a short-hand notation for a collection of
objects that will all be copied into the final library.
Now to the meat: the library libfoo that libshared depends on:
> While the symbols from libnoinst are placed into libshared, the references
> to libfoo remain unresolved. This lets the linking fail when I set
> LD_PRELOAD=libshared.so: symbols from libfoo.so can not be resolved
> (although it is in the LD path, same as where libshared is placed).
There are two ways this can be made to work:
1) Explicit linkage of libshared against libfoo should cause the runtime
linker to pull it in:
lib_LTLIBRARIES = libfoo.la libshared.la
libshared_la_LIBADD = libfoo.la
libfoo_la_SOURCES = ...
...
If that's what you already did, but it's producing errors anyway, then
please post a build log that contains the mode=link and mode=install
commands for both of these libraries plus all output they generate,
and the error output of the `LD_PRELOAD=...' command.
(The key here is that the *_LIBADD line will cause a DT_NEEDED entry
for libfoo.so.X to be put in libshared.so, which in turn will cause
the runtime glibc linker to pull in libfoo.so.X. If libfoo lives in a
nonstandard directory, then a DT_RPATH entry will be added, too.
For ELF runtime linkers other than the GNU/Linux one, I don't know
offhand whether LD_PRELOAD has the same semantics.)
2) Just list both to-be-preloaded libraries in LD_PRELOAD:
LD_PRELOAD=libfoo.so:libshared.so ...
But actually you should be listing the inter-library dependencies in
*_LIBADD anyway, and your build order should be such that libfoo is
build before libshared.
> Explicitely linking libshared.so to libfoo.a fails as its object files are
> not compiled as PIC (and I don't know how tell automake to do this
> anyway...).
Well you can make libfoo a convenience archive. But then its code will
end up completely in libshared; and it's not a good idea to install
convenience archives, which is why it's not done by Automake. A good
rule of thumb is that code should live in at most one installed library,
everything else can cause ugly sooner or later.
Hope that helps.
Cheers,
Ralf