Linux环境打包Qt程序并部署到Docker容器

1 篇文章 0 订阅

Linux环境打包Qt程序并部署到Docker容器

根据项目需要,将UKylin版本的qt应用程序打包并且部署到docker容器中

系统版本

  • UKylin版本:Ubuntu18.04
  • Docker镜像:Ubuntu:latest

一、打包QT应用程序

一般默认创建项目后,Qt Creator的左下角构建模式会出现三种,分别为Debug、Profile、Release,它们的区别在于Debug可以调试程序,Release不可以。程序出错时,在Debug模式下可以通过设置断点来调试程序。当程序所有错误都解决以后,在Release模式下生成程序,就可以对外发布。而Debug生成的程序因为包含了调试信息,编译器也未做优化,所以比Release模式生成的程序要大很多,而Profile则介于两者之间,用的比较少。

1. 编译可执行文件

在这里插入图片描述
确保程序在Debug模式下构建通过后,再选择Release模式构建项目,在生成目录查看生成的文件格式,点开CodeFrameBuilder(程序名称)属性发现当前应用程序文件为共享库文件,并非打包所需要的可执行文件。
在这里插入图片描述
此时打开程序源代码,在工程文件末尾添加代码:QMAKE_LFLAGS += -no-pie
重新编译后再打开生成目录,可以直观看到程序的图标变为可执行文件的图标,点开属性变为x-executable,即可执行exe。
在这里插入图片描述

2. 配置QT环境

打开系统终端,输入指令配置Qt环境

//配置linux环境变量
vim ~/.bashrc
//输入a/i进入编辑模式,在文件结尾添加Qt库路径,其中home/appsoft为Qt源码包的路径
export PATH=/home/appsoft/Qt5.9.5/5.9.5/gcc_64/bin:$PATH
export LD_LIBRARY_PATH=/home/appsoft/Qt5.9.5/5.9.5/gcc_64/lib:$LD_LIBRARY_PATH
export QT_PLUGIN_PATH=/home/appsoft/Qt5.9.5/5.9.5/gcc_64/plugins:$QT_PLUGIN_PATH
export QML2_IMPORT_PATH=/home/appsoft/Qt5.9.5/5.9.5/gcc_64/gml:$QML2_IMPORT_PATH
//添加完成后,点击esc退出编辑模式,输入:wq保存退出
source ~/.bashrc
//终端执行生效

3. 安装linuxdeployqt

3.1 下载linuxdeployqt

linuxdeployqt 下载linuxdeployqt-continuous-x86_64.AppImage , 该包是一个静态程序可以直接拿来使用。

3.2 安装linuxdeployqt

将下载好的linuxdeployqt包移动到虚拟机中,对其重命名并移动到指定路径

mv linuxdeployqt-continuous-x86_64.AppImage linuxdeployqt
chmod 777 linuxdeployqt
mv linuxdeployqt /usr/local/bin
//测试是否成功
linuxdeployqt --version
//测试结果
linuxdeployqt (commit edbf092), build 45 built on 2023-04-04 19:32:05 UTC

4. linuxdeployqt查找依赖库

将已编译生成好的Release版可执行程序(CodeFrameBuilder)复制到一个新的文件夹中,在新的文件夹(/home/appsoft/MyTools/New)中打开终端。
在这里插入图片描述
即在当前路径下,对应用程序进行打包;
注意:该工具只是找寻了所需的Qt依赖,但Qt环境需要的基础依赖库并没有找齐,将其放在docker下仍然跑不起来。

linuxdeployqt CodeFrameBuilder -appimage

若出现.desktop file is missing a Categories= key问题,则根据报错提示对当前文件夹下新生成的default.desktop结尾中添加:

vim default.desktop
//在结尾添加,退出保存
Categories=Application;


然后重新运行打包指令:linuxdeployqt CodeFrameBuilder -appimage

5. 添加libqxcb.so依赖库

5.1 创建脚本

脚本作用就是找到qt环境需要的基础依赖库即xcb库

//touch lib_copy.sh(可忽略)
//vim lib_copy.sh
//复制文本到lib_copy.sh
#!/bin/bash
if [ $# != 1 ]
then
    echo "传参数顺序: ./脚本.sh  <要发布的可执行文件文件>"
    exit 0
fi
LibDir=$PWD/xcblib
mkdir $LibDir
Target=$1
lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*"))
for Variable in ${lib_array[@]}
do
    cp "$Variable" $LibDir
done
5.2 执行脚本

libqxcb.so 在qt运行环境下的plugins/platforms/ 目录,但是之前已经将路径添加到了配置环境中,可以直接运行。

bash ./lib_copy.sh plugins/platforms/libqxcb.so

完成以上步骤,程序所依赖的Qt库和Qt依赖的库都分别放在 lib/ 和 xcblib/ 目录下,它们之间有些库是重复的,可以将其合成一个目录。

二、部署到Docker容器

1. 开放docker的gui权限

此后操作都需在当前终端上执行,因为当前终端开启了x11权限,但在重启后就不会有这些顾虑了,因为该权限已经应用到了全局。

vim /etc/profile
//在/etc/profile末尾添加
if [ "$DISPLAY" != "" ]
then
 xhost +
fi
//保存退出后,终端执行
source /etc/profile

2. 创建容器

使用docker run命令创建容器

//test为容器名称
docker run -itd -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE  --name test --privileged  -v ./data:/data --network host ubuntu:18.04 bash
docker exec -it test bash

在docker容器内测试x11图形界面权限,若出现下图所示即成功,若报错can't open display则重启再进行测试。

apt update
apt install xarclock
xarclock
//若成功则退出docker容器
exit

在这里插入图片描述

3. 复制文件夹

因为在新的文件夹中打开的终端,并且并未对文件路径进行操作,可以在终端直接输入

//../New为打包好的文件夹相对与当前终端路径
//69de为docker容器ID, /home/则为复制到容器内的位置
docker cp ../New 69de:/home/

4. 运行qt程序

进入docker后,开始测试我们的Qt程序能否执行。

cd /home/New
//这一步是为了报错的时候,可以看到报错的地方
export QT_DEBUG_PLUGINS=1
//这一步是给出依赖的库路径,请根据实际情况调整
export LD_LIBRARY_PATH=./lib:./xcblib
./CodeFrameBulder

设置依赖库的环境变量和Qt调试环境变量
如果中间报错缺少库,设置 QT_DEBUG_PLUGINS 为 1 后可以看到缺少库的名称,可以在主机中找到对应的库并拷贝到 docker 中。
也可以通过 apt-file search libxx.so 来查找属于哪个包,然后安装对应的包。

注意事项:运行qt应用程序出现错误的原因:宿主机的系统版本和docker容器系统版本不一致,导致libc的版本不一致。

  • 解决方法删除xcblib中的libc.so.6, librt.so.1, libpthread.so.0,默认用镜像自身的;
  • 将系统的库路径设置在 LD_LIBRARY_PATH 的前面,让其先从系统库路径下查找库。
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值