使用RPATH而不是RUNPATH?

zah*_*pov 28 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
Run Code Online (Sandbox Code Playgroud)

然后建议:

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

因此,使用RPATHwith RUNPATH是不好的,因为RUNPATH取消了类似的RPATH间接动态加载不能按预期工作?但为什么然后RPATH被弃用RUNPATH呢?

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

chi*_*ill 25

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

用户通常可以调整,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,最好使用nether DT_RPATH而不是DT_RUNPATH运送二进制文件.

除非

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

  • 问题是,在 RPATH 上推荐使用 RUNPATH,不推荐使用 RPATH,但目前并非所有系统都支持 RUNPATH。那么我**今天**做什么才能使应用程序正常工作?正如 Qt 文章所示,在使用插件时,使用 RPATH 比使用 RUNPATH 更有用。所以这里的整个情况非常混乱 (2认同)
  • 这不简单。Qt 问题是应用程序需要比系统上现有版本更新的 Qt 库。有些系统已经过时了 Qt SO,那么你会怎么做?如果您需要特定版本,我认为与您一起分发 Qt SO 是有意义的 (2认同)

FDS*_*FDS 16

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

动态库搜索顺序:

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


小智 9

但是为什么然后RPATH被弃用以支持RUNPATH?

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

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

  • 这个答案解释了对`DT_RUNPATH`的需求,但不是为什么不推荐使用`DT_RPATH`.两者都有自己的用法,当使用`LD_LIBRARY_PATH`时,`DT_RUNPATH`打破`libtool`:https://bugs.debian.org/cgi-bin/bugreport.cgi?video = 859732 (2认同)
  • @vinc17这不是我想要一些东西可以被重写,而是Linux开发人员(那些开发Linux本身的人!)不希望存在一些不可重写的东西,而RT_PATH是不可重写的,因此它必须停止存在。如果你不明白,那么我无法帮助你。我很确定这里的其他读者都明白我在说什么。 (2认同)