GNU ld does not handle ORIGIN processing correctly; is there a workaround?
In Solaris, I link some stuff as follows (using Sun Studio; under the hood it uses the Solaris linker, not GNU):
CC -shared (other flags) -R'$ORIGIN/../lib/' -o /buildpath/lib/libmylib1.so
CC -shared (other flags) -R'$ORIGIN/../lib/' -lmylib1 -o /buildpath/lib/libmylib2.so
CC (various flags) -R'$ORIGIN/../lib/' -lmylib2 -o /buildpath/bin/somebinary
... and it links the final binary just fine.
When I attempt to do this in Linux with GNU ld
(again using Sun Studio as the compiler driver) the shared objects link fine, but somebinary
fails to link because it can't find libmylib1.so.
When I run the 3rd line through strace, it attempts to open a file whose path has the literal (un-expanded) string $ORIGIN
in it.
I've come across a number of other questions touching on this topic. The only workaround I've seen is to use relative paths, but that requires that you execute the binary from a fixed location -- that is, it checks relative to `pwd`
instead of the binary's location.
Before anyone chimes in with the usual comment about $ORIGIN
being unsafe/insecure -- that isn't a concern in our environment, and I don't care to hear comments about it.
It looks like I have to do it this way, though I'm not sure what side effects this may have just yet as I'm unfamiliar with the -rpath-link
flag:
CC -shared (other flags) -R'$ORIGIN/../lib/' -o /buildpath/lib/libmylib1.so
CC -shared (other flags) -R'$ORIGIN/../lib/' -lmylib1 -o /buildpath/lib/libmylib2.so
CC (various flags) -R'$ORIGIN/../lib/' -Wl,-rpath-link,/buildpath/lib/ -lmylib2 -o /buildpath/bin/somebinary
With the few tests I did, I learned the following:
$ORIGIN
does not get expanded at all by GNU ld
, whether in -rpath
or -rpath-link
flags ld.so
will expand it fine -rpath-link
is the very first set of paths searched, before -rpath
, DT_*PATH
, LD_*_PATH
, etc.