ScreenLockDetector/LIBRARY_PATH_NOTE.md

5.8 KiB
Raw Blame History

库路径配置说明

问题背景

在运行 ./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.shScreenLockDemo.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
  • 系统标准库

库搜索顺序

程序运行时的库搜索顺序:

  1. /usr/local/lib - 用户自定义安装的库
  2. /usr/local/lib64 - 64位用户自定义库
  3. ${APP_DIR}/lib - DEB 包自带的库Qt 和依赖)
  4. $LD_LIBRARY_PATH - 原有的库路径
  5. 系统默认路径(/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: 有两个选择:

  1. 打包该库(推荐):确保 linuxdeployqt 能找到并打包它
  2. 在 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/"

最佳实践

  1. 编译时使用相对路径:使用 -rpath 编译选项
  2. 尽量打包所有依赖:避免依赖目标系统的特定版本
  3. 最小化系统依赖只依赖稳定的系统库libc, libm 等)
  4. 测试多个系统:在干净的系统上测试安装
  5. 文档化特殊依赖:在 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

更新历史

  • 2024-01-01: 初始版本,添加 /usr/local/lib 和 /usr/local/lib64 支持

如有问题或需要进一步的库路径配置,请参考此文档或咨询系统管理员。