我有一个使用一些共享对象的可执行文件
这些共享对象有其他共享对象作为依赖项,我想将主可执行文件的rpath
设置为包括这些依赖项的目录,因为runpath
不用于间接依赖项。
我正在尝试将rpath
烘焙到我的ELF中,但是当使用以下内容时:gcc -std=c++20 -o main main.cpp -lstdc++ -L./lib -Wl,-rpath,./lib
结果是./lib
在ELF中被设置为RUNPATH
而不是RPATH
:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath: [./lib]
0x000000000000000c (INIT) 0x1000
...
有人能解释为什么会发生这种情况吗?我希望在RPATH
部分中定义./lib
,而不是RUNPATH
。似乎RPATH
部分根本不存在。
我使用的是gcc
版本11.1.0
,ld
版本2.34
。
我知道这可能不是管理间接依赖关系的最佳解决方案,我很乐意听到更好的解决方案,但我仍然想知道为什么-Wl,-rpath,./lib
会导致ELF中定义的RUNPATH
,而不是RPATH
。
要获得DT_RUNPATH条目,您需要--enable-new-dtags
。
要获得DT_RPATH条目(已弃用(,您需要--disable-new-dtags
。
在你的情况下,类似这样的东西:
gcc -std=c++20 -o main main.cpp -lstdc++ -L./lib -Wl,--disable-new-dtags,-rpath,./lib
我建议在rpath中使用绝对路径,我不确定从哪个目录中解释相对路径。如果您想使用可执行文件作为参考点,还有$ORIGIN
。
请参阅https://man7.org/linux/man-pages/man1/ld.1.html和https://man7.org/linux/man-pages/man8/ld.so.8.html了解更多信息。