[Bug 923779] Re: cross-linker behaviour differs from native linked
doko at ubuntu.com
Fri Sep 7 20:12:23 UTC 2012
** Changed in: binutils (Ubuntu)
Status: Incomplete => Fix Released
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to binutils in Ubuntu.
cross-linker behaviour differs from native linked
Status in “armel-cross-toolchain-base” package in Ubuntu:
Status in “binutils” package in Ubuntu:
This requires a bit of background to understand. From the man page of
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
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
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
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
If the required shared library is not found, the linker will issue
a warning and continue with the link.
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
/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
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 ;)
To manage notifications about this bug go to:
More information about the foundations-bugs