不管是Ubuntu版本还是CentOS7版本的Linux,QT打包都是一个大问题,困扰了我很久。每次都是打包之后,在本机上是可以运行程序的,但是拿到其他电脑上就提示如下图错误,运行不起来。
下面是我整理的打包教程。
在Ubuntu和CentOS7下都适用(只试了这两个)。
1.创建一个单独的文件夹install,将需要发布的QT的可执行程序RoutePlanning复制到install文件夹中。
2.在install文件夹中创建脚本文件,命令为:
touch pack.sh
在脚本文件中写入如下内容:
#!/bin/bash
LibDir=$PWD
Target=$1
lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*"))
for Variable in ${lib_array[@]}
do
cp "$Variable" $LibDir
done
设置脚本权限,命令为:
chmod 777 pack.sh
执行脚本,命令为:
./pack.sh RoutePlanning
其中RoutePlanning为执行程序,此时会在该文件夹install下生成执行程序RoutePlanning依赖的QT基础库。
3.去QT的安装目录下,找到/home/li/Qt5.12.9/5.12.9/gcc_64/plugins/platforms目录
cd /home/li/Qt5.12.9/5.12.9/gcc_64/plugins/platforms
创建pack.sh脚本,写入脚本内容如下:
#!/bin/bash
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
这两个脚本在功能上是一样的,都是生成执行程序的依赖库。只不过区别在于2步骤直接将依赖库生成在当前目录;而3步骤创建了一个lib文件夹,用来存放依赖库,目的是方便清除,不改变QT的安装目录下的文件。
执行脚本,命令为:
./pack.sh libqxcb.so
会在该目录下生成一个lib文件夹
将里面的内容复制到install文件夹下
cd lib
cp * /home/install/ -rf
删除lib文件夹
cd ../
rm lib -rf
4.将platfroms文件夹也复制到install文件夹下。
cp platforms /home/install -rf
5.当程序中引用了模块时,也需要将模块库复制到install文件夹下,比如我的程序中引用了network,需要libQt5WebSockets.so.5库,找到/home/li/Qt5.12.9/5.12.9/gcc_64/lib目录
cp /home/li/Qt5.12.9/5.12.9/gcc_64/lib/libQt5WebSockets.so.5.12.9 ./ -d
cp /home/li/Qt5.12.9/5.12.9/gcc_64/lib/libQt5WebSockets.so.5 ./ -d
我试了复制这两个文件才能把链接复制过来。可以找更好的方法。
6.将自己创建的动态库链接复制到install文件夹下。
这样程序打包就完成了。
在install文件夹下创建RoutePlanning.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 RoutePlanning.sh
执行
./RoutePlanning.sh
此时的执行程序在关闭终端之后也会随之关闭,如果想把程序放入后台运行,即使关闭终端也不影响程序进程的运行,可以在install文件夹下创建run.sh脚本并添加如下脚本内容:
#!/bin/sh
path=$(pwd -P)
echo ${path}
nohup ${path}/RoutePlanning.sh &
关闭程序可以通过杀进程的方式。在install文件夹下创建close.sh脚本并写入如下内容:
#!/bin/bash
PID=`ps -ef | grep RoutePlanning | grep -v "grep" | awk '{print $2}'`
if [ $? -eq 0 ]; then
echo "process id:$PID"
else
echo "process $input1 not exit"
exit
fi
kill -9 ${PID}
if [ $? -eq 0 ];then
echo "kill $input1 success"
else
echo "kill $input1 fail"
fi
执行脚本即可关闭。