通过编辑可执行文件修复二进制文件中的库位置

Fix library location inside a binary by editing the executable

我的目标是让二进制文件作为安装过程的一部分在不同的系统上工作,即使库不在链接器在我的原始系统上找到它们的位置。

例如:我有一个二进制文件 'program',它链接到几个共享库 'library1.so'、'library2.so' 和 'library3.so'。

使用 ldd 我可以看到 libary3.so 即使在 /usr/local/lib:

中也找不到
$ ldd program
        library1.so.1 => (0x00007fff26ffe000)
        library2.so.10 => /usr/local/lib/library2.so.10 (0x00007fa67087d000)
        library3.so => not found

奇怪的是,另一个库 'library2.so' 恰好位于 'library3.so' 所在的位置。

当然我可以使用LD_LIBRARY_PATH解决这个问题,但我想避免这种情况。

问题:我还有哪些其他选项可以修复丢失的库?


编辑 2:我有 found this suggestion

规范处理规则LD_LIBRARY_PATH

  1. 永远不要全局设置 LD_LIBRARY_PATH。
  2. 如果您必须运送使用共享库的二进制文件并希望允许您的客户在 'standard' 位置之外安装程序,请执行以下操作之一:

    • 将您的二进制文件作为 .o 文件发送,并作为安装过程的一部分将它们与正确的安装库路径重新链接。
    • 使用非常长的“虚拟”运行-time 库路径发送可执行文件,并在安装过程中使用二进制编辑器替换可执行文件中的正确安装库路径。
  3. 如果您被迫设置 LD_LIBRARY_PATH,请仅作为包装器的一部分进行设置。

子问题:如何使用二进制编辑器更改库路径?

我认为编辑二进制文件来改变路径不是个好主意。 尝试包含选项

-Wl,-Bstatic -lstdc++

链接过程中。在那种情况下,您将拥有将在不同系统上调用的静态链接二进制文件。

我找到了 patchELF,它满足了我的需要:

[...] Likewise, you can change the RPATH, the linker search path embedded into executables and dynamic libraries:

patchelf --set-rpath /opt/my-libs/lib:/foo/lib program    

This causes the dynamic linker to search in /opt/my-libs/lib and /foo/lib for the shared libraries needed by program. Of course, you could also set the environment variable LD_LIBRARY_PATH, but that’s often inconvenient as it requires a wrapper script to set up the environment.