使用RPATH而不是RUNPATH?

时间:2011-11-01 14:18:11

标签: c linux gcc shared-libraries dynamic-linking

此页面 - http://labs.qt.nokia.com/2011/10/28/rpath-and-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

然后建议:

  

当您发送二进制文件时,请使用RPATH而不是RUNPATH或确保   LD_LIBRARY_PATH在运行之前设置。

因此,将RPATHRUNPATH一起使用是不好的,因为RUNPATH种取消RPATH所以间接动态加载不能按预期工作?但是为什么RPATH被弃用而不赞成RUNPATH

有人可以解释一下情况吗?

3 个答案:

答案 0 :(得分:20)

当您发布二进制文件时,最好为用户提供方法,使二进制文件适应他们自己系统的细节,以及调整库搜索路径等。

用户通常可以调整LD_LIBRARY_PATH/etc/ld.so.conf,两者的优先级都低于DT_RPATH,即您无法覆盖二进制文件中的硬编码,而如果您使用DT_RUNPATH代替,用户可以使用LD_LIBRARY_PATH覆盖它。

(FWIW,我认为ld.so.conf也应优先于DT_RUNPATH,但无论如何,至少我们有LD_LIBRARY_PATH

另外,我强烈不同意上述使用DT_RPATH的建议。 IMO,最好在发送的二进制文件中使用较为DT_RPATH而不是DT_RUNPATH

除非

您将所有依赖库与可执行文件一起发送,并希望确保安装后的事情JustWork(tm),在这种情况下使用DT_RPATH

答案 1 :(得分:15)

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

动态图书馆搜索订单:

  1. ELF二进制文件中的DT_RPATH,除非设置了DT_RUNPATH。
  2. LD_LIBRARY_PATH条目,除非是setuid / setgid
  3. ELF二进制文件中的DT_RUNPATH
  4. /etc/ld.so.cache条目,除非在链接时给出-z nodeflib
  5. / lib,/ usr / lib,除非-z nodeflib
  6. 完成,“未找到”。

答案 2 :(得分:6)

  

但为什么然后RPATH被弃用而不支持RUNPATH?

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

更多细节可以在 Ulrich Drepper 撰写的"How to write shared libraries"作品中找到。