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
删除了此部分并允许加载库。
但请注意,如果您这样做,您将明确打破库构建系统可能使用的假设,因此事情可能会失败。不过,就我而言,他们没有。
我正在尝试通过提供 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 接受该库。
我在安装了 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
删除了此部分并允许加载库。
但请注意,如果您这样做,您将明确打破库构建系统可能使用的假设,因此事情可能会失败。不过,就我而言,他们没有。