linux平台打包qt应用程序
最近在做Linux平台的Qt开发,功能基本实现之后,就要考虑应用程序的打包了。
¶LINUX打包步骤
¶环境
os:ubuntu 20.04
开发工具:qt5.15.2(默认安装目录/opt/Qt)
¶linuxdeployqt打包
linux平台打包qt可以用linuxdeployqt一键部署,不用担心会少了什么,推荐先使用这个方法!
-
下载
Download linuxdeployqt
下载编译好的linuxdeployqt应用程序,我这里用的是linuxdeployqt-continuous-x86_64.AppImage,或者也可以下载源码创建linuxdeployqt docker版。 -
安装
1
2chmod +x linuxdeployqt-5-x86_64.AppImage
cp linuxdeployqt-5-x86_64.AppImage /usr/local/bin/linuxdeployqt -
添加环境变量
1
2
3
4
5
6# QT_HOME是自己安装的路径
export QT_HOME=/opt/Qt/5.15.2/gcc_64 #修改QT_HOME
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${QT_HOME}/lib
export QT_PLUGIN_PATH=$QT_PLUGIN_PATH:${QT_HOME}/plugins
export QML2_IMPORT_PATH=$QML2_IMPORT_PATH:${QT_HOME}/qml
PATH=$PATH:${QT_HOME}/bin -
打包qt程序
编译Release版本的目标程序,执行linuxdeployqt。1
2# linuxdeployqt 程序名称 -appimage -always-overwrite
linuxdeployqt VPNClient_Web -appimage -always-overwrite -
运行打包好的程序
运行linuxdeployqt中生成的AppRun程序。
¶自制脚本打包
当然linuxdeployqt可能会拷贝不全,从而导致程序运行出错。
比如对含有QtWebEngine的程序,使用linuxdeployqt一键打包,运行时出现缺少libsoftokn3.so库、缺少libmozsqlite3.so库等错误。
根本原因就是缺少了需要的nss,这时需要手动把nss目录下的所有文件拷贝到linuxdeployqt生成的lib文件夹下。
这时可以寄几制作打包脚本,运行脚本一键打包,不过脚本的制作需要考虑全面,可能比较复杂,可以对比两种方式实现打包。
¶准备ldd.sh
ldd.sh
:在当前目录下新建lib文件夹,拷贝目标程序的依赖库,存放到新建的lib下。
1 | chmod 777 ldd.sh |
¶制作打包脚本(copy_lib.sh)
-
变量设置
设置QT安装路径 QT_HOME=
设置目标文件夹 target_dir=
设置应用程序命 appname=
-
添加目标程序
将目标程序(mytest)、ldd.sh 和它的依赖库拷贝到目标文件夹。1
2cp mytest $target_dir
cp ldd.sh $target_dir -
添加程序依赖
1
./ldd.sh mytest
会在目标文件夹下生成lib目录,存放程序的依赖库。
-
添加qt依赖
创建plugins目录,拷贝qt的platfroms文件夹到目标文件夹的plugins目录;对platforms目录下的libqxcb.so生成qt依赖库。1
2
3
4mkdir plugins
cp -r $QT_HOME/plugins/platforms $target_dir/plugins
cd $target_dir/plugins/platforms
./ldd.sh libqxcb.so拷贝platfroms/lib目录下的所有文件到目标文件夹的lib目录,删除lib目录和目标文件夹中的ldd.sh文件。
1
2
3cp $target_dir/platforms/lib/* $target_dir/lib
rm -r $target_dir/platforms/lib
rm $target_dir/ldd.sh -
添加XCB
拷贝qt的xcbglintegrations目录到目标文件夹的plugins目录;
1
cp -r $QT_HOME/plugins/xcbglintegrations $target_dir/plugins
-
(可选)拷贝WebEngine依赖
如果项目工程里用到了QtWebEngine插件,那么为了WebEngine的正常运行,还需要拷贝其他依赖库。
- 添加QtWebEngine程序
目标文件夹下新建libexec目录,拷qt的QtWebEngineProcess程序到libexec目录下。
1
2
3cd $target_dir
mkdir libexec
cp $QT_HOME/libexec/QtWebEngineProcess $target_dir/libexec/
-
拷贝插件
拷贝qt目录的bearer、imageformats、platforminputcontexts、platformthemes拷贝到目标文件夹的plugins目录下。1
2
3
4cp -r $QT_HOME/plugins/bearer $target_dir/plugins/
cp -r $QT_HOME/plugins/imageformats $target_dir/plugins/
cp -r $QT_HOME/plugins/platforminputcontexts $target_dir/plugins/
cp -r $QT_HOME/plugins/platformthemes $target_dir/plugins/ -
拷贝资源文件
拷贝qt的resources目录到目标文件夹。1
cp -r $QT_HOME/resources $target_dir
-
拷贝翻译文件
拷贝qt的translations目录到目标文件夹;1
cp -r $QT_HOME/translations $target_dir
-
添加nss
拷贝系统的nss文件夹下所有文件到到目标文件夹的lib目录;1
2nss_path=`find /usr/ -name nss`
cp $nss_path/* $target_dir/lib
¶制作运行脚本
打包好的程序怎么执行呢?
解压压缩包,sudo执行mytest.sh。
1 | sudo ./mytest.sh |
¶脚本示例:
源码模板
-
1
2
3
4
5
6
7
8
9
LibDir=$PWD"/lib"
Target=$1
lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*"))
$(mkdir $LibDir)
for Variable in ${lib_array[@]}
do
cp "$Variable" $LibDir
done -
运行脚本mytest.sh(与可执行程序同名)
1
2
3
4
5
6
7
8
9
10
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 "$@"