Search code examples
gcclinkerldrhel5ubuntu-24.04

Can I link an executable without recursively checking its shared objects references/linkage?


I'm building an executable which needs to link to some legacy shared objects to not only use the version of symbols exported by those, but also ensure that the sections of .gnu.version_r section as is properly populated well.

In short, this executable has to be built on Ubuntu 24.04 but runnable on RHEL5/6/7.

For example, when linking my executable on Ubuntu 24.04 I use the libpthread.so.0 from RHEL5 to ensure the max version of functions used is GLIBC_2.5 and (crucially) the the .gnu.version_r for libpthread.so.0 does exist and is populated indeed with the requirement to load only symbol version GLIBC_2.5.

Generally, I could use the __asm__(".symver func,func@GLIBC_2.5") directive, but because libraries (such as libpthread, libdl, libutil, ...) have been consolidated in libc on modern OSes (Ubuntu 24.04, RHEL9, ....), I need to link to a libpthread.so.0 really exporting those symbols/versions to ensure the .gnu.version_r of the resulting executable is also populated, otherwise my executable won't run on RHEL5/6/7.

When I use such approach and link an executable, seems like ld (the linker) tries to fully resolve all the symbol dependencies recursively, and because RHEL5's libpthread.so.0 depends on some GLIBC_PRIVATE symbols exported by RHEL5's libc.so.6 and ld-linux-x86-64.so.2, I end up exporting/copying those libs from RHEL5 and adding those to the linking phase.

Is there a way when linking an executable to skip this recursive check and just ensure the the first level of shared object linking has to be valid?

I had in mind the opposite of something like -Wl,--no-undefined but not sure this option does exist?

Alternatively I could create some shallow libraries copy of libdl, libpthread, libutil, ... exporting the same symbols/versions as RHEL5, just to be used during linking phase - and being 'empty' and not having dependencies, those would in essence just let me 'link'.

Thanks!


Solution

  • I think I found this useful option to fit my bill:

    -Wl,--unresolved-symbols=ignore-in-shared-libs

    Seems to be working and just do what's needed!