这个页面是关于ld.so
图书馆搜索的顺序:
Unless loading object has RUNPATH: RPATH of the loading object, then the RPATH of its loader (unless it has a RUNPATH), ..., until the end of the chain, which is either the executable or an object loaded by dlopen Unless executable has RUNPATH: RPATH of the executable LD_LIBRARY_PATH RUNPATH of the loading object ld.so.cache default dirs
And then建议:
当您发布二进制文件时,使用RPATH而不是RUNPATH或ensure
执行前设置LD_LIBRARY_PATH。
所以,使用RPATH
和RUNPATH
是不好的,因为RUNPATH
在某种程度上抵消了RPATH
,所以间接动态加载不能像预期的那样工作?但是为什么RPATH
被弃用而支持RUNPATH
呢?
当您发布二进制文件时,最好为用户提供使二进制文件适应他们自己系统的具体情况的方法,其中包括调整库搜索路径。
用户通常可以调整LD_LIBRARY_PATH
和/etc/ld.so.conf
,它们的优先级都比DT_RPATH
低,也就是说,你不能覆盖二进制中硬编码的内容,而如果你使用DT_RUNPATH
,用户可以用LD_LIBRARY_PATH
覆盖它。
(顺便说一句,我认为ld.so.conf
也应该优先于DT_RUNPATH
,但是,无论如何,至少我们有LD_LIBRARY_PATH
)。
同样,我强烈反对上面使用DT_RPATH
的建议。IMO,最好不要使用DT_RPATH
和DT_RUNPATH
的二进制文件。
您将所有依赖库与可执行文件一起发布,并希望确保安装后的东西可以正常工作(tm),在本例中使用DT_RPATH
。
Chill的答案完全正确;我想简单地添加一些颜色,来自最近阅读的glibc源([master 8b0ccb2],在2.17中)。要明确的是,如果在给定级别指定的位置中找不到库,则尝试下一个级别。如果在给定级别找到一个库,则停止搜索。
Dynamic Library Search Order:
- DT_RPATH在ELF二进制文件中,除非DT_RUNPATH设置。
- LD_LIBRARY_PATH条目,除非setuid/setgid
- DT_RUNPATH
- /etc/ld.so。缓存项,除非在链接时给出-z nodeflib
- /lib,/usr/lib除非-z nodeflib
- 已完成,"not found".
但是为什么RPATH被弃用而支持RUNPATH呢?
当引入DT_RPATH时,它优先于所有其他参数。这使得即使出于开发目的也无法覆盖库搜索路径。因此,引入了另一个参数LD_RUNPATH,它的优先级低于LD_LIBRARY_PATH。
更多细节可以在"如何编写共享库"中找到。Ulrich Drepper的作品