我最近在系统升级后遇到了这个问题:使用GCC primeicons 1.0.0-beta.10
选项的工作方式与以前不同。
我用它来设置一些在我的项目子模块中构建的共享库的搜索路径。当时,我认为它比在系统范围内设置-Wl,-rpath=
更好(我不想每次打开计算机时都进行设置)。一切正常,这两种方法似乎是等效的。
现在可以看出LD_LIBRARY_PATH
的行为已更改。它仍然适用于直接依赖的库,但不适用于通过-rpath
链接同一目录中的其他库的库。仍然可以像以前一样导出-rpath=
。
我使用LD_LIBRARY_PATH
检查了编译的输出,但有所不同。在升级之前(带有GCC 5.4的Linux Mint 18.2),动态部分具有以下内容:
readelf
升级后(带有GCC 7.3的Linux Mint 19),该行更改为:
0x000000000000000f (RPATH) Library rpath: [submod/lib]
在 use RPATH but not RUNPATH?中,建议将RPATH替换为RUNPATH(或者说,它至少具有不同的用途,因为它的优先级较低),但没有给出答案说明为什么会间接影响RPATH链接。库本身在0x000000000000001d (RUNPATH) Library runpath: [submod/lib]
输出中没有RPATH或RUNPATH。
所以我的问题是:为什么链接器突然开始以不同的方式解释readelf
选项,并且有一种方法可以强制执行旧的行为?(或采取其他不同的措施将产生等效的结果。)
另一个问题是:是否可以告诉链接器的旧版本产生新的输出(即RUNPATH而不是RPATH)?
编辑
这不是How to set RunPath of a binary?的副本-我的问题是相反的:我想要RPATH的行为。我知道了(感谢评论中的技巧),我将在这里回答我的问题。
答案 0 :(得分:4)
有没有办法强制旧行为?
是的。您可以使用此选项-Wl,--disable-new-dtags
来告诉 new 链接程序使用 old 行为,即RPATH。
是否可以告诉链接器的旧版本产生新的输出(即RUNPATH而不是RPATH)?
是的。使用-Wl,--enable-new-dtags
告诉 old 链接程序使用 new 行为,即RUNPATH。
我用readelf
验证了可执行文件,这两个选项似乎可以控制ELF动态部分中的内容。我认为问题是由新版本默认值的更改引起的,尽管有趣的是,ld
的手册页建议它应该仍然相同:
-enable-new-dtags
--disable-new-dtags
该链接器可以在ELF中创建新的动态标签。但是较旧的ELF系统可能无法理解它们。如果指定 --enable-new-dtags,将根据需要创建新的动态标签,并 较旧的动态代码将被省略。如果指定--disable-new-dtags,则不会创建新的动态标签。 默认情况下,不会创建新的动态代码。请注意,这些选项是 仅适用于ELF系统。
答案 1 :(得分:1)
项目GNU Binutils(包含GNU链接器(ld))并不是这种行为改变的源头,而是Debian(2016)1和Gentoo(2013!)2。 / p>
根据Mike Frysinger于2013年1月提交的gentoo承诺:
“新” dtags选项已经存在了14年以上,因此 Linux和GNU目标,默认情况下启用它们。”
3,4,5并没有很好地接受此更改,因为RUNPATH和RPATH具有“未记录的行为差异” ... 令人惊讶的是,此更改现已应用于Debian稳定版。
问题是使用RUNPATH会导致无法预料的问题... 但主要只是可行。来自维基百科:
ld动态链接器不会在DT_RUNPATH位置中搜索以下内容 传递性依赖项,与DT_RPATH不同。