Assume a shared libraries “foo.so” doesn’t contain the linker tag SONAME (nor DT_SONAME) such that ~$ readelf -Wa libfoo.so | grep SONAME is empty If this is the case, this prevents ld/gcc to correctly link this shared library in via direct reference to the shared object file (see line (***1***)), e.g. calling ld via g++: /usr/bin/c++ -fPIC -Wno-long-long -Wall -Wextra -O0 -g -g -Wl,--unresolved-symbols=ignore-in-shared-libs -shared\ -Wl,-soname,libmylib.so -o ../../BIN/libmylib.so\ … object-files … -L/lib/paths … -llibs … /full/path/to/so's .. /path/to/libfoo.so \ (***1***) -Wl,rpath, rpath stuff This yields a binary with the full path to the so-name for foo, which is only valid on the build machine: ~$ ldd libmylib.so | grep foo /path/to/libfoo.so (0xf53bc000) If we instead link with “-l” and “-L” flags like this /usr/bin/c++ -fPIC -Wno-long-long -Wall -Wextra -O0 -g -g -Wl,--unresolved-symbols=ignore-in-shared-libs -shared\ -Wl,-soname,libmylib.so -o ../../BIN/libmylib.so\ … object-files … -L/lib/paths … -llibs … /full/path/to/so -lfoo\ (***2***) -Wl,rpath, rpath stuff the soname is correctly entered in the resulting binary: ~$ ldd libmylib.so | grep foo libfoo.so => /path/to/libfoo.so (0xf5462000) So for the moment we are using the latter approach as a workaround, but for the future it would be preferable if ld could take only the filename-part (i.e. "libfoo.so") from the full so-path "/path/to/libfoo.so" and enter this into the binary "libmylib.so".
This is working as intended (and changing it will break lots of clients). If you don't want full path to libfoo.so be put into DT_NEEDED of libmylib.so, then either use '-lfoo', or set SONAME in libfoo.so itself (i.e. use the two workarounds you've already found).
I understand that there is a risk of breaking "lots of clients". I could not find any documentation on this behaviour (=putting the whole path into DT_NEEDED), so I can imagine others to be as astonished as I was. The problem I see is that the resulting binary "libmylib.so" will in general only be runnable on the build machine, since the path cannot be resolved in another environment. If this is what is intended, it should at least be documented somewhere as well, shouldn't it? (ad "add the SONAME"): Changing it's SONAME is difficult, if "libfoo.so" is a closed-source 3rd-party product.
(In reply to comment #2) > I could not find any documentation on this behaviour You are welcome to find a place where you think this should have been documented, and send a patch to update the documentation. > (=putting the whole path > into DT_NEEDED), so I can imagine others to be as astonished as I was. As far as I can tell, this is how all ELF systems (and several non-ELF systems) behaved since forever. > The problem I see is that the resulting binary "libmylib.so" will in general > only be runnable on the build machine Sometimes (though rarely) that's exactly the desired behavior. > (ad "add the SONAME"): Changing it's SONAME is difficult, if "libfoo.so" is a > closed-source 3rd-party product. But linking with -lfoo is usually not difficult, and the way it should generally be done anyway.