5.8 KiB
5.8 KiB
库路径配置说明
问题背景
在运行 ./build_deb.sh 或 ./make_deb.sh 时,如果遇到找不到某些库的错误,通常是因为这些库安装在非标准路径,例如:
/usr/local/lib/usr/local/lib64
这些路径默认不在 linuxdeployqt 的搜索路径中。
已实施的解决方案
打包脚本已经更新,自动包含这些路径:
1. 打包时的库路径
在两个打包脚本中,linuxdeployqt 运行时会使用以下 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:${QT_DIR}/lib:$LD_LIBRARY_PATH"
这确保 linuxdeployqt 能找到并打包:
/usr/local/lib和/usr/local/lib64中的自定义库- Qt 5.15.2 的库
- 系统标准库
2. 运行时的库路径
生成的启动脚本(screenlockdemo.sh 或 ScreenLockDemo.sh)也包含这些路径:
export LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:${APP_DIR}/lib:$LD_LIBRARY_PATH"
这确保打包后的程序在目标系统上运行时能找到:
- 系统中
/usr/local/lib和/usr/local/lib64的库(如果存在) - 打包在 DEB 中的库(
${APP_DIR}/lib) - 系统标准库
库搜索顺序
程序运行时的库搜索顺序:
/usr/local/lib- 用户自定义安装的库/usr/local/lib64- 64位用户自定义库${APP_DIR}/lib- DEB 包自带的库(Qt 和依赖)$LD_LIBRARY_PATH- 原有的库路径- 系统默认路径(
/lib,/usr/lib等)
验证库依赖
打包前验证
检查程序当前依赖的库:
ldd build/bin/ScreenLockDemo
输出示例:
libQt5Widgets.so.5 => /home/user/sdk/qt-5.15.2/lib/libQt5Widgets.so.5
libQt5Gui.so.5 => /home/user/sdk/qt-5.15.2/lib/libQt5Gui.so.5
libQt5Core.so.5 => /home/user/sdk/qt-5.15.2/lib/libQt5Core.so.5
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
...
打包后验证
安装 DEB 包后,检查打包程序的依赖:
ldd /opt/screenlockdemo/bin/ScreenLockDemo
应该看到大部分库指向 /opt/screenlockdemo/lib/:
libQt5Widgets.so.5 => /opt/screenlockdemo/lib/libQt5Widgets.so.5
libQt5Gui.so.5 => /opt/screenlockdemo/lib/libQt5Gui.so.5
...
常见问题
Q1: 为什么需要 /usr/local/lib?
A: 许多第三方库或手动编译安装的库会默认安装到 /usr/local/lib。如果程序依赖这些库,linuxdeployqt 需要能找到它们才能打包。
Q2: 如果库在其他路径怎么办?
A: 编辑打包脚本,在 LD_LIBRARY_PATH 中添加您的自定义路径:
# 在 build_deb.sh 或 make_deb.sh 中找到这行:
export LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:${QT_DIR}/lib:$LD_LIBRARY_PATH"
# 修改为:
export LD_LIBRARY_PATH="/your/custom/path:/usr/local/lib:/usr/local/lib64:${QT_DIR}/lib:$LD_LIBRARY_PATH"
同时也要更新启动脚本部分。
Q3: 打包的库太多,如何排除某些库?
A: 使用 linuxdeployqt 的 -exclude-libs 参数:
"$LINUXDEPLOYQT" "${APPDIR}/usr/bin/$APP_NAME" \
-verbose=2 \
-bundle-non-qt-libs \
-no-translations \
-exclude-libs="libsystemd,libdbus-1" \
-qmake="${QT_DIR}/bin/qmake"
Q4: 如何确认特定库被打包了?
A: 打包后检查:
# 列出所有打包的库
ls -la deb_package/AppDir/usr/lib/
# 或在 DEB 包中查找
dpkg -c deb_package/screenlockdemo_1.0.0_amd64.deb | grep "\.so"
Q5: 目标系统缺少某些库怎么办?
A: 有两个选择:
- 打包该库(推荐):确保 linuxdeployqt 能找到并打包它
- 在 debian/control 中添加依赖:
Depends: dbus, libx11-6, your-required-lib
调试技巧
1. 查看 linuxdeployqt 详细输出
# 在脚本中已经使用了 -verbose=2
# 运行时会显示所有找到和复制的库
./build_deb.sh 2>&1 | tee packaging.log
2. 检查缺失的库
如果程序无法启动,检查缺失的库:
# 运行程序并查看错误
/opt/screenlockdemo/bin/ScreenLockDemo
# 使用 ldd 查看未找到的库
ldd /opt/screenlockdemo/bin/ScreenLockDemo | grep "not found"
3. 手动添加缺失的库
如果某个库没有被自动打包:
# 找到库的位置
find /usr /lib -name "libmissing.so*" 2>/dev/null
# 手动复制到打包目录(在打包脚本的第5步后添加)
cp /usr/local/lib/libmissing.so.1 "${DEB_DIR}/opt/${PACKAGE_NAME}/lib/"
最佳实践
- 编译时使用相对路径:使用
-rpath编译选项 - 尽量打包所有依赖:避免依赖目标系统的特定版本
- 最小化系统依赖:只依赖稳定的系统库(libc, libm 等)
- 测试多个系统:在干净的系统上测试安装
- 文档化特殊依赖:在 README 中说明特殊要求
参考配置
当前配置已经包含:
# 打包时
LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH"
# 运行时
LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:/opt/screenlockdemo/lib:$LD_LIBRARY_PATH"
这应该能处理大多数情况。如有特殊需求,请根据上述指南调整。
相关命令参考
# 查看系统库路径配置
ldconfig -v 2>/dev/null | grep -v ^$'\t'
# 查看程序使用的库搜索路径
LD_DEBUG=libs /opt/screenlockdemo/bin/ScreenLockDemo 2>&1 | less
# 手动设置库路径运行程序
LD_LIBRARY_PATH=/custom/path:/opt/screenlockdemo/lib /opt/screenlockdemo/bin/ScreenLockDemo
# 检查 ELF 文件的 RPATH/RUNPATH
readelf -d /opt/screenlockdemo/bin/ScreenLockDemo | grep -i path
更新历史
- 2025-01-01: 初始版本,添加 /usr/local/lib 和 /usr/local/lib64 支持
如有问题或需要进一步的库路径配置,请参考此文档或咨询系统管理员。