使用RPATH而不是RUNPATH



这个页面是关于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。

所以,使用RPATHRUNPATH是不好的,因为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_RPATHDT_RUNPATH的二进制文件。

除非

您将所有依赖库与可执行文件一起发布,并希望确保安装后的东西可以正常工作(tm),在本例中使用DT_RPATH

Chill的答案完全正确;我想简单地添加一些颜色,来自最近阅读的glibc源([master 8b0ccb2],在2.17中)。要明确的是,如果在给定级别指定的位置中找不到库,则尝试下一个级别。如果在给定级别找到一个库,则停止搜索。

Dynamic Library Search Order:

  1. DT_RPATH在ELF二进制文件中,除非DT_RUNPATH设置。
  2. LD_LIBRARY_PATH条目,除非setuid/setgid
  3. DT_RUNPATH
  4. /etc/ld.so。缓存项,除非在链接时给出-z nodeflib
  5. /lib,/usr/lib除非-z nodeflib
  6. 已完成,"not found".

但是为什么RPATH被弃用而支持RUNPATH呢?

当引入DT_RPATH时,它优先于所有其他参数。这使得即使出于开发目的也无法覆盖库搜索路径。因此,引入了另一个参数LD_RUNPATH,它的优先级低于LD_LIBRARY_PATH。

更多细节可以在"如何编写共享库"中找到。Ulrich Drepper的作品

最新更新