前言
对于一个Qt开发者来说,也想有一套适合自己的持续集成方案,查了很多资料后,发现有几种实现途径:
- 在github上托管代码,使用action进行持续集成,这种方案应该是最简单的,有各种教程,也有很多现成的模板,拿来就可以用。
- 自建git服务器,同是搭配jenkins来使用,可能很多小伙伴都是使用此方案,也这应该是许多公司常用的方案
- 用gitee,coding等国内的代码托管平台,进行代码托管,然后使用这些平台支持的持续集成方案进行进行代码的自动化构建
第一种我没有采用,受限于同步速度和代码构建过程中需开源等原因
第二种是因为我的代码需要在不同地方经常使用,自建的服务外网很不友好
只能采用第三种,我这里使用coding的代码托管和其持续集成的功能。
我这里讲一下Qt程序对于windows平台的持续集成记录,其它平台会更简单
一、准备工作
- 注册一个coding账号,目前来说5人以下的团队都免费,使用功能都可以使用
- 上传一份Qt代码到远程仓库
- 准备一台windows机器做为节点机器,如果是想编译linux的qt程序,可以直接使用coding提供的免费节点,并且在windows机器上安装好QT5.15.0和vs2019,因为我是使用的msvc编译的qt程序
二、思路
- 使用qmake进行qt项目的make,生成makefile
- 使用QtCreator 带的jom进行编译,这一步没有使用nmake,原因是jom编译速度更快,默认多线程,而且也更简单
- QT在编译的时复制所有Qt所依赖的库,此需要在pro文件中加入windeployqt
- 使用QtIFW进行安装包的制作
- coding的持续集成也是使用的jenkins进行构建的,我们需要编写Jenkinsfile,但coding已经做了图形化操作,对于不了解Jenkins的同学来说,会方便很多。
三、使用步骤
1.项目pro文件中需包含以下代码
#定义编译好的程序存放目录
DESTDIR = $$OUT_PWD/../build
#复制Qt自身依赖项
QT_BIN_DIR = $$dirname(QMAKE_QMAKE) #QT bin 目录
QT_BIN_DIR = $$replace(QT_BIN_DIR,"/","\\") # 由于是windows下,需将/ 转换为 \\
DESTDIR_QT = $$DESTDIR
DESTDIR_QT ~= s,/,\\,g
DEPLOY_TARGET = $$shell_quote($$shell_path($$DESTDIR_QT\\$${TARGET}.exe))
# qml程序所依赖库
QMAKE_POST_LINK += $$escape_expand(\\n) $$QT_BIN_DIR\\windeployqt --qmldir=.\ $${DEPLOY_TARGET}
# qWidget 所依赖库,如果用到可以添加
#QMAKE_POST_LINK += $$escape_expand(\\n) $$QT_BIN_DIR\\windeployqt $${DEPLOY_TARGET}
用于Qt在构建的时候自动复制Qt所依赖的Qt库,可以在pro文件中设置好所有依赖库,让其在编译的时候自动复制所有库,用这种模式,就不需要单独再使用windeployqt 去复制Qt库
2. 在项目文件中添加几个bat文件
此文件命名为build5-15-2-win32.bat
@echo off
:: 使用时必须传入pro文件
set vsPath="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat"
set QTDIR=D:\Qt\5.15.0\msvc2019\bin;
set proFile=%1
set jomPath=D:\Qt\Tools\QtCreator\bin;
:: 删除上一次编译的文件,删除整个文件夹
if exist build rd /s /q build
@if exist %vsPath% ( call %vsPath% ) else ( echo "vcvars32.bat not exist,please check the path")
@if not exist %proFile% ( echo "pro file not exist,please check the pro file")
:: 调用msvc的编译环境
call %vsPath%
:: 设置临时变量
set PATH=%QTDIR%%jomPath% %PATH%
echo "***************qmake start***************"
qmake %proFile% -spec win32-msvc
echo "***************qmake end***************"
echo "***************jom qmake_all***************"
jom qmake_all
echo "***************jom***************"
jom
echo "***************jom clean***************"
jom clean
echo "***************delete build temp files***************"
:: /f 强制删除只读文件 /s 从所有子目录删除指定文件 /q 安静模式,不要求确认
if exist Makefile del /f /s /q Makefile
if exist Makefile.Debug del /f /s /q Makefile.Debug
if exist Makefile.Release del /f /s /q Makefile.Release
if exist .qmake.stash del /f /s /q .qmake.stash
if exist vc140.pdb del /f /s /q vc140.pdb
if exist ui_MainWindow.h del /f /s /q ui_MainWindow.h
此文件拿去就可以用,也可以在本机测试,只要设置好vsPath和QTDIR,jomPath,这三个路径,并且执行时传入pro文件路径,就可以编译成QT程序
build2exe.bat
@echo off
:: 获取版本号
for /f %%a in ('git describe --abbrev^=0 --tags') do set LATEST_TAG=%%a
echo %LATEST_TAG%
set name=CiForQt%LATEST_TAG%.exe
set zipName=CiForQt%LATEST_TAG%.zip
:: 清除已存在的同名文件
if exist out\%name% del /f /s /q out\%name%
if exist out\%zipName% del /f /s /q out\%zipName%
:: 先删除打包目录里可能存在的文件
if exist workflows\BuildToExe\packages\install\data rd /s /q workflows\BuildToExe\packages\install\data
md workflows\BuildToExe\packages\install\data
:: 拷贝build到打包目录
xcopy build workflows\BuildToExe\packages\install\data /s/e/i/y
:: 如果out文件不存在,创建
if not exist out md out
:: 开始打包
D:\Qt\QtIFW-4.0.0\bin\binarycreator.exe -c workflows\BuildToExe\config\config.xml -p workflows\BuildToExe\packages out\%name%
:: 将exe打包为zip格式,防止在某些系统是上传exe会报错的情况
"C:\Program Files\Bandizip\bc.exe" c out\%zipName% out\%name%
::拷贝到目标目录
copy out\%zipName% E:\Share\软件发布\安装包\
此bat用于将QT编译的程序打包成exe安装包,使用的是QtIFW,注意不要使用QtIFW4.1.1这个版本的会使用D3D12,如果节点机器上没有,会用不了,下一个版本会修复。另外使用了Bandizip将exe打包为zip,打包成zip是因为exe文件在有些地方不让上传,用什么工具压缩大家可以自己设置,比如7z,rar等都可以。最后一行是拷贝文件,将压缩好的文件存放到固定位置
注意:使用时要注意替换QtIFW和 Bandizip的路径
3.新建构建节点
下载cci-agent ,按要求启用后就连接了,这步很简单。
连接上后就会看到节点主机了,还可以看详细信息
4. 创建构建计划
我们选择自定义构建过程
这里看到coding支持的代码仓库还挺多,,jenkinsfile文件我这里选择代码库中的文件,也可静态配置
前于两者的选择:
如果你的代码会有多个分支时同工作并打包,或者开发人员和维护持续构建的人员不是同一个,建议使用静态配置
如果开发人员和持续构建都是同一个,那可以用代码库中的Jenkinsfile。注意这里的路径是以你打开代码仓库的顶级目录为起点 如 CiForQt/workflows/windows-Jenkinsfile。。。注意是’/’ ,而不是’’
这里就进入到图形化界面了
这里只需要根据需求自己设置就可以了,还是很简单的。但也有很多的坑
- 如果要上传制品库,在windows节点下,它并不支持路径选择 比如 AA/BB/CC.zip。只能使用先进入子目录,再上传
编辑好构建流程后,还需去设置构建节点,如下图
选择我们自己的windows节点,保存完进行构建就是了
触发规则可根据自己所需进行更改,如果是用我的Jenkinsfile,建议使用tag来触发,因为我打包是根据tag号来进行打包的
5. 开源示例代码
https://q669.coding.net/public/buildtest/test/git
总结
- 如果大家都懂shell脚本,Jenkins,qmake,jom 的使用,那这些会很简单。
- windows节点,coding支持的不是很好,bug比较多,特别是编码问题,用时请注意,尽可能统一文件编码为utf-8,不然会有各种乱码。可能会出现节点机器不能识别上面写的两个bat的情况,这里节点机器cmd的编码格式,百度上可以找到很多。
- windows节点,可以使用build5-15-2-win32.bat 去编译的时候,再上coding
- QtCreator 不要去编辑Jenkinsfile,在行首会多出一个什么字符,coding会识别错误,可能是我的QtCreator的问题
- 在测试的过程中,最好取消 构建计划设置里 触发规则 自动取消相同版本号 ,不然同一个版本的代码不能编译多次
- 如果使用企业微信插件,节点机器要安装python3.8以上版本,还需要安装golong,golong用于企业微信返回数据的解析。另外企业微信插件Windows端的bug比较多,比如不能发送带换行符的微信消息,比如某些控件窗口不能输入“\”的问题,比如字符串乱码的问题
- coding 的Jenkins执行bat的路径统一都是仓库的顶级目录开始
- 可以多看看coding的帮助中心,很全面
- 如果遇到实现解决不了问题,可以提交工单,一般1小时内就会有回复