Debian Bug report logs - #291641
Checks dependencies of shared libraries without honouring RPATH

version graph

Package: libtool; Maintainer for libtool is Kurt Roeckx <kurt@roeckx.be>; Source for libtool is src:libtool.

Reported by: Philip Martin <philip@codematters.co.uk>

Date: Sat, 22 Jan 2005 01:18:02 UTC

Severity: important

Merged with 320698

Found in version libtool/1.5.6-6

Reply or subscribe to this bug.

Toggle useless messages

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to debian-bugs-dist@lists.debian.org, Scott James Remnant <scott@netsplit.com>:
Bug#291641; Package libtool. Full text and rfc822 format available.

Acknowledgement sent to Philip Martin <philip@codematters.co.uk>:
New Bug report received and forwarded. Copy sent to Scott James Remnant <scott@netsplit.com>. Full text and rfc822 format available.

Message #5 received at submit@bugs.debian.org (full text, mbox):

From: Philip Martin <philip@codematters.co.uk>
To: submit@bugs.debian.org
Subject: libtool: resolves dependencies to the install tree rather than the build tree
Date: Sat, 22 Jan 2005 01:01:05 +0000
Package: libtool
Version: 1.5.6-3
Severity: normal

*** Please type your report below this line ***
Sorry this is so long, a quick summary: Debian's libtool appears to resolve
inter-library dependencies to the install tree rather than the build tree,
this is different from the upstream GNU behaviour and can be awkward for
people using Debian as a development platform.

I am building Subversion from upstream source on a Debian machine with
libtool 1.5.6-3 installed.  Subversion builds a number of shared libraries
and executables and I have configured my Subversion build using
--prefix=$HOME/subversion so shared libraries get installed in
$HOME/subversion/lib.

One of libraries built is libsvn_ra-1.so, it is linked as follows:

cd subversion/libsvn_ra && /bin/sh /home/pm/sw/subversion/obj2/libtool --tag=CC --silent --mode=link gcc  -std=c89 -g -Wall -Wsign-compare -Wwrite-strings -Wpointer-arith -Wshadow -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wendif-labels -Wredundant-decls -DSVN_DEBUG -DSVN_DEBUG_ERROR -g -pthread -DNEON_ZLIB -DNEON_SSL    -rpath /home/pm/subversion/lib -o libsvn_ra-1.la  ra_loader.lo ../../subversion/libsvn_subr/libsvn_subr-1.la ../../subversion/libsvn_ra_local/libsvn_ra_local-1.la ../../subversion/libsvn_repos/libsvn_repos-1.la ../../subversion/libsvn_fs/libsvn_fs-1.la ../../subversion/libsvn_delta/libsvn_delta-1.la ../../subversion/libsvn_subr/libsvn_subr-1.la ../../subversion/libsvn_ra_svn/libsvn_ra_svn-1.la ../../subversion/libsvn_delta/libsvn_delta-1.la ../../subversion/libsvn_subr/libsvn_subr-1.la ../../subversion/libsvn_ra_dav/libsvn_ra_dav-1.la ../../subversion/libsvn_delta/libsvn_delta-1.la ../../subversion/libsvn_subr/libsvn_subr-1.la /home/pm/apache/lib/libaprutil-0.la -ldb -lexpat /home/pm/apache/lib/libapr-0.la -lrt -lm -lcrypt -lnsl  -lpthread -ldl

In particular, it links against three other libraries in the build tree
namely, libsvn_ra_svn-1.la, libsvn_ra_dav-1.la and libsvn_ra_local-1.la.

libsvn_ra-1.la is then used when linking an executable as follows:

cd subversion/clients/cmdline && /bin/sh /home/pm/sw/subversion/obj2/libtool --tag=CC --silent --mode=link gcc  -std=c89 -g -Wall -Wsign-compare -Wwrite-strings -Wpointer-arith -Wshadow -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wendif-labels -Wredundant-decls -DSVN_DEBUG -DSVN_DEBUG_ERROR -g -pthread -DNEON_ZLIB -DNEON_SSL    -rpath /home/pm/subversion/lib -o svn  add-cmd.o blame-cmd.o cat-cmd.o checkout-cmd.o cleanup-cmd.o commit-cmd.o copy-cmd.o delete-cmd.o diff-cmd.o export-cmd.o help-cmd.o import-cmd.o info-cmd.o log-cmd.o ls-cmd.o main.o merge-cmd.o mkdir-cmd.o move-cmd.o notify.o prompt.o propdel-cmd.o propedit-cmd.o propget-cmd.o proplist-cmd.o props.o propset-cmd.o resolved-cmd.o revert-cmd.o status-cmd.o status.o switch-cmd.o update-cmd.o util.o ../../../subversion/libsvn_client/libsvn_client-1.la ../../../subversion/libsvn_wc/libsvn_wc-1.la ../../../subversion/libsvn_ra/libsvn_ra-1.la ../../../subversion/libsvn_delta/libsvn_delta-1.la ../../../subversion/libsvn_subr/libsvn_subr-1.la /home/pm/apache/lib/libaprutil-0.la -ldb -lexpat /home/pm/apache/lib/libapr-0.la -lrt -lm -lcrypt -lnsl  -lpthread -ldl -lneon -lssl -lcrypto -lz -lxml2 -lz -lpthread -lm

Note that this is explicitly linked against libsvn_ra-1.la but there is no
mention of the three dependent libraries.

If I pass -v through libtool to gcc then I get the link command:

 /usr/lib/gcc-lib/i486-linux/3.3.5/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o .libs/svn /usr/lib/gcc-lib/i486-linux/3.3.5/../../../crt1.o /usr/lib/gcc-lib/i486-linux/3.3.5/../../../crti.o /usr/lib/gcc-lib/i486-linux/3.3.5/crtbegin.o -L/usr/lib/gcc-lib/i486-linux/3.3.5 -L/usr/lib/gcc-lib/i486-linux/3.3.5/../../.. add-cmd.o blame-cmd.o cat-cmd.o checkout-cmd.o cleanup-cmd.o commit-cmd.o copy-cmd.o delete-cmd.o diff-cmd.o export-cmd.o help-cmd.o import-cmd.o info-cmd.o log-cmd.o ls-cmd.o main.o merge-cmd.o mkdir-cmd.o move-cmd.o notify.o prompt.o propdel-cmd.o propedit-cmd.o propget-cmd.o proplist-cmd.o props.o propset-cmd.o resolved-cmd.o revert-cmd.o status-cmd.o status.o switch-cmd.o update-cmd.o util.o ../../../subversion/libsvn_client/.libs/libsvn_client-1.so ../../../subversion/libsvn_wc/.libs/libsvn_wc-1.so ../../../subversion/libsvn_ra/.libs/libsvn_ra-1.so ../../../subversion/libsvn_delta/.libs/libsvn_delta-1.so ../../../subversion/libsvn_subr/.libs/libsvn_subr-1.so /home/pm/apache/lib/libaprutil-0.so -ldb /usr/lib/libexpat.so /home/pm/apache/lib/libapr-0.so -lrt -lcrypt -lnsl -ldl /usr/lib/libneon.so -lssl -lcrypto /usr/lib/libxml2.so -lz -lpthread -lm --rpath /home/pm/subversion/lib --rpath /home/pm/apache/lib -lgcc --as-needed -lgcc_s --no-as-needed -lpthread -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-lib/i486-linux/3.3.5/crtend.o /usr/lib/gcc-lib/i486-linux/3.3.5/../../../crtn.o

This mentions libsvn_ra-1.so but doesn't mention the three dependent
libraries, however the link normally succeeds whether or not I have
libraries installed in $HOME/subversion/lib.  Running ldd on the binary
in the build tree reveals that it is correctly linked to libraries in
the build tree, and once installed it is correctly linked to libraries
in the install tree.

A recent change to the Subversion source (revision 12801) introduced
new functions into the three dependent libraries, and made
libsvn_ra-1.so reference those new functions.  Now the link fails
citing unresolved symbols corresponding to the new functions (and only
the new functions not any of the old functions).  If I remove the
installed libraries the link works.  This seems to indicate that the
link is resolving the dependent libraries to those in the install
tree, which don't have the new functions, rather than those in the
build tree.  Quite how it does that I don't know, perhaps it uses the
NEEDED data form the ELF header and -rpath passed on the command line.

If I reconfigure my build to use a pristine GNU 1.5.6 libtool the link no
longer fails.  I have examined the generated libsvn_ra-1.la files and they
are identical (modulo the libtool version comment).  The generated libtool
scripts are different:

$ diff libtool.gnu libtool.debian
316c316
< link_all_deplibs=unknown
---
> link_all_deplibs=no
390c390
< TIMESTAMP=" (1.1220.2.94 2004/04/10 16:27:27)"
---
> TIMESTAMP=" (1.1220.2.95 2004/04/11 05:50:42) Debian$Rev: 220 $"
2184c2184,2187
< 	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
---
> 	link)
> 	  libs="$deplibs %DEPLIBS%"
> 	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
> 	  ;;
2210,2213d2212
< 	  if test "$pass" = conv; then
< 	    deplibs="$deplib $deplibs"
< 	    continue
< 	  fi
3275a3275,3279
> 	  *)
> 	    $echo "$modename: unknown library version type \`$version_type'" 1>&2
> 	    $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
> 	    exit $EXIT_FAILURE
> 	    ;;
7034c7038
< link_all_deplibs=unknown
---
> link_all_deplibs=no

and while the libtool invocation is the same, GNU libtool generates a
different final link command:

 /usr/lib/gcc-lib/i486-linux/3.3.5/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o .libs/svn /usr/lib/gcc-lib/i486-linux/3.3.5/../../../crt1.o /usr/lib/gcc-lib/i486-linux/3.3.5/../../../crti.o /usr/lib/gcc-lib/i486-linux/3.3.5/crtbegin.o -L/usr/lib/gcc-lib/i486-linux/3.3.5 -L/usr/lib/gcc-lib/i486-linux/3.3.5/../../.. add-cmd.o blame-cmd.o cat-cmd.o checkout-cmd.o cleanup-cmd.o commit-cmd.o copy-cmd.o delete-cmd.o diff-cmd.o export-cmd.o help-cmd.o import-cmd.o info-cmd.o log-cmd.o ls-cmd.o main.o merge-cmd.o mkdir-cmd.o move-cmd.o notify.o prompt.o propdel-cmd.o propedit-cmd.o propget-cmd.o proplist-cmd.o props.o propset-cmd.o resolved-cmd.o revert-cmd.o status-cmd.o status.o switch-cmd.o update-cmd.o util.o ../../../subversion/libsvn_client/.libs/libsvn_client-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_wc/.libs/libsvn_wc-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_ra/.libs/libsvn_ra-1.so ../../../subversion/libsvn_wc/.libs/libsvn_wc-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_diff/.libs/libsvn_diff-1.so ../../../subversion/libsvn_ra/.libs/libsvn_ra-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_ra_local/.libs/libsvn_ra_local-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_repos/.libs/libsvn_repos-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_fs/.libs/libsvn_fs-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_fs_fs/.libs/libsvn_fs_fs-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_fs_base/.libs/libsvn_fs_base-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_ra_svn/.libs/libsvn_ra_svn-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_ra_dav/.libs/libsvn_ra_dav-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_delta/.libs/libsvn_delta-1.so ../../../subversion/libsvn_delta/.libs/libsvn_delta-1.so /home/pm/sw/subversion/obj2/subversion/libsvn_subr/.libs/libsvn_subr-1.so ../../../subversion/libsvn_subr/.libs/libsvn_subr-1.so /home/pm/apache/lib/libaprutil-0.so -ldb /usr/lib/libexpat.so /home/pm/apache/lib/libapr-0.so -lrt -lcrypt -lnsl -ldl /usr/lib/libneon.so -lssl -lcrypto /usr/lib/libxml2.so -lz -lpthread -lm --rpath /home/pm/subversion/lib --rpath /home/pm/apache/lib -lgcc --as-needed -lgcc_s --no-as-needed -lpthread -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-lib/i486-linux/3.3.5/crtend.o /usr/lib/gcc-lib/i486-linux/3.3.5/../../../crtn.o

Note that this explicitly refers to the build tree for the three dependent
libraries, I guess that explains why it works.

I find the libtool inter-library documentation confusing, but I think this
is a Debian bug simply because Debian's libtool fails and GNU's libtool
appears to work.  Is there some reason that Debian's libtool is not allowed
to work the same way as GNU's libtool (rpath perhaps)?  I have another
machine with Debian libtool 1.5.2-1 installed and that doesn't show the
problem, it works like GNU libtool.

One final point: while investigating this I grabbed the Debian source for
libtool 1.5.6-3 and I was surprised to see that libtool is a native package,
with a .tar.gz rather than an .orig.tar.gz and a .diff.gz.  Does libtool
really qualify to be a native package?  It makes it harder to determine 
the differences between Debian and upstream.

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.8-1-686
Locale: LANG=en_GB, LC_CTYPE=en_GB (charmap=ISO-8859-1)

Versions of packages libtool depends on:
ii  autotools-dev               20041130.2   Update infrastructure for config.{
ii  cpp                         4:3.3.5-1    The GNU C preprocessor (cpp)
ii  file                        4.12-1       Determines file type using "magic"
ii  gcc [c-compiler]            4:3.3.5-1    The GNU C compiler
ii  gcc-3.3 [c-compiler]        1:3.3.5-5    The GNU C compiler
ii  gcc-3.4 [c-compiler]        3.4.3-6      The GNU C compiler
ii  libc6-dev [libc-dev]        2.3.2.ds1-20 GNU C Library: Development Librari

-- no debconf information



Information forwarded to debian-bugs-dist@lists.debian.org:
Bug#291641; Package libtool. Full text and rfc822 format available.

Acknowledgement sent to Scott James Remnant <scott@netsplit.com>:
Extra info received and forwarded to list. Full text and rfc822 format available.

Message #10 received at 291641@bugs.debian.org (full text, mbox):

From: Scott James Remnant <scott@netsplit.com>
To: Philip Martin <philip@codematters.co.uk>, 291641@bugs.debian.org
Subject: Re: Bug#291641: libtool: resolves dependencies to the install tree rather than the build tree
Date: Sat, 22 Jan 2005 12:47:30 +0000
[Message part 1 (text/plain, inline)]
On Sat, 2005-01-22 at 01:01 +0000, Philip Martin wrote:

> Sorry this is so long, a quick summary: Debian's libtool appears to resolve
> inter-library dependencies to the install tree rather than the build tree,
> this is different from the upstream GNU behaviour and can be awkward for
> people using Debian as a development platform.
> 
I think I know what's causing this, can you just confirm something for
me though.

> This mentions libsvn_ra-1.so but doesn't mention the three dependent
> libraries, however the link normally succeeds whether or not I have
> libraries installed in $HOME/subversion/lib.
> 
This is correct behaviour for Linux.  The Linux dynamic link loader can
traverse the dependencies of shared libraries and load their
dependencies in automatically.  There is no need to link the entire
dependency tree to the binary, just the immediate dependencies.

> A recent change to the Subversion source (revision 12801) introduced
> new functions into the three dependent libraries, and made
> libsvn_ra-1.so reference those new functions.
> 
Does only libsvn_ra-1.so reference these new functions?  Or does the svn
binary reference these new functions?

> Now the link fails citing unresolved symbols corresponding to the new
> functions (and only the new functions not any of the old functions).
> 
Which link?  Linking libsvn_ra-1.so or the svn binary?

> I find the libtool inter-library documentation confusing, but I think this
> is a Debian bug simply because Debian's libtool fails and GNU's libtool
> appears to work.  Is there some reason that Debian's libtool is not allowed
> to work the same way as GNU's libtool (rpath perhaps)?  I have another
> machine with Debian libtool 1.5.2-1 installed and that doesn't show the
> problem, it works like GNU libtool.
> 
The reason is that otherwise if you change the SONAME of a library deep
in the dependency chain (e.g. libpng) you have to recompile *every*
shared library and binary above it -- which in Debian is just about
everything.


What's going wrong here is that when it links to the intermediate
library (libsvn_ra-1.so) it can find a copy of its dependencies so
checks them for consistency.

By removing the installed copy, it just can't find them, so doesn't
bother to check.

Adding -Wl,--rpath -Wl,/path/to/dependency/libs to the link line seems
to cure the problem.

We probably need to be more intelligent and rather than simply ripping
out the dependency_libs and just take out the -l lines and leave the
paths in for the linker to find.

> One final point: while investigating this I grabbed the Debian source for
> libtool 1.5.6-3 and I was surprised to see that libtool is a native package,
> with a .tar.gz rather than an .orig.tar.gz and a .diff.gz.  Does libtool
> really qualify to be a native package?  It makes it harder to determine 
> the differences between Debian and upstream.
> 
This was probably an accident, though I can't see why it would've
happened.

Scott
-- 
Have you ever, ever felt like this?
Had strange things happen?  Are you going round the twist?
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org:
Bug#291641; Package libtool. Full text and rfc822 format available.

Acknowledgement sent to Scott James Remnant <scott@netsplit.com>:
Extra info received and forwarded to list. Full text and rfc822 format available.

Message #15 received at 291641@bugs.debian.org (full text, mbox):

From: Scott James Remnant <scott@netsplit.com>
To: Philip Martin <philip@codematters.co.uk>
Cc: 291641@bugs.debian.org
Subject: Re: Bug#291641: libtool: resolves dependencies to the install tree rather than the build tree
Date: Sat, 22 Jan 2005 14:00:44 +0000
[Message part 1 (text/plain, inline)]
reassign 291641 gcc-3.3
retitle 291641 Checks dependencies of shared libraries without honouring RPATH
thanks

On Sat, 2005-01-22 at 12:47 +0000, Scott James Remnant wrote:

> On Sat, 2005-01-22 at 01:01 +0000, Philip Martin wrote:
> 
> > Sorry this is so long, a quick summary: Debian's libtool appears to resolve
> > inter-library dependencies to the install tree rather than the build tree,
> > this is different from the upstream GNU behaviour and can be awkward for
> > people using Debian as a development platform.
> > 
> I think I know what's causing this, can you just confirm something for
> me though.
> 
Yeah, I've put together a test case and confirmed what's happening here.
First let's go through the test case:

Create a binary and two levels of shared libraries beneath it.

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ mkdir a b c
$ echo "int this_is_c() { return 0; }" > c/test.c
$ echo "int this_is_b() { this_is_c(); return 0; }" > b/test.c
$ echo "int main() { this_is_b(); return 0; }" > a/test.c
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

Compile and link a shared library in 'c':

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<----
$ cd c
$ libtool --mode=compile gcc -c test.c
mkdir .libs
 gcc -c test.c  -fPIC -DPIC -o .libs/test.o
 gcc -c test.c -o test.o >/dev/null 2>&1
$ libtool --mode=link gcc -o libtestc.la -rpath /usr/local/lib test.lo
gcc -shared  .libs/test.o   -Wl,-soname -Wl,libtestc.so.0 -o .libs/libtestc.so.0.0.0
(cd .libs && rm -f libtestc.so.0 && ln -s libtestc.so.0.0.0 libtestc.so.0)
(cd .libs && rm -f libtestc.so && ln -s libtestc.so.0.0.0 libtestc.so)
ar cru .libs/libtestc.a  test.o
ranlib .libs/libtestc.a
creating libtestc.la
(cd .libs && rm -f libtestc.la && ln -s ../libtestc.la libtestc.la)
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

Do the same in 'b', and link that shared library to the libtestc.la
we've just built:

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<----
$ cd ../b
$ libtool --mode=compile gcc -c test.c
mkdir .libs
 gcc -c test.c  -fPIC -DPIC -o .libs/test.o
 gcc -c test.c -o test.o >/dev/null 2>&1
$ libtool --mode=link gcc -o libtestb.la -rpath /usr/local/lib test.lo ../c/libtestc.la
gcc -shared  .libs/test.o  -Wl,--rpath -Wl,/home/scott/tmp/lt-test/c/.libs -Wl,--rpath -Wl,/usr/local/lib ../c/.libs/libtestc.so  -Wl,-soname -Wl,libtestb.so.0 -o .libs/libtestb.so.0.0.0
(cd .libs && rm -f libtestb.so.0 && ln -s libtestb.so.0.0.0 libtestb.so.0)
(cd .libs && rm -f libtestb.so && ln -s libtestb.so.0.0.0 libtestb.so)
ar cru .libs/libtestb.a  test.o
ranlib .libs/libtestb.a
creating libtestb.la
(cd .libs && rm -f libtestb.la && ln -s ../libtestb.la libtestb.la)
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

And now compile and link a binary in 'a', linking it to *just*
libtestb.la (after all, it uses nothing from libtestc.la itself).

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ cd ../a
$ libtool --mode=compile gcc -c test.c
mkdir .libs
 gcc -c test.c  -fPIC -DPIC -o .libs/test.o
 gcc -c test.c -o test.o >/dev/null 2>&1
$ libtool --mode=link gcc -o test test.lo ../b/libtestb.la
gcc -o .libs/test .libs/test.o  ../b/.libs/libtestb.so  -Wl,--rpath -Wl,/usr/local/lib
creating test
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----


Notice that this works, I theorise that it's because gcc assumes because
it can't find the libtestc.so dependency of libtestb.so, it doesn't
bother to check the symbols match, rather than warning.

Now, let's install both shared libraries and the binary (we'll skip the
output here because Libtool relinks things to take away the rpath --
more on that in a moment).


Now let's make a change to libtestc, we'll rename the function,
recompile and relink it:

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ cd ../c
$ echo "int this_is_new_c() { return 0; }" > test.c
$ libtool --mode=compile gcc -c test.c
 gcc -c test.c  -fPIC -DPIC -o .libs/test.o
 gcc -c test.c -o test.o >/dev/null 2>&1
$ libtool --mode=link gcc -o libtestc.la -rpath /usr/local/lib test.lo rm -fr  .libs/libtestc.a .libs/libtestc.la .libs/libtestc.lai .libs/libtestc.so .libs/libtestc.so.0 .libs/libtestc.so.0.0.0
gcc -shared  .libs/test.o   -Wl,-soname -Wl,libtestc.so.0 -o .libs/libtestc.so.0.0.0
(cd .libs && rm -f libtestc.so.0 && ln -s libtestc.so.0.0.0 libtestc.so.0)
(cd .libs && rm -f libtestc.so && ln -s libtestc.so.0.0.0 libtestc.so)
ar cru .libs/libtestc.a  test.o
ranlib .libs/libtestc.a
creating libtestc.la
(cd .libs && rm -f libtestc.la && ln -s ../libtestc.la libtestc.la)
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

Obviously we now have to change libtestc, recompile and relink that too:

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ cd ../b
$ echo "int this_is_b() { this_is_new_c(); return 0; }" > test.c
$ libtool --mode=compile gcc -c test.c
 gcc -c test.c  -fPIC -DPIC -o .libs/test.o
 gcc -c test.c -o test.o >/dev/null 2>&1
$ libtool --mode=link gcc -o libtestb.la -rpath /usr/local/lib test.lo ../c/libtestc.la
rm -fr  .libs/libtestb.a .libs/libtestb.la .libs/libtestb.lai .libs/libtestb.so .libs/libtestb.so.0 .libs/libtestb.so.0.0.0
gcc -shared  .libs/test.o  -Wl,--rpath -Wl,/home/scott/tmp/lt-test/c/.libs -Wl,--rpath -Wl,/usr/local/lib ../c/.libs/libtestc.so  -Wl,-soname -Wl,libtestb.so.0 -o .libs/libtestb.so.0.0.0
(cd .libs && rm -f libtestb.so.0 && ln -s libtestb.so.0.0.0 libtestb.so.0)
(cd .libs && rm -f libtestb.so && ln -s libtestb.so.0.0.0 libtestb.so)
ar cru .libs/libtestb.a  test.o
ranlib .libs/libtestb.a
creating libtestb.la
(cd .libs && rm -f libtestb.la && ln -s ../libtestb.la libtestb.la)
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

Now, because we only linked the 'test' binary to libtestb, and we
haven't changed the SONAME, we shouldn't need to recompile or relink the
binary.  But what happens if we do?

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ cd ../a
$ libtool --mode=link gcc -o test test.lo ../b/libtestb.la
gcc -o .libs/test .libs/test.o  ../b/.libs/libtestb.so  -Wl,--rpath -Wl,/usr/local/lib
../b/.libs/libtestb.so: undefined reference to `this_is_new_c'
collect2: ld returned 1 exit status
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

This fails, because it cannot find a reference to this_is_new_c; I
theorise that because gcc *can* find a libtestc.so in /usr/local/lib, it
checks libtestb.so against that one, rather than the copy in the build
directory.

Note that gcc is clearly checking the correct libtestb.so, which is good
because it's been given the path to the one we want.


So why does this work with the upstream Libtool?  Because the upstream
Libtool, in this test case, would link the binary to *both* shared
libraries.  This is because it doesn't trust the Linux link loader to do
the right thing, when it does.

It actually turns out that all gcc needs is to know the path to the
libtestc.so in the build directory, adding an RPATH to the binary is
sufficient:

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ libtool --mode=link gcc -o test test.lo ../b/libtestb.la -Wl,--rpath -Wl,../c/.libs
gcc -o .libs/test .libs/test.o -Wl,--rpath -Wl,../c/.libs  ../b/.libs/libtestb.so  -Wl,--rpath -Wl,/usr/local/lib
creating test
---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----

Success.


So now, why do I think this is a gcc bug?

gcc is being given, without doubt, the correct libtestb.so to link -- we
pass it in directly on the command line without using -L or -l to
influence it.

And it's clearly using that library (and not the one in /usr/local/lib)
as it's the new symbol that it's failing on.

This is the library it's looking at:

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---- 
$ objdump -p b/.libs/libtestb.so

b/.libs/libtestb.so:     file format elf32-i386

Program Header:
    LOAD off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
         filesz 0x000007b0 memsz 0x000007b0 flags r-x
    LOAD off    0x000007b0 vaddr 0x000017b0 paddr 0x000017b0 align 2**12
         filesz 0x0000011c memsz 0x00000120 flags rw-
 DYNAMIC off    0x000007bc vaddr 0x000017bc paddr 0x000017bc align 2**2
         filesz 0x000000d8 memsz 0x000000d8 flags rw-
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rw-

Dynamic Section:
  NEEDED      libtestc.so.0
  NEEDED      libc.so.6
  SONAME      libtestb.so.0
  RPATH       /home/scott/tmp/lt-test/c/.libs:/usr/local/lib
  INIT        0x5d0
  FINI        0x790
  HASH        0xb4
  STRTAB      0x434
  SYMTAB      0x1e4
  STRSZ       0xef
  SYMENT      0x10
  PLTGOT      0x18a8
  PLTRELSZ    0x18
  PLTREL      0x11
  JMPREL      0x5b8
  REL         0x590
  RELSZ       0x28
  RELENT      0x8
  VERNEED     0x570
  VERNEEDNUM  0x1
  VERSYM      0x524
  RELCOUNT    0x2

Version References:
  required from libc.so.6:
    0x09691f73 0x00 02 GLIBC_2.1.3

---->8-------->8-------->8-------->8-------->8-------->8-------->8-------->8----


The library clearly indicates that it's linked to libtestc.so.0 with its
NEEDED line, gcc looks for that in /usr/local/lib (after all, it hasn't
been told anywhere better on the link line) and picks the old version.

Except gcc *does* know where the version it's supposed to be looking at
is located, the path to it is sitting in the shared library's RPATH
field:

  NEEDED      libtestc.so.0
  RPATH       /home/scott/tmp/lt-test/c/.libs:/usr/local/lib


At this point, gcc is checking the symbol references of libtestb.so
against those libraries listed in its NEEDED lines *without* honouring
the RPATH line.


In summary:

  When finding/loading a dependency of a shared library, gcc should
  honour the RPATH of that shared library.

Scott
-- 
Have you ever, ever felt like this?
Had strange things happen?  Are you going round the twist?
[signature.asc (application/pgp-signature, inline)]

Bug reassigned from package `libtool' to `gcc-3.3'. Request was from Scott James Remnant <scott@netsplit.com> to control@bugs.debian.org. Full text and rfc822 format available.

Changed Bug title. Request was from Scott James Remnant <scott@netsplit.com> to control@bugs.debian.org. Full text and rfc822 format available.

Information forwarded to debian-bugs-dist@lists.debian.org, Debian GCC maintainers <debian-gcc@lists.debian.org>:
Bug#291641; Package gcc-3.3. Full text and rfc822 format available.

Acknowledgement sent to Philip Martin <philip@codematters.co.uk>:
Extra info received and forwarded to list. Copy sent to Debian GCC maintainers <debian-gcc@lists.debian.org>. Full text and rfc822 format available.

Message #24 received at 291641@bugs.debian.org (full text, mbox):

From: Philip Martin <philip@codematters.co.uk>
To: Scott James Remnant <scott@netsplit.com>
Cc: 291641@bugs.debian.org
Subject: Re: Bug#291641: libtool: resolves dependencies to the install tree rather than the build tree
Date: Sat, 22 Jan 2005 19:02:25 +0000
Scott James Remnant <scott@netsplit.com> writes:

> On Sat, 2005-01-22 at 01:01 +0000, Philip Martin wrote:
>
>> A recent change to the Subversion source (revision 12801) introduced
>> new functions into the three dependent libraries, and made
>> libsvn_ra-1.so reference those new functions.
>> 
> Does only libsvn_ra-1.so reference these new functions?  Or does the svn
> binary reference these new functions?

Only libsvn_ra-1.so.

>> Now the link fails citing unresolved symbols corresponding to the new
>> functions (and only the new functions not any of the old functions).
>> 
> Which link?  Linking libsvn_ra-1.so or the svn binary?

The svn binary.

> Adding -Wl,--rpath -Wl,/path/to/dependency/libs to the link line seems
> to cure the problem.

I added three of those, one for each of the dependent libraries, to
the list of parameters used to invoke libtool when linking the svn
binary.  I can confirm that it does make the link succeed.

-- 
Philip Martin



Information forwarded to debian-bugs-dist@lists.debian.org, Debian GCC maintainers <debian-gcc@lists.debian.org>:
Bug#291641; Package gcc-3.3. Full text and rfc822 format available.

Acknowledgement sent to Philip Martin <philip@codematters.co.uk>:
Extra info received and forwarded to list. Copy sent to Debian GCC maintainers <debian-gcc@lists.debian.org>. Full text and rfc822 format available.

Message #29 received at 291641@bugs.debian.org (full text, mbox):

From: Philip Martin <philip@codematters.co.uk>
To: Scott James Remnant <scott@netsplit.com>
Cc: 291641@bugs.debian.org
Subject: Re: Bug#291641: libtool: resolves dependencies to the install tree rather than the build tree
Date: Sun, 23 Jan 2005 14:12:32 +0000
Scott James Remnant <scott@netsplit.com> writes:

> Except gcc *does* know where the version it's supposed to be looking at
> is located, the path to it is sitting in the shared library's RPATH
> field:
>
>   NEEDED      libtestc.so.0
>   RPATH       /home/scott/tmp/lt-test/c/.libs:/usr/local/lib
>
> At this point, gcc is checking the symbol references of libtestb.so
> against those libraries listed in its NEEDED lines *without* honouring
> the RPATH line.
>
> In summary:
>
>   When finding/loading a dependency of a shared library, gcc should
>   honour the RPATH of that shared library.

I'm not a compiler expert, but does gcc ever see that information?  I
think gcc, via collect2, invokes the ld linker to do the link and so
gcc never sees any of the NEEDED or RPATH data.  The ld linker is part
of the binutils package, not gcc.

-- 
Philip Martin



Information forwarded to debian-bugs-dist@lists.debian.org, Debian GCC maintainers <debian-gcc@lists.debian.org>:
Bug#291641; Package gcc-3.3. Full text and rfc822 format available.

Acknowledgement sent to Philip Martin <philip@codematters.co.uk>:
Extra info received and forwarded to list. Copy sent to Debian GCC maintainers <debian-gcc@lists.debian.org>. Full text and rfc822 format available.

Message #34 received at 291641@bugs.debian.org (full text, mbox):

From: Philip Martin <philip@codematters.co.uk>
To: Scott James Remnant <scott@netsplit.com>
Cc: 291641@bugs.debian.org
Subject: Re: Bug#291641: libtool: resolves dependencies to the install tree rather than the build tree
Date: Tue, 01 Feb 2005 22:39:42 +0000
Scott James Remnant <scott@netsplit.com> writes:

> On Sat, 2005-01-22 at 01:01 +0000, Philip Martin wrote:
>
>> I find the libtool inter-library documentation confusing, but I think this
>> is a Debian bug simply because Debian's libtool fails and GNU's libtool
>> appears to work.  Is there some reason that Debian's libtool is not allowed
>> to work the same way as GNU's libtool (rpath perhaps)?  I have another
>> machine with Debian libtool 1.5.2-1 installed and that doesn't show the
>> problem, it works like GNU libtool.
>> 
> The reason is that otherwise if you change the SONAME of a library deep
> in the dependency chain (e.g. libpng) you have to recompile *every*
> shared library and binary above it -- which in Debian is just about
> everything.
>
> What's going wrong here is that when it links to the intermediate
> library (libsvn_ra-1.so) it can find a copy of its dependencies so
> checks them for consistency.

As far as I can tell this is going to cause Debian packages of the, as
yet unrelease, Subversion 1.2 to fail to build on machines with
Subversion 1.1 installed.

-- 
Philip Martin



Bug reassigned from package `gcc-3.3' to `binutils'. Request was from Matthias Klose <doko@cs.tu-berlin.de> to control@bugs.debian.org. Full text and rfc822 format available.

Bug reassigned from package `binutils' to `libtool'. Request was from kurt@roeckx.be (Kurt Roeckx) to control@bugs.debian.org. (Sat, 01 Dec 2007 19:06:03 GMT) Full text and rfc822 format available.

Severity set to `important' from `normal' Request was from kurt@roeckx.be (Kurt Roeckx) to control@bugs.debian.org. (Sat, 01 Dec 2007 19:15:01 GMT) Full text and rfc822 format available.

Merged 291641 320698. Request was from kurt@roeckx.be (Kurt Roeckx) to control@bugs.debian.org. (Sat, 01 Dec 2007 19:15:02 GMT) Full text and rfc822 format available.

Send a report that this bug log contains spam.


Debian bug tracking system administrator <owner@bugs.debian.org>. Last modified: Mon Apr 21 06:06:13 2014; Machine Name: beach.debian.org

Debian Bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.