finding libraries from linker via $ORIGIN

Oliver Kiddle okiddle@yahoo.co.uk
Wed Apr 10 16:31:00 GMT 2013


It seems the bfd linker reads in all shared libraries from transitive
library dependencies. When using --no-copy-dt-needed-entries this is
surely fairly pointless? The consequence is that when using $ORIGIN,
I need to use -rpath-link for the locations of all possible transitive
dependencies of any shared libraries used. In the case of the software
I'm dealing with, this isn't realistically possible. The gold linker
and Sun's linker work fine albeit for different reasons. I had a look
at what it would take to change bfd ld to handle this, and got as far as
establishing that removing the link_info.executable part of the following
condition gets very close to doing the job. The remaining problem seems to
be that it then fails because of symbols in ld-linux-x86-64.so.2 needed
by libc.so.6. How does gold handle this? Is there a further test that
can be used to further qualify this condition test?

 elf32.em

   1196       if (l->by != NULL
   1197           && ((bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0
   1198               || (!link_info.executable
   1199                   && bfd_elf_get_dyn_lib_class (l->by) & DYN_NO_ADD_NEEDED) != 0))
   1200         continue

An alternative solution is to expand $ORIGIN when searching for
libraries. That is perhaps what the Solaris linker does because it
complains if I delete the library. Presumably, that would go in the same
file after the run path is split on config.rpath_separator?

I've attached a short shell script that does the minimum to reproduce
the situation.

Is there a way to force gcc to use a different linker that I can control
from a Makefile (such as via an environment variable). Or is my only
option to make sure that the ld found via the PATH is gold and not the
old linker?

Thanks

Oliver
-------------- next part --------------
#!/bin/zsh
set -x -e
a=1;
for f in lib{1,2} main; do
  mkdir $f
  echo "int $f() { return $a; }" > $f.c
  a="1+$f()"
done
gcc -shared -Wl,--no-add-needed -Wl,-z,defs -o lib1/lib1.so -fPIC lib1.c
gcc -shared -Wl,--no-add-needed -Wl,-z,defs -o lib2/lib2.so -fPIC lib2.c -Llib1 -Wl,-rpath,\$ORIGIN/../lib1 -l1
gcc -o main/main -Wl,--no-add-needed main.c -Llib2 -Wl,-rpath,\$ORIGIN/../lib2 -l2


More information about the Binutils mailing list