微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何设置 DT_RPATH 或 DT_RUNPATH?

如何解决如何设置 DT_RPATH 或 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 相同吗?

解决方法

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

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

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

如何设置 DT_RPATH 或 DT_RUNPATH?

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

当用 GNU ld 创建 elf 文件时,现在你用 -rpath=something 设置 RUNPATH 部分。您可以使用 RPATH 设置 --disable-new-dtags -rpath=something 部分。 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?

它们是否与 -rpath 和 -rpath-link 相同?

来自ld documentation

-rpath 和 -rpath-link 的区别在于 -rpath 选项指定的目录包含在可执行文件中并在运行时使用,而 -rpath-link 选项仅在链接时有效。

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

终于有一个LD_RUN_PATH环境变量

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

,

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

-rpath-link 选项是一个选项,它创建任何条目,但用于取代当前正在创建的库的动态部分中存在的 DT_RUNPATH 条目。链接。因此,在编译时,您通常应该不需要它。您可以在 man 1 ld(向下滚动到 -rpath-link=)或 this other answer 中找到更多信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。