ld 跳过共享库

ld skips shared library

我正在尝试通过提供 Qt 库作为目录中的共享库并使用 LD_LIBRARY_PATH 将 ld 指向它们来部署 Qt 应用程序。这适用于所有 Qt 库,例如 libQt5Network 或 libQt5Gui,但不适用于 libQt5Core,它不知何故找不到,而是使用系统版本。

使用 LD_DEBUG=all 我可以看到 ld 尝试了存在的文件,但跳过了它

  3705: file=libQt5Core.so.5 [0];  needed by ./app.bin [0]
  3705: find library=libQt5Core.so.5 [0]; searching
  3705:  search path=/home/user/app/lib:/usr/lib64/tls/x86_64/x86_64:/usr/lib64/tls/x86_64:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/x86_64/x86_64:/usr/lib64/x86_64:/usr/lib64/x86_64:/usr/lib64     (LD_LIBRARY_PATH)
  3705:   trying file=/home/user/app/lib/libQt5Core.so.5 <- this file exists
  3705:   trying file=/usr/lib64/tls/x86_64/x86_64/libQt5Core.so.5
  3705:   trying file=/usr/lib64/tls/x86_64/libQt5Core.so.5
  3705:   trying file=/usr/lib64/tls/x86_64/libQt5Core.so.5
  3705:   trying file=/usr/lib64/tls/libQt5Core.so.5
  3705:   trying file=/usr/lib64/x86_64/x86_64/libQt5Core.so.5
  3705:   trying file=/usr/lib64/x86_64/libQt5Core.so.5
  3705:   trying file=/usr/lib64/x86_64/libQt5Core.so.5
  3705:   trying file=/usr/lib64/libQt5Core.so.5

libQt5Core.so.5 和 app.bin 都是 64 位精灵。

有什么方法可以找出 ld 拒绝文件的原因吗?

解决方案在这里:https://github.com/Microsoft/WSL/issues/3023

该库包含一个 ABI 注释,可以使用 strip 将其删除以使 ld 接受该库。

是正确的。以防万一 link 坏了,下面是我的情况以及我是如何修复它的。

我在安装了 Qt5 的系统上 运行 安装了一个较旧的内核,版本 3.10。其中一个库,即 libQt5Core.so.5.11.0,有一个 ELF 部分 .note.ABI-tag,它指定该库是为内核 3.17.0 编译的。可以通过例如

查看此部分的存在
objdump -sj .note.ABI-tag /path/to/library.so

并且 file 揭示了它是为较新内核编译的事实,在其输出接近尾声时很难注意到 "for GNU/Linux 3.17.0"。在我的例子中是:

/opt/qt511/lib/libQt5Core.so.5.11.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.17.0, BuildID[sha1]=df5f7e933899d1ff629145ab7ca35b2f9bc41843, stripped

所以我的解决办法是 运行

strip --remove-section=.note.ABI-tag /path/to/library.so

删除了此部分并允许加载库。

但请注意,如果您这样做,您将明确打破库构建系统可能使用的假设,因此事情可能会失败。不过,就我而言,他们没有。