为什么安装二进制文件后需要设置 LD_LIBRARY_PATH?

juz*_*lin 4 linux linker shared-libraries ld

我的应用程序链接到一个自编译的 Qt,该 Qt 位于/usr/local/lib.

当我在构建目录中启动应用程序时,这工作正常。但是,在我安装应用程序后,/usr/local/bin/它尝试加载没有所需符号的不兼容系统 Qt 库并失败。

为什么?我的二进制文件的实际位置如何影响正在解析的 Qt?

如果我启动我的应用程序,LD_LIBRARY_PATH=/usr/local/lib它就会按预期工作。

jww*_*jww 5

为什么安装二进制文件后需要设置 LD_LIBRARY_PATH?

简单的答案是,这是系统架构师和工具链的失败。在 Linux 上,他们是维护 Binutils 和 glibc 的人。维护者集体认为,可以针对一个版本的库进行编译和链接,然后针对错误版本的库进行运行时链接,或者丢失该库。他们已经确定这是第一大用例(qv)。事情并不是开箱即用的,你必须做一些特别的事情才能进入良好的状态。

考虑一下,我有一些构建脚本,可以构建和安装大约 70 个常见的 Linux 实用程序和库,例如 cURL、Git、SSH 和 Wget。这些脚本构建程序及其所有依赖项。有时我尝试使用它们进行安全测试和评估,例如Asan和UBsan。这个想法是运行已检测的程序和库并/usr/local检测未定义的行为、内存错误等。然后,将错误报告给项目。

尝试在 Linux 系统上运行检测构建是不可能的。例如,一旦使用仪器构建了 Bzip、iConv、Unicode、IDN、PRCE 和其他几个关键库,系统就不再起作用。/usr/bin中的程序/usr/bin/bash将加载 中的检测库/usr/local/lib。程序和库有太多错误,导致程序不断被杀死。您无法再运行脚本,因为其中的程序/usr/bin使用了错误的库(并且类似的程序bash有很多错误)。

当然,也存在像您这样的问题,程序和库找不到自己的库。由于维护者的决定,网络上充满了屠杀。


要解决您正在构建的程序的问题,请将以下内容添加到您的LDFLAGS

-Wl,-R,/usr/local/lib -Wl,--enable-new-dtags
Run Code Online (Sandbox Code Playgroud)

-R,/usr/local/lib告诉运行时链接器查找/usr/local/lib其库。--enable-new-dtags告诉链接器使用RUNPATH而不是RPATH.

RUNPATH可以用 覆盖LD_LIBRARY_PATH,而 则RPATH不能。省略-Wl,--enable-new-dtags通常是一个坏主意。另请参阅使用 RPATH 但不使用 RUNPATH?

您还可以使用相对运行时路径:

-Wl,-R,'$$ORIGIN/../lib' -Wl,--enable-new-dtags
Run Code Online (Sandbox Code Playgroud)

-R,'$$ORIGIN/../lib'告诉运行时链接器查找../lib/其库。大概您的二进制文件位于 中.../bin/,因此../lib/位于该lib/目录中。

当您具有如下文件系统布局时,基于 ORIGIN 的链接器路径非常有用:

My_App
  |
  +-- bin
  |    |
  |    +- my_app.exe
  |
  +-- lib
  |    |
  |    +- my_lib.so
  |
  +-- share
Run Code Online (Sandbox Code Playgroud)

My_App您可以在文件系统中移动文件夹,并且my_app.exe始终能够找到其库my_lib.so。如果 是My_App根目录/,那么它是发行版使用的标准 Linux 文件系统(即--prefix=/)。如果My_App/usr/local,那么它是用户使用的标准 Linux 文件系统(即--prefix=/usr/local)。

如果您configuremakemake test,那么您可以用来LD_LIBRARY_PATH设置用于测试的库的临时路径(如.../My_App/lib)。事实上,写得好的make test应该在测试期间为您做到这一点。


您不必添加,-Wl,-R,/usr/local/lib -Wl,--enable-new-dtags因为程序是针对库进行编译和链接的/usr/local/lib(大概使用-L<path>-l<lib>)。你必须这样做的原因是因为维护人员一遍又一遍地犯同样的错误。这是一个彻底的工程失败。

大约 25 年前,当 Linux 架构师决定开箱即用时,他们就收到了有关这些路径问题的警告。有两个阵营:一个阵营希望事情开箱即用,另一个阵营希望用户做一些特别的事情来让事情发挥作用。后者赢得了辩论。他们选择了“让我们链接到错误的库”和“让我们失去库”模式。我希望我能找到讨论该问题的 Usenet 帖子,以便您可以自己阅读。


归档时间:

查看次数:

1424 次

最近记录:

6 年,6 月 前