This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

finding libraries from linker via $ORIGIN


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
#!/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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]