Given that the executable is like this:
>objdump -x someprog | grep c++ NEEDED libstdc++.so.6
I want to change the requirement for the full version (including the minor version and the fix level):
>objdump -x someprog | grep c++ NEEDED libstdc++.so.6.0.22
I know two ways to do this:
- create a dummy library on this subject ( forcing or preventing the use of a specific minor version of libstdc ++ )
- use patchelf
> patchelf --add-needed libstdc ++. so.6.0.22 someprog
> objdump -x someprog | grep c ++
NEEDED libstdc ++. So.6
NEEDED libstdc ++. So.6.0.22
(I did not calculate the working command line for -replace-needed)
Both of them feel like hacks to me. Is there a way to achieve this at compile time or link time using the appropriate -Wl flags for gcc?
Ideally, I want to avoid using -nostdlib since I need not only libstd ++, but libc and everything else that I need standard versions for.
For a regular library, just linking the specific version for libstdc ++ is enough, itโs not (or rather, I suspect that -stdlib will override the subsequent full names that I provide).
Prerequisites: I have executables that require a later version of libstdc++ than is installed on the system. Unfortunately, the installed version may be the same major version, and if so ld would be happy to use the system version, since it corresponds to the libstdc++.so.6
I prefer not to statically link, as I actually want to install many small programs that share the same C ++ runtime, and this will greatly inflate the installation.
Some information about my library search path is available here:
ld --verbose | grep SEARCH_DIR SEARCH_DIR ("/ usr / x86_64-redhat-linux / lib64"); SEARCH_DIR ("/ USR / lib64"); SEARCH_DIR ("/ USR / local / lib64"); SEARCH_DIR ("/ lib64"); SEARCH_DIR ("/ USR / x86_64-RedHat-Linux / Library"); SEARCH_DIR ("/ USR / local / library"); SEARCH_DIR ("/ Lib"); SEARCH_DIR ("/ USR / Lib");
In my case, it is clear that / usr / lib64 searches before the RPATH executable, which:
>objdump -x /opt/foo/bin/bar | grep PATH RPATH $ORIGIN/../lib64/private:$ORIGIN/../lib64:$ORIGIN/
man ld.so suggests a search order:
If the library dependency does not contain a slash, it is executed in the following order:
o (ELF only) Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is deprecated. o Using the environment variable LD_LIBRARY_PATH. Except if the executable is a set-user-ID/set-group-ID binary, in which case it is ignored. o (ELF only) Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present. o From the cache file /etc/ld.so.cache, which contains a compiled list of candidate libraries previously found in the augmented library path. If, however, the binary was linked with the -z nodeโ flib linker option, libraries in the default library paths are skipped. Libraries installed in hardware capability directories (see below) are preferred to other libraries. o In the default path /lib, and then /usr/lib. If the binary was linked with the -z nodeflib linker option, this step is skipped.
Similar to https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf
Both seem to be surpassed by actual use, but in reality it is not. look for symbolic links:
>LD_LIBRARY_PATH= LD_DEBUG=libs ldd /opt/foo/bin/bar 21720: find library=libstdc++.so.6 [0]; searching 21720: search path=/opt/foo/bin/../lib64/private:/opt/foo/bin/../lib64:/opt/foo/bin (RPATH from file /opt/foo/bin/bar) 21720: trying file=/opt/foo/bin/../lib64/private/libstdc++.so.6
This is an interaction with another question that I installed a shared imported library with the necessary links, where it was stated that the links are not required. They are clearly necessary if you did not specify the full semantic version.