【发布时间】:2017-12-27 11:45:17
【问题描述】:
给定一个可执行文件:
>objdump -x someprog | grep c++
NEEDED libstdc++.so.6
我想将需求更改为完整版(包括次要版本和补丁级别):
>objdump -x someprog | grep c++
NEEDED libstdc++.so.6.0.22
我知道有两种方法可以做到这一点:
- 根据这个问题创建一个虚拟库 (Forcing or preventing use of a particular minor version of libstdc++)
- 使用补丁
(我还没有为 --replace-needed 找到一个可以工作的命令行)
这两个对我来说都像是黑客攻击。 有没有办法在编译或链接时使用适当的 -Wl 标志到 gcc 来实现相同的目标?
理想情况下,我希望避免使用 -nostdlib,因为这不仅需要我指定 libstd++,还需要指定 libc 以及我确实需要标准版本的所有其他内容。
对于一个常规库来说,仅仅链接到特定版本就足够了 libstdc++ 它不是(或者更确切地说,我怀疑 -stdlib 会覆盖我提供的后续完全限定名称)。
背景:我的可执行文件需要比系统上安装的更高版本的libstdc++。不幸的是,安装的版本可能是相同的主要版本,如果是这样,ld 将愉快地使用系统版本,因为它与 soname libstdc++.so.6
我不喜欢静态链接,因为我实际上想安装许多共享相同 C++ 运行时的小程序,这会使安装变得相当臃肿。
有关我的(该)库搜索路径的一些信息可在此处获得:
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/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
在我的情况下,很明显 /usr/lib64 在可执行文件的 RPATH 之前被搜索:
>objdump -x /opt/foo/bin/bar | grep PATH
RPATH $ORIGIN/../lib64/private:$ORIGIN/../lib64:$ORIGIN/
man ld.so 建议搜索顺序应该是:
如果库依赖项不包含斜杠,则搜索它 按以下顺序:
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.
同样https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf
两者似乎都被实际使用所压倒,但实际上并非如此。 需要的是寻找符号链接:
>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
这是我与install shared imported library with necessary links 的另一个问题的互动,其中建议不需要链接。 如果您没有指定完整的语义版本,那么它们显然是是必需的。
【问题讨论】:
-
前/后情况似乎没有区别,所以不清楚你想要什么。
-
这是我的错字(现已修复),我的意思是 6.0.22。不是这样。6
-
现在它又有意义了,希望可以删除反对票。