116

我有一个为废料堆安排的旧可执行文件,但它还没有。它依赖于一些已从我的环境中删除的库,但我有一些存根库可以正常工作。我想将此可执行文件指向这些存根库。是的,我可以设置 LD_LIBRARY_PATH,但是这个可执行文件是从许多脚本和许多用户中调用的,我很想在一个地方修复它。

我没有这方面的来源,而且很难得到它。我在想 - 我可以编辑这个文件,使用一个 ELF 感知编辑器,并添加一个简单的 PATH 到 rpath 让它命中新的库吗?这是可能的吗,或者一旦你创建了一个 ELF 二进制文件,你将东西固定到位置并且它们不能移动?

4

4 回答 4

197

有一个比chrpath所谓的更通用的工具patchelf。它最初是为为 Nix 和 NixOS(打包系统和 GNU/Linux 发行版)制作包而创建的。

如果二进制文件(这里称为 rdsamp)中没有 rpath,则chrpath失败:

chrpath -r '$ORIGIN/../lib64' rdsamp 
rdsamp: no rpath or runpath tag found.

另一方面,

patchelf --set-rpath '$ORIGIN/../lib64' rdsamp

成功就好了。

于 2013-12-02T16:52:38.563 回答
86

有一个名为的工具chrpath可以做到这一点 - 它可能在您的发行版的软件包中可用。

于 2012-12-07T19:05:03.430 回答
33

就像@user7610 所说,正确的方法是patchelf工具。

但是,我觉得我可以给出一个更全面的答案,涵盖所有需要执行此操作的命令。

有关该主题的综合文章,请单击此处

首先,很多开发者都在谈论RPATH,但实际上他们的意思是RUNPATH。这是两个不同的可选动态部分,加载器处理它们的方式非常不同。您可以在我之前提到的链接中阅读有关它们之间区别的更多信息。

现在,请记住:

  • 如果RUNPATH已设置,RPATH则忽略
  • RPATH已弃用,应避免使用
  • RUNPATH是首选,因为它可以被覆盖LD_LIBRARY_PATH

查看当前的 R[UN]PATH

readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"

清除 R[UN]PATH

patchelf --remove-rpath <path-to-elf>

笔记:

  • 删除两者RPATHRUNPATH

将值添加到 R[UN]PATH

patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>

笔记:

  • <desired-path>是一个冒号分隔的目录列表,例如:/my/libs:/my/other/libs
  • 如果指定--force-rpath,则设置RPATH,否则设置RUNPATH
于 2019-02-16T13:18:13.707 回答
0

这对我有用,用 $ORIGIN 替换 XORIGIN。

chrpath -r '\$\ORIGIN/../lib64' httpd

于 2016-06-28T10:49:22.763 回答