Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences in linking behavior between Ubuntu and CentOS

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).

like image 625
Florian Rhiem Avatar asked Jan 27 '26 21:01

Florian Rhiem


1 Answers

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.

like image 169
rici Avatar answered Jan 31 '26 00:01

rici