# 库路径配置说明 ## 问题背景 在运行 `./build_deb.sh` 或 `./make_deb.sh` 时,如果遇到找不到某些库的错误,通常是因为这些库安装在非标准路径,例如: - `/usr/local/lib` - `/usr/local/lib64` 这些路径默认不在 linuxdeployqt 的搜索路径中。 ## 已实施的解决方案 打包脚本已经更新,自动包含这些路径: ### 1. 打包时的库路径 在两个打包脚本中,linuxdeployqt 运行时会使用以下 LD_LIBRARY_PATH: ```bash 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`)也包含这些路径: ```bash 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`) - 系统标准库 ## 库搜索顺序 程序运行时的库搜索顺序: 1. **`/usr/local/lib`** - 用户自定义安装的库 2. **`/usr/local/lib64`** - 64位用户自定义库 3. **`${APP_DIR}/lib`** - DEB 包自带的库(Qt 和依赖) 4. **`$LD_LIBRARY_PATH`** - 原有的库路径 5. 系统默认路径(`/lib`, `/usr/lib` 等) ## 验证库依赖 ### 打包前验证 检查程序当前依赖的库: ```bash 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 包后,检查打包程序的依赖: ```bash 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 中添加您的自定义路径: ```bash # 在 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` 参数: ```bash "$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:** 打包后检查: ```bash # 列出所有打包的库 ls -la deb_package/AppDir/usr/lib/ # 或在 DEB 包中查找 dpkg -c deb_package/screenlockdemo_1.0.0_amd64.deb | grep "\.so" ``` ### Q5: 目标系统缺少某些库怎么办? **A:** 有两个选择: 1. **打包该库**(推荐):确保 linuxdeployqt 能找到并打包它 2. **在 debian/control 中添加依赖**: ``` Depends: dbus, libx11-6, your-required-lib ``` ## 调试技巧 ### 1. 查看 linuxdeployqt 详细输出 ```bash # 在脚本中已经使用了 -verbose=2 # 运行时会显示所有找到和复制的库 ./build_deb.sh 2>&1 | tee packaging.log ``` ### 2. 检查缺失的库 如果程序无法启动,检查缺失的库: ```bash # 运行程序并查看错误 /opt/screenlockdemo/bin/ScreenLockDemo # 使用 ldd 查看未找到的库 ldd /opt/screenlockdemo/bin/ScreenLockDemo | grep "not found" ``` ### 3. 手动添加缺失的库 如果某个库没有被自动打包: ```bash # 找到库的位置 find /usr /lib -name "libmissing.so*" 2>/dev/null # 手动复制到打包目录(在打包脚本的第5步后添加) cp /usr/local/lib/libmissing.so.1 "${DEB_DIR}/opt/${PACKAGE_NAME}/lib/" ``` ## 最佳实践 1. **编译时使用相对路径**:使用 `-rpath` 编译选项 2. **尽量打包所有依赖**:避免依赖目标系统的特定版本 3. **最小化系统依赖**:只依赖稳定的系统库(libc, libm 等) 4. **测试多个系统**:在干净的系统上测试安装 5. **文档化特殊依赖**:在 README 中说明特殊要求 ## 参考配置 当前配置已经包含: ```bash # 打包时 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" ``` 这应该能处理大多数情况。如有特殊需求,请根据上述指南调整。 ## 相关命令参考 ```bash # 查看系统库路径配置 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 ``` ## 更新历史 - 2024-01-01: 初始版本,添加 /usr/local/lib 和 /usr/local/lib64 支持 --- 如有问题或需要进一步的库路径配置,请参考此文档或咨询系统管理员。