Linux 使用 RPATH 而不是 RUNPATH?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7967848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 06:56:31  来源:igfitidea点击:

use RPATH but not RUNPATH?

clinuxgccshared-librariesdynamic-linking

提问by zaharpopov

This page - http://labs.qt.nokia.com/2011/10/28/rpath-and-runpath/- says about order for library search in ld.so:

此页面 - 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

And then suggest:

然后建议:

When you ship binaries, either use RPATH and not RUNPATH or ensure LD_LIBRARY_PATH is set before they are run.

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

So, using RPATHwith RUNPATHis bad because RUNPATHkind-of cancels RPATHso indirect dynamic loading doesn't work as expected? But why then RPATHgot deprecated in favor of RUNPATH?

那么,使用RPATHwithRUNPATH是不好的,因为RUNPATH有点取消RPATH所以间接动态加载不能按预期工作?但是为什么后来RPATH被弃用而支持RUNPATH

Can somebody explain the situation?

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

采纳答案by chill

When you ship a binary, it's good to provide means for the users to accommodate the binary to the specifics of their own system, among other things, adjusting library search paths.

当你发布一个二进制文件时,最好为用户提供方法来适应他们自己系统的具体情况,其中包括调整库搜索路径。

A user can generally tweak LD_LIBRARY_PATHand /etc/ld.so.conf, both of which are with lower precedence than DT_RPATH, i.e. you can't override what is hardcoded in the binary, whereas if you use DT_RUNPATHinstead, a user can override it with LD_LIBRARY_PATH.

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

(FWIW, I think ld.so.confshould also take precedence over DT_RUNPATH, but, anyway, at least we've got LD_LIBRARY_PATH).

(FWIW,我认为ld.so.conf也应该优先于DT_RUNPATH,但是,无论如何,至少我们已经有了LD_LIBRARY_PATH)。

Also, I strongly disagree with the suggestion above to use DT_RPATH. IMO, its best to use nether DT_RPATHnot DT_RUNPATHin shipped binaries.

另外,我强烈不同意上述使用DT_RPATH. IMO,最好DT_RPATH不要DT_RUNPATH在发布的二进制文件中使用下界。

unless

除非

you ship all your dependent libraries with your executables and wish to ensure that things JustWork(tm) after installation, in this case use DT_RPATH.

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

回答by FDS

Chill's answer is exactly right; I wanted to simply add some color, from a recent reading of the glibc source ([master 8b0ccb2], in 2.17). To be clear, if a library is not found in the location specified by a given level, the next level is tried. If a library is found at a given level, the search stops.

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

Dynamic Library Search Order:

动态库检索顺序:

  1. DT_RPATH in the ELF binary, unless DT_RUNPATH set.
  2. LD_LIBRARY_PATH entries, unless setuid/setgid
  3. DT_RUNPATH in ELF binary
  4. /etc/ld.so.cache entries, unless -z nodeflib given at link time
  5. /lib, /usr/lib unless -z nodeflib
  6. Done, "not found".
  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. 完成,“未找到”。

回答by MichaelGoren

But why then RPATH got deprecated in favor of RUNPATH?

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

When DT_RPATH was introduced, it had precedence over all other parameters. This made impossible to override the libraries search path even for development purposes. Therefore another parameter, LD_RUNPATH, was introduced that has lower precedence than LD_LIBRARY_PATH.

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

More details can be found in the "How to write shared libraries"work written by Ulrich Drepper.

更多细节可以在Ulrich Drepper编写“如何编写共享库”工作中找到。