如何设置 DT_RPATH 或 DT_RUNPATH?

How do I set DT_RPATH or DT_RUNPATH?

在 Linux 上,ld.so(8) 手册页讨论了动态库的搜索顺序。它说 DT_RPATH 已弃用,还提到 DT_RUNPATH。没有提到 -rpath 链接器选项。

ld(1) 手册页提到了 -rpath-rpath-link 选项,但除了描述库搜索顺序之外从未提到 DT_RPATHDT_RUNPATH , 这当然与 ld.so(8).

中给出的信息不匹配

终于有一个LD_RUN_PATH环境变量了。 ld(1) 说它在 -rpath-rpath-link 选项没有设置时使用,但 ld.so(8) 没有提到它。

我的直觉是 -rpath 实际上设置 DT_RPATH,而 -rpath-link 设置 DT_RUNPATH,但我无法在任何地方找到这一点。我一直用-rpath;如果它与 DT_RPATH 相同,那么我不应该使用它,但是我在动态链接上找到的操作方法文章说要使用它,所以我不确定它是否相同。

谁能解释一下 DT_RPATHDT_RUNPATH 是如何设置的,它们是否与 -rpath-rpath-link 相同?

当你编译一个程序时,你创建目标文件然后link它们在一起。你可以使用 GNU ld(1) 来 link 它们,还有其他 linker,LLVM linker。 linker 将目标文件组合成可执行文件。 GNU ld(1) 是带有 documentation available here.

的 binutils 的一部分

当你执行一个已经编译好的可执行文件时,动态linker ld.so(8)会在系统上找到库可执行文件依赖、加载它们并执行可执行文件。 ld.so(8) 是一个共享库,通常作为 C 标准库的一部分分发,通常在 linux 上,即 glibc,但也有其他的,如 musl。

我认为这两个程序都被命名为“linker”令人困惑。一种是“编译linker”,另一种是“可执行linker”。

How do I set DT_RPATH or DT_RUNPATH?

编辑 elf 文件以包含特定部分。

当使用 GNU ld 创建 elf 文件时,现在您使用 -rpath=something 设置 RUNPATH 部分。您可以使用 --disable-new-dtags -rpath=something 设置 RPATH 部分。 RPATH 已弃用,因此通常 -rpath 设置 RUNPATH。 https://www.javaer101.com/en/article/1127068.html *这不会在我的系统上检出,我必须使用 gcc -Wl,--enable-new-dtags -Wl,-rpath=/tmp 进行编译以设置 RUNPATH...

您还可以在编译后的任何 ELF 文件中设置部分。参见 Can I change 'rpath' in an already compiled binary?

whether they are the same as -rpath and -rpath-link?

来自 ld documentation:

The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time.

并且文档还解释了 -rpath-link 的工作原理。指定搜索依赖共享库的目录。

Finally there is an LD_RUN_PATH environment variable

编译 一个可执行文件时,GNU ld(1) 也会在此变量指定的目录中搜索库。

用于在 .dynamic 部分创建 DT_RPATH 条目的 -rpath 命令行选项,但由于 DT_RPATH 已弃用,取而代之的是 DT_RUNPATH ,现代链接器版本使用 DT_RUNPATH 代替。这意味着在一个非常旧的链接器上使用 -rpath,您将创建一个带有 .d_val = DT_RPATH 的动态节条目,但如果您的链接器是最新的,您将创建一个带有 .d_val = DT_RUNPATH 的条目。

-rpath-link 选项 创建任何条目,但用于取代 DT_RUNPATH 动态部分中的条目正在链接的库。因此,在编译时,通常不需要它。您可以在 man 1 ld (scroll down to -rpath-link=) or in this other answer.

上找到更多信息