Linux 如何使用GCC/LD设置RPATH和运行路径?
我最近在升级系统后遇到了这个问题:使用GCCLinux 如何使用GCC/LD设置RPATH和运行路径?,linux,gcc,shared-libraries,ld,dynamic-linking,Linux,Gcc,Shared Libraries,Ld,Dynamic Linking,我最近在升级系统后遇到了这个问题:使用GCC-Wl,-rpath=选项的工作方式与以前不同 我用它来设置一些共享库的搜索路径,这些库是在我的项目的子模块中构建的。当时我认为它比在系统范围内设置LD\u LIBRARY\u PATH要好(我不想每次打开电脑时都设置它)。一切都很顺利,这两种方法似乎是等价的 现在可以看出,-rpath的行为已经改变。它仍然适用于直接依赖的库,但不适用于那些通过-rpath=链接同一目录集中的其他库的库。导出LD\u LIBRARY\u路径仍像以前一样工作 我使用re
-Wl,-rpath=
选项的工作方式与以前不同
我用它来设置一些共享库的搜索路径,这些库是在我的项目的子模块中构建的。当时我认为它比在系统范围内设置LD\u LIBRARY\u PATH
要好(我不想每次打开电脑时都设置它)。一切都很顺利,这两种方法似乎是等价的
现在可以看出,-rpath
的行为已经改变。它仍然适用于直接依赖的库,但不适用于那些通过-rpath=
链接同一目录集中的其他库的库。导出LD\u LIBRARY\u路径
仍像以前一样工作
我使用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(或者它至少服务于一个不同的用途,因为它具有较低的优先级),但它没有回答为什么会影响间接链接。库本身在readelf
输出中既没有RPATH,也没有RUNPATH
因此,我的问题是:为什么链接器突然开始以不同的方式解释-rpath=
选项,有没有办法强制执行旧的行为?(或者做一些不同的事情来产生相同的结果。)
另一个问题是:是否可以告诉旧版本的链接器生成新的输出(即运行路径而不是RPATH)?
编辑 这不是重复的——我的问题正好相反:我想要RPATH的行为。我找到了答案(感谢评论中的提示),我将在这里回答我的问题 有没有办法强迫旧的行为 对。您可以使用此选项
-Wl,--disable new dtags
告知新链接器使用旧行为,即RPATH
是否可以告诉旧版本的链接器生成新的输出(即运行路径而不是RPATH)
对。使用-Wl,--enable new dtag
告诉旧链接器使用新行为,即运行路径
我用readelf
验证了可执行文件,这两个选项似乎可以控制在ELF动态部分中编写的内容。我认为这个问题是由于新版本的默认设置发生了变化,尽管有趣的是,ld
的手册页面会建议它仍然应该是相同的:
--启用新的dtags--禁用新的dtags
此链接器可以在ELF中创建新的动态标记。但较老的ELF系统可能无法理解它们。如果您指定 --启用新的dtags,将根据需要创建新的动态标记,并 旧的动态标记将被忽略。如果指定--disable new dtag,则不会创建新的动态标记默认情况下,不会创建新的动态标记。请注意,这些选项是 仅适用于ELF系统 GNU Binutils项目(包含GNU链接器(ld))不是这种行为变化的根源,而是Debian(2016)和Gentoo(2013!) 根据2013年1月Mike Frysinger的gentoo承诺: “新”dtags选项已经存在14年多了,因此 Linux和GNU目标,默认情况下启用它们。” 由于运行路径和RPATH具有“未记录的行为差异”,因此未很好地接受此更改。。。 令人惊讶的是,这一变化现在应用于Debian stable 问题是使用运行路径会导致不可预知的问题。。。 但主要是起作用。来自维基百科: ld动态链接器不会在DT_运行路径位置搜索 可传递依赖项,与DT_RPATH不同 可能的重复等。我相信新的做事方式是
-Wl,-rpath,
和-Wl,--启用新的dtags
。它允许您使用LD_LIBRARY_PATH
覆盖嵌入的路径,这也是Coreutil人员推荐的二进制文件。