在没有 LD_RUN_PATH 的情况下强制共享库的绝对路径

Force absolute path for shared library without LD_RUN_PATH

我正在尝试 link 使用我的二进制文件 ./bar 本地安装的共​​享库 (./vendor/lib/libfoo.so)。不幸的是,我的 none 次尝试生成了 link,其中包含 libfoo.so 的绝对路径。因此我需要使用

LD_LIBRARY_PATH=vendor/lib ./bar

到运行它,我想避免。 ldd bar 给我看这个:

    linux-vdso.so.1 =>  (0x00007ffed5fd8000)
    libbar.so.2 => not found
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb9ea787000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb9ea47d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb9ea267000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb9e9e9d000)
    /lib64/ld-linux-x86-64.so.2 (0x000055f326761000)

关于 libbar.so.2 的一句话:文件与 libbar.so 一起存在(在 vendor/lib 中)。两者实际上是 symlink 到 libhts.so.1.6。该文件也存在,并且是实际的共享库。

以下是我尝试过的不同方法:

FULL_PATH="$(pwd -P)/vendor/lib"

g++ -o bar bar.o -Lvendor/lib -lfoo        # 1
g++ -o bar bar.o -L$FULL_PATH -lfoo        # 2
g++ -o bar bar.o $FULL_PATH/libfoo.so      # 3
g++ -o bar bar.o $FULL_PATH/libfoo.so.1.6  # 4

所有这些变体产生相同的ldd输出,甚至最后一行ld坚持使用最高版本的库?)。

我发现完成这项工作的唯一方法是使用

LD_RUN_PATH=$FULL_PATH g++ -o bar bar.o -Lvendor/lib -lfoo

(我不能使用 -rpath 因为我的 g++ 版本不理解这个论点,我使用 g++ 而不是 ld 来获得正确的 libstdc++ 依赖关系——我当然可以使用 -Wl,-rpath。)

但我不禁觉得应该有一种方法可以在不使用环境变量的情况下完成这项工作/-rpath。我找到了 an answer specifically referencing symlinks to libraries 但不幸的是它对我没有帮助(见上面的尝试 4)。

这是在 Ubuntu 16.04、g++ 5.4.0、GNU ld 2.26.1 上,以防万一。

这听起来可能是您在安装后没有更新 ldconfig 缓存 您在非标准位置的共享库 /what/ever/vendor/lib:-

sudo ldconfig /what/ever/vendor/lib

在你这样做之前,运行时链接器将不知道 libfoo.so 是 在/what/ever/vendor/lib中,即使是,除非你在运行时提示它通过 LD_LIBRARY_PATH 环境变量。

顺便说一下,这并不是您 g++ 版本的缺点 不认识 -rpath。这只是一个链接器 (ld) 选项, 从来没有 GCC 前端选项。所以 -Wl,-rpath=/what/ever/vendor/lib 是 将非标准运行时库路径添加到您的 程序以避免依赖 ldconfig 缓存或 LD_LIBRARY_PATH

对于不寻常的链接,最好使用 -rpath 而不是扩展 ldconfig 缓存,它具有较少的歧视效果。