Bug 6753 - In a prefixed install, -L order is not respected when searching for -l<libname>, but -T fixes it
Summary: In a prefixed install, -L order is not respected when searching for -l<libnam...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.18
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-20 23:34 UTC by Sunil
Modified: 2008-08-09 12:50 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
shell script to reproduce the bug (320 bytes, text/plain)
2008-07-23 18:40 UTC, Sunil
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sunil 2008-07-20 23:34:58 UTC
I am building with in prefix /home/devsk/portage and binutils is configured with:

./configure --prefix=/home/devsk/portage/usr --host=i686-pc-linux-gnu
--target=i686-pc-linux-gnu
--datadir=/home/devsk/portage/usr/share/binutils-data/i686-pc-linux-gnu/2.18.50.0.7
--infodir=/home/devsk/portage/usr/share/binutils-data/i686-pc-linux-gnu/2.18.50.0.7/info
--mandir=/home/devsk/portage/usr/share/binutils-data/i686-pc-linux-gnu/2.18.50.0.7/man
--bindir=/home/devsk/portage/usr/i686-pc-linux-gnu/binutils-bin/2.18.50.0.7
--libdir=/home/devsk/portage/usr/lib/binutils/i686-pc-linux-gnu/2.18.50.0.7
--libexecdir=/home/devsk/portage/usr/lib/binutils/i686-pc-linux-gnu/2.18.50.0.7
--includedir=/home/devsk/portage/usr/lib/binutils/i686-pc-linux-gnu/2.18.50.0.7/include
--enable-64-bit-bfd --enable-shared --disable-werror --disable-nls
--build=i686-pc-linux-gnu --disable-nls --with-gnu-ld --enable-debug=no
--disable-debug
-with-lib-path=/home/devsk/portage/lib:/home/devsk/portage/usr/lib:/home/devsk/portage/usr/X11R6/lib:/usr/X11R6/lib:/usr/lib:/lib
--x-includes=/home/devsk/portage/usr/include
--x-libraries=/home/devsk/portage/usr/lib

GCC is gcc-4.2.4

This link fails to find appropriate libfontconfig.so:

/home/devsk/portage/usr/bin/ld --verbose -v --eh-frame-hdr -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 -o kdesktop_lock /usr/lib/crt1.o
/usr/lib/crti.o
/home/devsk/portage/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/crtbegin.o 
-L/home/devsk/portage/lib -L/home/devsk/portage/usr/lib
-L/home/devsk/portage/usr/kde/3.5/lib -L/home/devsk/portage/usr/qt/3/lib
-L/usr/X11R6/lib -L/usr/lib
-L/home/devsk/portage/usr/lib/gcc/i686-pc-linux-gnu/4.2.4
-L/home/devsk/portage/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/../../../../i686-pc-linux-gnu/lib
-L/home/devsk/portage/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/../../..
kdesktop_lock.all_cc.o ../.libs/libkdesktopsettings.a
../../kdmlib/.libs/libdmctl.a /home/devsk/portage/usr/kde/3.5/lib/libkio.so
/home/devsk/portage/usr/kde/3.5/lib/libkdeui.so
/home/devsk/portage/usr/kde/3.5/lib/libkdesu.so
/home/devsk/portage/usr/kde/3.5/lib/libkwalletclient.so
/home/devsk/portage/usr/kde/3.5/lib/libkdecore.so -L= -lutempter
/home/devsk/portage/usr/kde/3.5/lib/libDCOP.so -lresolv -lutil
/home/devsk/portage/usr/lib/libart_lgpl_2.so
/home/devsk/portage/usr/lib/libidn.so
/home/devsk/portage/usr/kde/3.5/lib/libkdefx.so
/home/devsk/portage/usr/qt/3/lib/libqt-mt.so -lmng -ljpeg -lpng -lfontconfig
/home/devsk/portage/usr/lib/libmng.so /home/devsk/portage/usr/lib/liblcms.so
/home/devsk/portage/usr/lib/libjpeg.so /home/devsk/portage/usr/lib/libXrandr.so
/home/devsk/portage/usr/lib/libXcursor.so
/home/devsk/portage/usr/lib/libXfixes.so /home/devsk/portage/usr/lib/libXft.so
/home/devsk/portage/usr/lib/libfontconfig.so
/home/devsk/portage/usr/lib/libfreetype.so
/home/devsk/portage/usr/lib/libexpat.so /home/devsk/portage/usr/lib/libpng12.so
/home/devsk/portage/usr/lib/libXrender.so -lz
/home/devsk/portage/usr/lib/libfam.so
/home/devsk/portage/usr/lib/libXxf86misc.so /usr/lib/libGLU.so
/home/devsk/portage/usr/lib/libSM.so /home/devsk/portage/usr/lib/libICE.so
/home/devsk/portage/usr/lib/libXmu.so /home/devsk/portage/usr/lib/libXt.so
/home/devsk/portage/usr/lib/libXext.so /home/devsk/portage/usr/lib/libXi.so
-lpthread -lGL /home/devsk/portage/usr/lib/libX11.so
/home/devsk/portage/usr/lib/libXau.so /home/devsk/portage/usr/lib/libXdmcp.so
-ldl --rpath /home/devsk/portage/usr/kde/3.5/lib --rpath
/home/devsk/portage/usr/lib --rpath /home/devsk/portage/usr/qt/3/lib --rpath
/home/devsk/portage/usr/kde/3.5/lib --rpath /home/devsk/portage/usr/lib --rpath
/home/devsk/portage/usr/qt/3/lib -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/home/devsk/portage/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/crtend.o /usr/lib/crtn.o
> /tmp/tmper 2>&1

/home/devsk/portage/usr/lib is ahead of /usr/lib in -L search order but the
verbose output shows:

-lpng (/usr/lib/libpng.so)
attempt to open /home/devsk/portage/usr/kde/3.5/lib/libfontconfig.so failed
attempt to open /home/devsk/portage/usr/kde/3.5/lib/libfontconfig.a failed
attempt to open /home/devsk/portage/usr/qt/3/lib/libfontconfig.so failed
attempt to open /home/devsk/portage/usr/qt/3/lib/libfontconfig.a failed
attempt to open /usr/X11R6/lib/libfontconfig.so failed
attempt to open /usr/X11R6/lib/libfontconfig.a failed
attempt to open /usr/lib/libfontconfig.so succeeded
-lfontconfig (/usr/lib/libfontconfig.so)

The internal script has the SEARCH_DIR paths set correctly to specify 
/home/devsk/portage/usr/lib ahead of system paths.

If I invoke ld with -T and provide the same linker script explicitly, it finds
the libraries in correct order.

So, the internal script and external script provided to ldwith -T are same
(verified in --verbose mode) but their treatment is different. That's the bug.
Comment 1 Sunil 2008-07-20 23:57:43 UTC
the command line is generated by libtool and I just passed '-v -v ' to g++ to
get to the eventual ld command line. I tried adding -L= for fun but the result
was same without -L=. All libs specified with -l were found in /usr/lib instead
of /home/devsk/portage/usr/lib.
Comment 2 H.J. Lu 2008-07-22 15:05:12 UTC
Please provide a SMALL STANDALONE testcase.
Comment 3 Sunil 2008-07-23 18:40:36 UTC
Created attachment 2838 [details]
shell script to reproduce the bug

the script assumes you have /tmp and you can create /tmp/mydir. Rest it does by
itself.

I am not sure if you need to have a gcc/ld install in a prefix to reproduce but
my guess is shouldn't matter. Make sure you have libfontconfig.so in other
usual places like /usr/lib or $PREFIX/usr/lib. Otherwise change the script to
call it something like libm. I just wanted some name not belonging to libc
family.
Comment 4 H.J. Lu 2008-07-23 19:45:52 UTC
(In reply to comment #3)
> Created an attachment (id=2838)
> shell script to reproduce the bug
> 
> the script assumes you have /tmp and you can create /tmp/mydir. Rest it does by
> itself.
> 
> I am not sure if you need to have a gcc/ld install in a prefix to reproduce but
> my guess is shouldn't matter. Make sure you have libfontconfig.so in other
> usual places like /usr/lib or $PREFIX/usr/lib. Otherwise change the script to
> call it something like libm. I just wanted some name not belonging to libc
> family.
> 

There is no -L in your test.
Comment 5 Sunil 2008-07-23 20:38:05 UTC
OK, I thought it would be that easy and messed up confusing -rpath-link with -L.

But I sidetracked from the original bug, which is about a prefix install and -T
fixing it. Assuming, you have installed binutils with --prefix=$PREFIX, do this:

cd /tmp/mydir
gcc -shared -o libmylib.so mysymbol.o
mv libmylib.so $PREFIX/usr/lib/libmylib.so
cp /usr/lib/libcwait.so /usr/lib/libmylib.so
gcc -o mymain mymain.o -L$PREFIX/usr/lib -L/usr/lib -lmylib

It won't honor the -L$PREFIX/usr/lib but pick libmylib.so up from /usr/lib. But
when you get the command line for ld using gcc -c followed by collect2 -v, and
use -T option to specify the linker script, it will work. Linker script used in
both cases (internal or external with -T) is same as can be seen from --verbose
output.

In my case, it was:

/scratch/devsk/usr/bin/ld -v -T
/scratch/devsk/usr/lib/binutils/i686-pc-linux-gnu/2.18.50.0.7/ldscripts/elf_i386.xc
--eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o mymain
/usr/lib/crt1.o /usr/lib/crti.o
/scratch/devsk/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/crtbegin.o
-L/scratch/devsk/usr/lib -L/usr/lib
-L/scratch/devsk/usr/lib/gcc/i686-pc-linux-gnu/4.2.4
-L/scratch/devsk/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/../../../../i686-pc-linux-gnu/lib
-L/scratch/devsk/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/../../.. mymain.o  -lmylib
-lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s
--no-as-needed /scratch/devsk/usr/lib/gcc/i686-pc-linux-gnu/4.2.4/crtend.o
/usr/lib/crtn.o

Comment 6 Sunil 2008-07-23 20:42:26 UTC
I used "--prefix=/scratch/devsk
-with-lib-path=/scratch/devsk/lib:/scratch/devsk/usr/lib:/usr/lib:/lib ...."
when configuring, so that /scratch/devsk/lib:/scratch/devsk/usr/lib would be in
SEARCH_DIR of LD by default.
Comment 7 H.J. Lu 2008-07-23 22:05:05 UTC
(In reply to comment #6)
> I used "--prefix=/scratch/devsk
> -with-lib-path=/scratch/devsk/lib:/scratch/devsk/usr/lib:/usr/lib:/lib ...."
> when configuring, so that /scratch/devsk/lib:/scratch/devsk/usr/lib would be in
> SEARCH_DIR of LD by default.

You have a very strange setup. You better come up with a testcase
which doesn't require me to copy things into /usr/lib.
Comment 8 Sunil 2008-07-23 22:28:36 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > I used "--prefix=/scratch/devsk
> > -with-lib-path=/scratch/devsk/lib:/scratch/devsk/usr/lib:/usr/lib:/lib ...."
> > when configuring, so that /scratch/devsk/lib:/scratch/devsk/usr/lib would be in
> > SEARCH_DIR of LD by default.
> 
> You have a very strange setup. You better come up with a testcase
> which doesn't require me to copy things into /usr/lib.

so, don't copy. change the name libmylib.so to libcwait.so. Or pick another
library name which is in /usr/lib and use that. Only condition is binutils needs
to be installed in a prefix and the same library needs to be present in
$PREFIX/usr/lib/ and /usr/lib and with "-L$PREFIX/usr/lib -L/usr/lib", ld will
just pick the one form /usr/lib.
Comment 9 H.J. Lu 2008-07-24 04:58:10 UTC
(In reply to comment #8)
> > 
> > You have a very strange setup. You better come up with a testcase
> > which doesn't require me to copy things into /usr/lib.
> 
> so, don't copy. change the name libmylib.so to libcwait.so. Or pick another
> library name which is in /usr/lib and use that. Only condition is binutils needs
> to be installed in a prefix and the same library needs to be present in
> $PREFIX/usr/lib/ and /usr/lib and with "-L$PREFIX/usr/lib -L/usr/lib", ld will
> just pick the one form /usr/lib.

Please provide a testcase I can try.
Comment 10 Sunil 2008-07-24 05:38:43 UTC
(In reply to comment #9)
> (In reply to comment #8)
> > > 
> > > You have a very strange setup. You better come up with a testcase
> > > which doesn't require me to copy things into /usr/lib.
> > 
> > so, don't copy. change the name libmylib.so to libcwait.so. Or pick another
> > library name which is in /usr/lib and use that. Only condition is binutils needs
> > to be installed in a prefix and the same library needs to be present in
> > $PREFIX/usr/lib/ and /usr/lib and with "-L$PREFIX/usr/lib -L/usr/lib", ld will
> > just pick the one form /usr/lib.
> 
> Please provide a testcase I can try.
> 

The bug reproduces only in a prefixed environment. And if you have a prefixed
binutils install, the steps mentioned by me should reproduce the problem:

1. run the script
2. cd /tmp/mydir
3 gcc -shared -o libcwait.so mysymbol.o
4 mv libcwait.so $PREFIX/usr/lib/libcwait.so
5. gcc -o mymain mymain.o -L$PREFIX/usr/lib -L/usr/lib -lcwait

You can use any other name for library. It should be already present in /usr/lib.

The link will fail with undefined symbol.

This is the minimal I can do. The bug is pretty obvious in prefix env.
Comment 11 H.J. Lu 2008-07-24 14:21:38 UTC
(In reply to comment #10)
> (In reply to comment #9)
> > (In reply to comment #8)
> > > > 
> > > > You have a very strange setup. You better come up with a testcase
> > > > which doesn't require me to copy things into /usr/lib.
> > > 
> > > so, don't copy. change the name libmylib.so to libcwait.so. Or pick another
> > > library name which is in /usr/lib and use that. Only condition is binutils
needs
> > > to be installed in a prefix and the same library needs to be present in
> > > $PREFIX/usr/lib/ and /usr/lib and with "-L$PREFIX/usr/lib -L/usr/lib", ld will
> > > just pick the one form /usr/lib.
> > 
> > Please provide a testcase I can try.
> > 
> 
> The bug reproduces only in a prefixed environment. And if you have a prefixed
> binutils install, the steps mentioned by me should reproduce the problem:
> 
> 1. run the script
> 2. cd /tmp/mydir
> 3 gcc -shared -o libcwait.so mysymbol.o
> 4 mv libcwait.so $PREFIX/usr/lib/libcwait.so
> 5. gcc -o mymain mymain.o -L$PREFIX/usr/lib -L/usr/lib -lcwait
> 
> You can use any other name for library. It should be already present in /usr/lib.
> 
> The link will fail with undefined symbol.
> 
> This is the minimal I can do. The bug is pretty obvious in prefix env.

I can't reproduce it. I configured binutils with

--prefix=$HOME/bugs/binutils/6753/usr

bash-3.2$ make
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -I. -fPIC   -c -o
mysymbol.o mysymbol.c
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -shared -o libcrypt.so
mysymbol.o
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -I.   -c -o mymain.o
mymain.c
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -o foo mymain.o -lcrypt
-L/export/home/hjl/bugs/binutils/6753/usr/usr/lib
bash-3.2$ ls -l /export/home/hjl/bugs/binutils/6753/usr/usr/lib
total 4
-rwxr-xr-x 1 hjl hjl 4000 2008-07-24 07:14 libcrypt.so
bash-3.2$ gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -o foo
mymain.o -lcrypt -L/export/home/hjl/bugs/binutils/6753/usr/usr/lib
bash-3.2$ gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -o foo
mymain.o -lcrypt -L/export/home/hjl/bugs/binutils/6753/usr/lib
mymain.o: In function `main':
mymain.c:(.text+0x12): undefined reference to `mysymbol'
collect2: ld returned 1 exit status
bash-3.2$ mv usr/usr/lib/libcrypt.so usr/lib
bash-3.2$ gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -o foo
mymain.o -lcrypt -L/export/home/hjl/bugs/binutils/6753/usr/lib
bash-3.2$ 

Comment 12 Sunil 2008-07-24 15:52:18 UTC
you did not specify -L/usr/lib on the link line. The point is that
$PREFIX/usr/lib loses out to /usr/lib when specified before it.
Comment 13 H.J. Lu 2008-07-24 16:56:23 UTC
Still works for me with Today's CVS:

[hjl@gnu-6 6753]$ make
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -I. -fPIC   -c -o
mysymbol.o mysymbol.c
mkdir -p /export/home/hjl/bugs/binutils/6753/usr/usr/lib
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -shared -o
/export/home/hjl/bugs/binutils/6753/usr/usr/lib/libcrypt.so mysymbol.o
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -I.   -c -o mymain.o
mymain.c
gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -o foo mymain.o -lcrypt
-L/export/home/hjl/bugs/binutils/6753/usr/usr/lib -L/usr/lib
[hjl@gnu-6 6753]$ 
Comment 14 Sunil 2008-07-24 17:13:44 UTC
(In reply to comment #13)
> Still works for me with Today's CVS:
> 
> [hjl@gnu-6 6753]$ make
> gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -I. -fPIC   -c -o
> mysymbol.o mysymbol.c
> mkdir -p /export/home/hjl/bugs/binutils/6753/usr/usr/lib
> gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -shared -o
> /export/home/hjl/bugs/binutils/6753/usr/usr/lib/libcrypt.so mysymbol.o
> gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -I.   -c -o mymain.o
> mymain.c
> gcc -m32 -B/export/home/hjl/bugs/binutils/6753/usr/bin/ -o foo mymain.o -lcrypt
> -L/export/home/hjl/bugs/binutils/6753/usr/usr/lib -L/usr/lib
> [hjl@gnu-6 6753]$ 

Is there a CHANGELOG for cvs version I can inspect with respect to 2.18.50.0.7?
Comment 15 H.J. Lu 2008-07-24 17:23:27 UTC
(In reply to comment #14)
> 
> Is there a CHANGELOG for cvs version I can inspect with respect to 2.18.50.0.7?

There are ChangeLog files in each subdirectory. You can do a diff on
them.
Comment 16 Sunil 2008-07-24 17:37:10 UTC
(In reply to comment #15)
> (In reply to comment #14)
> > 
> > Is there a CHANGELOG for cvs version I can inspect with respect to 2.18.50.0.7?
> 
> There are ChangeLog files in each subdirectory. You can do a diff on
> them.

I don't have CVS access at my place. Can you please attach latest CHANGELOG to
this bug?
Comment 17 H.J. Lu 2008-07-24 17:46:16 UTC
You can download the Linux binutils source from

http://www.kernel.org/pub/linux/devel/binutils/

and compare ChangeLogs.
Comment 18 Sunil 2008-07-24 17:58:10 UTC
Is 2.18.50.0.8 the release where you reported success?
Comment 19 H.J. Lu 2008-07-24 17:59:32 UTC
(In reply to comment #18)
> Is 2.18.50.0.8 the release where you reported success?

It should work.
Comment 20 Alan Modra 2008-08-08 15:27:28 UTC
I can't reproduce this with current sources.  Are you sure that using a -T
script  in place of the built-in one affects search order in directories
specified by -L?

However, I can see a bug:  ldmain.c:set_scripts_dir might change search order
between the default script and specifying exactly the same script via -T, but
only if you are *not* using -L, ie. if you are relying on SEARCH_DIR in the script.