C++程序如何使用Jenkins自动化打包详细教程

一. 环境

操作系统:Windows 10

Qt版本:QT5.12.8

Visual Studio版本:Visual Studio 2017

NSIS版本:NSIS 3.08 增强版

Jenkins版本:2.346 (建议使用最新)

以下是环境搭建说明:

Windows下Jenkins软件安装说明及配置_枫蓝驿的博客-CSDN博客

Visual Studio 2017下载及安装_枫蓝驿的博客-CSDN博客

win10 安装 Qt 5.12.8 安装_枫蓝驿的博客-CSDN博客

CentOS 安装Gitlab及 配置_枫蓝驿的博客-CSDN博客

二、Jenkins 创建项目

2.1 新建项目

项目名称:自定义(必填项),最好和项目相关,区分不同项目

项目类型:Freestyle project 自由风格的项目

2.2 常规设置

Gitlab Connection 需要在插件中心安装Gitlab插件,并在System配置Gitlab Token方可使用

Rebuild 需要在插件中心 安装Rebuild插件方可使用

This project is parameterized支持参数化构建,定义一个唯一的参数名称.${PARAMETER_NAME},在脚本中通过%PARAMETER_NAME%全局参数来获取参数的值

常用的有:     

Choice Parameter 单选

git Parameter git参数

如下分别是单选和git参数示例: 

 配置完成后参数最终构建时的界面样式:

2.3 源码管理

源码管理支持git 及多repo的SCMs

默认git ,仅能添加一个主仓库,如存在多个依赖仓库时选择Multiple SCMs,Multiple SCMs需要在插件中心安装Multiple SCMs才能被支持。

一般在jenkins项目创建之前,需要把主repo,依赖repo进行汇总,然后便于在jenkins上进行添加,如下表有两个repo那这时候我们就选择Multiple SCMs添加多个git仓库了

git仓库

分支

主库:

http://192.168.1.2:9999/demo/ANK.git

${Branch}

依赖库1:http://192.168.1.2:9999/demo/tools.git

${ToolBranch}

2.4 构建触发器

触发远程构建器:配置一个构建项目的token,拼接在URL上,通过脚本调用URL来实现打包

如下:

http://192.168.3.24:8080/http://192.168.1.3:8080/view/AAA/job/DemoCI/build?token=TOKEN_NAME

可以直接在浏览器直接打开这个地址旧可以触发构建

Build after other projects are built: 当前项目构建时依赖于其他项目其他项目构建成功失败等条件时触发。

Build periodically:定时构建,支持cron语法

 webhook :在gitlab项目中setting配置webhook并开启 GitLab triggers,根据配置条件,如push Merg,等事件触发构建,一般为Accepted Merge Request Events,

如果是使用jenkins做自动化代码静态检查,也会在push时触发;

GitHub hook trigger for GITScm polling:GItHUb一般国内用不到

Gitlab Merge Requests Builder:Merge Requests触发build,如果成功自动执行Merge

Poll SCM:jenkins定期去扫描repo改动,如有改动则触发构建,支持cron语法,不建议去用轮询来检测更改,因为每次会去检测整个工作区与gitlab服务器的差异,相当耗性能。

2.5 构建环境

构建环境常用的功能,开启控制台显示时间线,默认为不显示

2.6 构建步骤

由于我们是在windows下构建windows平台的应用程序,所以我们选择windows batch command来执行脚本,增加构建步骤——>Execute Windows batch command

2.7 Jenkin批处理调用示例

@echo off

call D:\Demo\DemoCI\01_CI.bat

 

2.8 Jenkins批处理调用顺序

01_CI.bat 分别按顺序来调用Build Deploy package Install等脚本

​三、脚本详解

01_CI Jenkins目标脚本

rem表示注释,因为当前是调试环境,如果田间到jenkins执行时可以根据自身需求增减,jenkins全局参数可参考jenkins api进行调用,

定义全局变量

 %CIDIR%:脚本目录,%~dp0 表示当前目录,使用%cd%也可以实现
%WORKSPACE%:Jenkins自身全局变量,为jenkins工作区目录
%Branch%:jenkins新建项目时,定义的git Paramer 参数名称
%BUILD_NUMBER%:jenkins当前编译的序号从0开始递增
PRODUCT_NAME:jenkins构建项目名称

@echo off

rem 定义全局变量
set CIDIR=%~dp0
set WORKSPACE=E:\workspace
REM set SRCDIR=%WORKSPACE%
REM set BRANCH_NAME=%Branch%
REM set BUILD_NUMBER=%BUILD_NUMBER%
set PRODUCT_NAME=analogclock

rem 回调编译、打包、安装包制作脚本
call %CIDIR%/02_build.bat
call %CIDIR%/03_deploy.bat
call %CIDIR%/04_Install.bat

02_build 批处理调用qmake编译

为什么要设置QTTDIR、QTMSDIR、VCDIR?

因为一台电脑上可能安装多个qt和visual studia版本,甚至有没有设置环境变量都不一定,如果使用默认那就有可能编译报错,甚至编译成功但是打开软件会提示0x000007f 这种无脑异常,找问题贼难找,那为了解决这个问题我们首先要做的是确认和开发中使用的环境一致(qt版本、vs版本)。

QTTDIR、QTMSDIR、VCDIR等vs和qt目录,均为默认安装时的目录,请确认和您的环境一致

第4行 QTTDIR变量:jom多线程编译器的路径

第5行 QTMSDIR变量:qmake编译器的路径

第6行 VCDIR变量:VC环境配置目录

vcvarsall.bat  x86_amd64   ## 使用 32 位 x86 本机兼容工具生成 64 位 x64 代码。

第8行 编译缓存文件

第10行 pro文件路径

第13行 编译前清除缓存和编译文件,目的是解决新的编译存在旧的文件,导致编译出来的exe不是最新的。

第16行 调用vc环境

第18行 执行qmake编译,

        -wnone 参数 ,不输出警告信息

        -spec win32-msvc 参数,告诉 qmake 生成适用于 Windows 平台的 Microsoft Visual C++ 项目文件

        "CONFIG += release" ,指定了构建类型为 release 版本

 第19行 jom多线程编译 ,/j 4 ,如果cpu核数足够多,可以更改为/j 8 甚至更高来加快编译速度

第23行 windeployqt.exe工具自动地将程序依赖的库、资源拷贝到其所在目录,防止程序运行报找不到库的错误。

qt 编译脚本
@echo off
rem 设置VisualStudio和QT的目录
set WORKSPACE=E:\workspace
set QTTDIR=C:\Qt\Qt5.12.8\Tools\QtCreator\bin
set QTMSDIR=C:\Qt\Qt5.12.8\5.12.8\msvc2017_64\bin
set VCDIR="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"
rem 设置构建目录
set BUILD_DIR=%WORKSPACE%\qt-build\AutoBuild\build
rem 设置需要编译的pro文件的地址
set TARGETPRO="%WORKSPACE%\qt-build\analogclock\analogclock.pro"



rem 编译前,清空编译缓存和旧文件
rmdir /s /q %BUILD_DIR% && mkdir %BUILD_DIR% && cd /d %BUILD_DIR%
rem 执行VS的脚本配置当前环境
call %VCDIR% x86_amd64
::配置构建参数
%QTMSDIR%/qmake.exe %TARGETPRO% -Wnone -spec win32-msvc "CONFIG += release"
%QTTDIR%/jom.exe /j 4 /f Makefile
%QTTDIR%/jom.exe -f Makefile.Release clean  
REM ::构建完成之后清空对应的中间文件 
cd .\release
if not exist "analogclock.exe" (
         echo "**************************error: analogclock.exe no-exit******************************************"
		 exit 2
)
%QTMSDIR%\windeployqt.exe analogclock.exe

03_deploy copy静态文件

deploy 需要根据自身项目需求,来编写不同的脚本,大体的作用是将静态文件,依赖的dll文件,copy到预打包目录

chcp 65001
@ECHO off

SET BINDIR="%WORKSPACE%\qt-build\analogclock"
set RELEASE_DIR=%WORKSPACE%\qt-build\AutoBuild\build\release

mkdir %RELEASE_DIR%\config
xcopy /E /y /i %BINDIR%\*.cfg %RELEASE_DIR%\config
xcopy /E /y /i %BINDIR%\*.sql %RELEASE_DIR%\config
xcopy /E /y /i %BINDIR%\*.yml %RELEASE_DIR%\config
xcopy /E /y /i %BINDIR%\*.json %RELEASE_DIR%\config
xcopy /E /y /i %BINDIR%\*.dt %RELEASE_DIR%\config
xcopy /E /y /i %BINDIR%\*.qm %RELEASE_DIR%\config

echo {>>%RELEASE_DIR%\product.ini
echo    "product_name":"analogclock",>>%RELEASE_DIR%\product.ini
echo    "product_version":"V1.0.0",>>%RELEASE_DIR%\product.ini
echo    "inner_product_version":"%BRANCH_NAME% ",>>%RELEASE_DIR%\product.ini
echo    "file_version":"%VER%">>%RELEASE_DIR%\product.ini
echo }>>%RELEASE_DIR%\product.ini

04_package 打包安装包

NSISDIR:定义NSIS编译器目录

NSISSCRIPTDIR:定义NSIS脚本目录

chcp 65001
@echo off
set WORKSPACE=E:\workspace
set NSISDIR=E:\workspace\qt-build\NSIS
set NSISSCRIPTDIR=%WORKSPACE%\qt-build\AutoBuild


echo "*********************start makensis %data% %time%******************"
%NSISDIR%\makensis.exe %NSISSCRIPTDIR%\analogclock.nsi
echo "*********************end makensis %data% %time%******************"

05 NSIS脚本

第10行 !define PackgePath "E:\workspace\qt-build" 项目路径,建议先将项目clone下来跑通了再进行修改

第11行 !AddPluginDir "F:\Packge_Installer\NSIS\Plugins",NSIS路径需要改成您实际的NSIS路径

; include for some of the windows messages defines
!include "MUI2.nsh"
!include "WinMessages.nsh"
!include "LogicLib.nsh"
!include "x64.nsh"
!define "LIBRARY_X64"
!include "FileFunc.nsh"

; 定义打包路径
!define PackgePath "E:\workspace\qt-build"
!AddPluginDir "E:\workspace\qt-build\NSIS\Plugins"

; UAC进行权限请求 RequestExecutionLevel none|user|highest|admin
RequestExecutionLevel admin
SetCompressor lzma
SetCompressorDictSize 32
Unicode True

; OutPutProductName
!define analogclock_ViewerName "analogclock"
!define analogclock_exeName "analogclock"
!define DependentProduct "analogclock"
!define PRODUCTNAME "${analogclock_ViewerName}"
!define ORGNAME "QTBuild"
; ProductType



; Product Information
!define Version "V1.0.0"
!define FullVersion "1.0.0.6"
!define analogclock_UDI ""
!define analogclock_ProductName "QtGUI测试软件"
!define analogclock_ProductModel "analogclock"
!define analogclock_FileVersion "${FullVersion}"
!define analogclock_ProductVersion "${Version}"
!define analogclock_PublishDate "2022-01-30"
!define analogclock_LegalCopyright "Copyright@ 2022 xxxxxxxx Technology Co., LTD. All Rights Reserved."
!define analogclock_CompanyName "xxxxxx有限公司"
!define analogclock_Address "xxxxxxx大厦11层18室"


; Product File Version
VIProductVersion "${FullVersion}"
VIAddVersionKey /LANG=2052 "ProductName" "${analogclock_ProductName}"
VIAddVersionKey /LANG=2052 "FileDescription" "${analogclock_ProductModel}"
VIAddVersionKey /LANG=2052 "LegalCopyright" "Copyright(C) 2022 xxxxxxx Technology Co., LTD. All Rights Reserved."
VIAddVersionKey /LANG=2052 "ProductVersion" "${Version}"
VIAddVersionKey /LANG=2052 "FileVersion" "${FullVersion}"


; 安装和卸载程序图标
!define MUI_ICON "${PackgePath}\AutoBuild\static\logo.ico"
!define MUI_UNICON "${PackgePath}\AutoBuild\static\uninstx.ico"

!define MUI_PRODUCT "${PRODUCTNAME}"

; 定义输出安装包名称
!define /date PRODUCT_TIME %Y%m%d%H%M%S
OutFile "${PackgePath}\Install_${analogclock_ProductName}_${PRODUCT_TIME}.exe"

Name "${MUI_PRODUCT}"

; 展示安装细节
ShowInstDetails "show"
ShowUninstDetails "show"
AutoCloseWindow false

SetDateSave on
SetDatablockOptimize on
CRCCheck on
SilentInstall normal


; 定义安装路径
;InstallDir "$PROGRAMFILES64\${ORGNAME}"
InstallDir "D:\${ORGNAME}"
; 判断D盘存在与否确定安装路径
!define DrivePath "D:\"

;BrandingText "www.manual.com"
BrandingText " "

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!insertmacro MUI_PAGE_WELCOME
;!insertmacro MUI_PAGE_LICENSE textfile
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH

; Languages
!insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "English"

;---------------------------------------------------------------------------------------
;Installer Sections


Section "${analogclock_ViewerName}" S_2
    SetOutPath "$INSTDIR\analogclock"
    File /r "${PackgePath}\AutoBuild\build\release\*"

    SetOutPath "$INSTDIR\analogclock"
    WriteUninstaller "$INSTDIR\analogclock\uninst.exe"
	
SectionEnd



; 未选择组件禁止下一步(只针对Section生效)
 Function .onSelChange
     StrCpy $0 0
     StrCpy $1 ${S_2}
     ${DoWhile} $1 <= ${S_2}
         ${If} ${SectionIsSelected} $1
             StrCpy $0 1
             ${ExitDo}
         ${EndIf}
         IntOp $1 $1 + 1
     ${Loop}

     GetDlgItem $1 $HwndParent 1
     EnableWindow $1 $0
 FunctionEnd



;=============================================================================================================
;Uninstaller Sections

Section "Uninstall"

    ; make sure windows knows about the change
    SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment"  /TIMEOUT=5000

    nsExec::Exec "TASKKILL /F /IM ${analogclock_exeName}.exe /T"

    RMDir /r "$INSTDIR\${analogclock_exeName}"
    RMDir /r "$INSTDIR"

    IfFileExists "$INSTDIR" 0 NoErrorMsg
        MessageBox MB_OK "Note: $INSTDIR could not be removed!" IDOK 0 ; skipped if file doesn't exist
    NoErrorMsg:

SectionEnd

编译输出安装包

NSIS 使用版本

QtBuild: Qt c++ jenkins使用批处理编译

四、编译完整demo开源仓库

此仓库已经开源,欢迎下载:

git clone https://gitee.com/fenglanyi/qt-build.git

QtBuild: Qt c++ jenkins使用批处理编译

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值