I'm building two shared libraries, with one library (B) dependent on the other (A) and both being built with an rpath of $ORIGIN/., then link an executable to library B. So the dependencies are as follows:
executable C -> library B -> library A
On Ubuntu, B's dependency on A is resolved using its rpath, while on CentOS the linker warns that A could not be found and I should use "try using -rpath or -rpath-link" during the compilation of the executable.
Here's a minimal example to reproduce the issue:
mkdir testdir
echo 'void a() {}' > testdir/a.c
echo 'int a(); void b() { a(); }' > testdir/b.c
echo 'int b(); int main() { b(); }' > testdir/c.c
gcc testdir/a.c -shared -o testdir/liba.so -Wl,-rpath,'$ORIGIN/.' -fPIC
gcc testdir/b.c -Ltestdir -la -shared -o testdir/libb.so -Wl,-rpath,'$ORIGIN/.' -fPIC
gcc testdir/c.c -Ltestdir -lb -o testdir/a.out
What difference between linking behavior on Ubuntu and CentOS is causing this issue? Is there a way that I can "fix" this, so that A will be resolved without having to rely on things like LD_LIBRARY_PATH?
Update: If I use the absolute path to the library directory instead of $ORIGIN, this seems to work. Of course I don't know the absolute path to where they will be deployed, so this doesn't solve this issue, but it points to $ORIGIN not being supported by CentOS 7 (or its loader).
I think the problem here could be this bug, reported against binutils 2.26 but presumably present in earlier versions as well. The issue is that the linker ld, unlike the dynamic loader ld.so, did not interpret the special replacement string $ORIGIN in the rpath, so only an absolute path could be used.
The bug was marked as fixed in binutils 2.28, but Centos 7 has binutils 2.27. Ubuntu 18.4, on the other hand, uses binutils 2.30.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With