准备工作:
项目/可执行文件名:QTAppName
打包项目存放的文件名:pack(这个文件名无所谓)
脚本名:
copylib.sh(类似ldd命令):用于将.so库文件的依赖项复制并放入自动生成的 “lib文件” 中。
QTAppName.sh(注:该脚本名为"可执行文件名.sh")“:用于最后执行可执行文件的脚本
- 将Qt项目使用Release模式编译运行一遍,确保生成可执行文件 QTAppName
- 脚本编写:
copylib.sh
#!/bin/bash
LibDir=$PWD"/lib"
Target=$1lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*"))$(mkdir $LibDir)
for Variable in ${lib_array[@]}
docp "$Variable" $LibDir
done
QTAppName.sh
#!/bin/sh
appname=`basename $0 | sed s,\.sh$,,`dirname=`dirname $0`
tmp="${dirname#?}"if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/$appname "$@"
- 权限给予
chmod 777 copylib.sh QTAppName.sh
开始打包
- 将copylib.sh拷贝进对应项目的构建/build目录(例如:build-SmartCheckImgWidget_4_3-Desktop_Qt_5_15_2_GCC_64bit-Release)
- 在Terminal中,输入./copylib.sh QTAppName
- 将① QTAppName的可执行程序、② lib文件夹里面全部的文件**(不是直接复制lib文件夹,是文件夹的内容)** 复制到 pack文件夹中;
- 复制完毕后,将lib文件夹删除即可。
- 进入Qt的安装目录,并将copylib.sh拷贝qt中的platforms目录下(我的目录:/opt/Qt/5.15.2/gcc_64/plugins/platforms)。
- 执行 ./copylib.sh libqxcb.so(注:xcb是移植的重要文件,如果拷贝错误将不能在目标主机运行。)
- 回到plugins(platforms的上级目录)将platforms整个文件夹拷贝到pack
- 将libqxcb.so依赖库文件夹内(pack/platforms/lib/*)的东西全部放到pack目录下(可能会有重复项替换即可)。并删除pack/platforms/lib文件夹及其所属文件。(最后记得将原来Qt/5.15.2/gcc_64/plugins/platform/lib也删除了,虽然不删除也没啥事)
若是还有其他依赖项目,如:所编写的程序有操作数据库的动作,还需要将与platforms同级目录中的sqldrivers文件夹也拷贝到“pack文件夹”中
QTAppName.sh放入pack,并使用 ./QTAppName.sh 调用测试是否成功
可能问题:
问题一:打包后在其他设备上尝试 ./QTAppName.sh 运行,报错Inconsistency detected by ld.so: dl-deps.c: 622: _dl_map_object_deps: Assertion `nlist > 1‘ failed!
解决方案:该问题大概率是由libc(该库是linux底层的一个基本库)的版本不一致导致的,可以使用以下命令查看libc版本
ldd --version
若是版本不一致可以尝试更新libc6,但是并不推荐该方法,因为这是一个底层库这样做可能有风险,且该库的高版本并不一定兼容低版本,手动安装指定版本,系统可能会在安装的过程中崩溃。
sudo apt-get update
sudo apt-get install libc6
**推荐方法:**使打包主机和运行的环境主机的版本号(不是内核版本)一致,且没有更新过
cat /etc/os-release //可以查看发行版本
问题二:依赖缺失
解决方案:
- 模块缺失在上文的开始打包中仿照Qt依赖项的获取,添加对应的依赖即可
- .so库的依赖缺失:使用ldd命令,查看库的依赖情况
ldd 依赖库名.so
决方案:
- 模块缺失在上文的开始打包中仿照Qt依赖项的获取,添加对应的依赖即可
- .so库的依赖缺失:使用ldd命令,查看库的依赖情况
ldd 依赖库名.so
尝试使用find查询打包主机上对应依赖项,并添加