[Bug 923779] Re: cross-linker behaviour differs from native linked
Launchpad Bug Tracker
923779 at bugs.launchpad.net
Wed Dec 5 08:42:52 UTC 2012
** Branch linked: lp:ubuntu/raring-proposed/binutils-armhf-cross
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to binutils in Ubuntu.
https://bugs.launchpad.net/bugs/923779
Title:
cross-linker behaviour differs from native linked
Status in “armel-cross-toolchain-base” package in Ubuntu:
Triaged
Status in “armhf-cross-toolchain-base” package in Ubuntu:
New
Status in “binutils” package in Ubuntu:
Fix Released
Status in “binutils-armel-cross” package in Ubuntu:
New
Status in “binutils-armhf-cross” package in Ubuntu:
New
Bug description:
This requires a bit of background to understand. From the man page of
ld(1).
-snip-
-rpath-link=dir
When using ELF or SunOS, one shared library may require another.
This happens when an "ld -shared" link includes a shared library as
one of the input files.
When the linker encounters such a dependency when doing a non-
shared, non-relocatable link, it will automatically try to locate
the required shared library and include it in the link, if it is
not included explicitly. In such a case, the -rpath-link option
specifies the first set of directories to search. The -rpath-link
option may specify a sequence of directory names either by
specifying a list of names separated by colons, or by appearing
multiple times.
This option should be used with caution as it overrides the search
path that may have been hard compiled into a shared library. In
such a case it is possible to use unintentionally a different
search path than the runtime linker would do.
The linker uses the following search paths to locate required
shared libraries:
1. Any directories specified by -rpath-link options.
2. Any directories specified by -rpath options. The difference
between -rpath and -rpath-link is that directories specified by
-rpath options are included in the executable and used at
runtime, whereas the -rpath-link option is only effective at
link time. Searching -rpath in this way is only supported by
native linkers and cross linkers which have been configured
with the --with-sysroot option.
3. On an ELF system, for native linkers, if the -rpath and
-rpath-link options were not used, search the contents of the
environment variable "LD_RUN_PATH".
4. On SunOS, if the -rpath option was not used, search any
directories specified using -L options.
5. For a native linker, the search the contents of the environment
variable "LD_LIBRARY_PATH".
6. For a native ELF linker, the directories in "DT_RUNPATH" or
"DT_RPATH" of a shared library are searched for shared
libraries needed by it. The "DT_RPATH" entries are ignored if
"DT_RUNPATH" entries exist.
7. The default directories, normally /lib and /usr/lib.
8. For a native linker on an ELF system, if the file
/etc/ld.so.conf exists, the list of directories found in that
file.
If the required shared library is not found, the linker will issue
a warning and continue with the link.
-snip-
Our concern are the sections 3, 5, 6, 8 and indirectly 7 (/usr/lib
/arm-linux-gnueabi isn't apparently considered default directory).
The problem is, that while we search for libraries in /usr/lib/arm-
linux-gnueabi, the search is not _recursive_. Take case that we link
against -lhi, which in turn uses symbols from -lhi. With a native
toolchain, we can just build by giving "gcc -lhi". With current cross-
toolchain, that is not enough.
The attached testcase, which succeeds on native ld, will fail with the
cross-toolchain with:
-snip-
/usr/lib/gcc/arm-linux-gnueabi/4.6/../../../../arm-linux-gnueabi/bin/ld: warning: liblo.so, needed by /usr/lib/arm-linux-gnueabi/libhi.so, not found (try using -rpath or -rpath-link)
/usr/lib/arm-linux-gnueabi/libhi.so: undefined reference to `alowcall'
collect2: ld returned 1 exit status
-snip-
Changing the last line to either:
arm-linux-gnueabi-gcc hiuser.c -llo -lhi -o foouser
arm-linux-gnueabi-gcc hiuser.c -Wl,-rpath-link=/usr/lib/arm-linux-gnueabi -lhi -o foouser
Will make the build succeed.
We have a bunch of options here:
1) patch ld to make cross-ld behave identically to ld. This can be done by setting "NATIVE=yes" in genscripts.sh of binutils
2) add /usr/lib/arm-linux-gnueabi to default directories (after quick search didn't find out how). This could still risk breaking if there are packages that use LD_LIBRARY_PATH during buildtime
3) tell people to change their buildscripts to add all libraries to the linking command line. This is tricky, as most people don't select the -lflags them self, they come from pkg-config et all. Further more, people have been actively endorsing doing the complete opposite, eg. removing all unnecessary -lflags to cut down package dependencies.
4) copy the ld wrapper from scratchbox that adds the default directories and LD_LIBRARY_PATH with -rpath-link to the real linkier... I don't think we want that, but just for sake of completeness lets mention it ;)
Discuss.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/armel-cross-toolchain-base/+bug/923779/+subscriptions
More information about the foundations-bugs
mailing list