3

I'm trying to learn how to use the -rpath option in GCC's linker (ld) with $ORIGIN.

I'm trying the simplest example I can think of (see below), and all the links I read seem to say I'm doing it correctly.

However, when I run the executable it can't find the shared object unless I run it from within $ORIGIN.

Using readelf -d on the executable (main.run) shows:


0x0000000000000001 (NEEDED) Shared library: [lib/foo.so]
...
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
...

The file structure (relevant files) is:

  • /make/test/dll_test/
    • main.run
    • lib/
      • foo.so

Executing from within dll_test works fine. Executing from elsewhere (/make/test) gives the error:

dll_test/main.run: error while loading shared libraries: lib/foo.so: cannot open shared object file: No such file or directory

I'm using -l:foo.so instead of -lfoo, but this shouldn't affect anything (I hope).



SOURCE FILES

dll_test/src/foo.cpp


int foo()
    { return 1; }

dll_test/src/main.cpp


int foo();

#include <iostream&gt


int main()
  {
    std::cout &lt&lt foo() &lt&lt std::endl;
  }


BUILD SCRIPT

dll_test/make.sh


mkdir -p -v obj
mkdir -p -v lib

g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/foo.so obj/foo.o

g++ -c -o obj/main.o src/main.cpp
g++ -o main.run obj/main.o -Wl,-rpath,'$ORIGIN' -Llib -l:foo.so



To build, create these files in their respective locations and simply run "sh make.sh" from within dll_test (or wherever the project root is). It should generate "dll_test/main.run".

Running "main.run" from within dll_test should work (prints 1).
Running "main.run" from within dll_test fails. Why?

Also, foo.so's path stored in main.run as [lib/foo.so]. Can I get it to be [foo.so] so I can use the -Wl,-rpath,'$ORIGIN/lib' ?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Simon
  • 623
  • 1
  • 8
  • 13
  • Apologies for the editing before. NoScript hid the preview and I assumed I was writing raw text. – Simon Jun 09 '11 at 09:57
  • As this question is a bit confusing, I rewrote it here: http://stackoverflow.com/questions/6311016/building-a-simple-hello-world-esque-example-of-using-lds-option-rpath-with-o – Simon Jun 10 '11 at 19:12

1 Answers1

0

You need -Wl,-rpath,'$ORIGIN/lib' instead of just '$ORIGIN'.

edit: Are you actually entering -l:foo.so? That seems odd... you should be just fine with -Wl,-rpath,'$ORIGIN/lib' -Llib -lfoo.so. If that doesn't work, add -Wl,-soname,libfoo.so to the linker command for your shared library. I'm not positive that this will fix the "lib/foo.so" issue, but it's worth a shot :)

Tom
  • 10,689
  • 4
  • 41
  • 50
  • The `-l:foo.so` is accurate. I'm trying to avoid using the `lib` prefix in my code as it's superfluous, linux-specific and IMO harder to read. – Simon Jun 10 '11 at 14:57
  • Tried all combinations of `$ORIGIN/lib`, `$ORIGIN`, `-Llib` vs no -L. No luck. Tried `-lfoo.so` and `-soname`, no luck there either. – Simon Jun 10 '11 at 15:00