如何使用 GCC/LD 设置 RPATH 和 RUNPATH?
- 2024-11-08 09:04:00
- admin 原创
- 27
问题描述:
我最近在系统升级后遇到了这个问题:使用 GCC-Wl,-rpath=
选项的工作方式与以前不同。
我用它来设置一些共享库的搜索路径,这些库是在我的项目的子模块中构建的。当时我认为这比设置LD_LIBRARY_PATH
系统范围的更好(我不想每次打开电脑时都设置它)。一切都很顺利,这两种方法似乎是等效的。
现在看来 的行为-rpath
已经改变。它仍然适用于直接依赖的库,但不适用于通过 设置的同一目录链接其他库的库-rpath=
。导出LD_LIBRARY_PATH
仍然像以前一样有效。
我检查了编译的输出readelf
,发现有区别。升级之前(Linux Mint 18.2 和 GCC 5.4),动态部分有以下行:
0x000000000000000f (RPATH) Library rpath: [submod/lib]
升级后(Linux Mint 19 带有 GCC 7.3),该行更改为:
0x000000000000001d (RUNPATH) Library runpath: [submod/lib]
在使用 RPATH 但不使用 RUNPATH?时,有人建议用 RUNPATH 替换 RPATH(或者至少它用于不同的目的,因为它具有较低的优先级),但它没有回答为什么这会影响间接链接。库本身在readelf
输出中既没有 RPATH,也没有 RUNPATH。
所以我的问题是:为什么链接器突然开始以-rpath=
不同的方式解释该选项,并且有没有办法强制旧的行为?(或者做一些不同的事情来产生相同的结果。)
另一个问题是:是否可以告诉旧版本的链接器产生新的输出(即 RUNPATH 而不是 RPATH)?
编辑
这不是如何设置二进制文件的 RunPath的重复——我的问题恰恰相反:我想要 RPATH 的行为。我弄明白了(感谢评论中的提示),我将在这里回答我的问题。
解决方案 1:
有没有办法强制执行旧的行为?
是的。您可以使用此选项-Wl,--disable-new-dtags
告诉新链接器使用旧行为,即 RPATH。
是否可以告诉旧版本的链接器产生新的输出(即 RUNPATH 而不是 RPATH)?
是的。用来-Wl,--enable-new-dtags
告诉旧链接器使用新行为,即 RUNPATH。
我使用 验证了可执行文件readelf
,这两个选项似乎控制着在 ELF Dynamic 部分中写入的内容。我认为问题是由新版本的默认设置更改引起的,但有趣的是,手册页建议ld
它应该仍然相同:
--enable-new-dtags
--disable-new-dtags
此链接器可以在 ELF 中创建新的动态标签。但较旧的 ELF 系统可能无法理解它们。如果指定 --enable-new-dtags,则将根据需要创建新的动态标签,并忽略较旧的动态标签。如果指定 --disable-new-dtags,则不会创建新的动态标签。默认情况下,不会创建新的动态标签。请注意,这些选项仅适用于 ELF 系统。
解决方案 2:
GNU Binutils 项目(包含 GNU 链接器 (ld))不是这种行为改变的起源,而是 Debian(2016)1和 Gentoo(2013!)2。
根据 Mike Frysinger 于 2013 年 1 月对 gentoo 的提交:
“‘新’ dtags 选项已经存在 14 年多了,因此对于 Linux 和 GNU 目标,默认启用它们。”
这一变化并未受到广泛好评3、4、5 ,因为 RUNPATH 和 RPATH 存在“未记录的行为差异”……令人惊讶的是,这一变化现已应用于 Debian 稳定版。
问题是使用 RUNPATH 会导致不可预测的问题...但主要是能正常工作。来自维基百科:
与 DT_RPATH 不同,ld 动态链接器不会在 DT_RUNPATH 位置中搜索
传递依赖项。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件