title: 使用 Jenksin 跨平台开发 Qt 桌面应用
src: posts/2022-09-09-使用 Jenkins 跨平台部署 Qt 应用.md
change log: None
created at: Jan. 24, 2026, 12:39 p.m., last updated: Jan. 24, 2026, 12:39 p.m.
如今带图形界面的软件流行的都是web搞跨平台,或是移动端开发。桌面开发没刚2000年刚接触电脑时的红火,linux桌面开发就更没人搞了。这个流程搭建纯粹个人爱好,用爱发电。
这篇文章会介绍如何搭建一个工作流在win端写代码,push到原创仓库后,linux端自动拉取代码构建。这里的linux不是需要交叉编译的嵌入式设备,是一个有完整桌面环境的linux设备,我用的是一台raspberry 400。
首先得有一台私有的Jenksin服务器,我用docker在阿里云搭了一个atian.icu:8000
win 安装 qt(官网默认 mingw 版本)
然后用QtCreator随便写个工程,CMakeLists.txt 大概是这样的:
cmake_minimum_required(VERSION 3.5)
project(qt_leetcode_note VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools)
set(TS_FILES qt_leetcode_note_zh_CN.ts)
set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
${TS_FILES}
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(qt_leetcode_note
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET qt_leetcode_note APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
if(ANDROID)
add_library(qt_leetcode_note SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(qt_leetcode_note
${PROJECT_SOURCES}
)
endif()
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()
target_link_libraries(qt_leetcode_note PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(qt_leetcode_note PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
install(TARGETS qt_leetcode_note
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(qt_leetcode_note)
endif()
顺便照着写一个powershell脚本编译,等下写bash脚本的时候可以参考下
$build_dir = "./build"
$install_dir = "./install"
$cmake_prefix_path = "C:/Qt/5.15.2/mingw81_64"
if (Test-Path $build_dir) {
Remove-Item -LiteralPath $build_dir -Force -Recurse
}
if (Test-Path $install_dir) {
Remove-Item -LiteralPath $install_dir -Force -Recurse
}
mkdir $build_dir
mkdir $install_dir
cd $build_dir
cmake "-DCMAKE_GENERATOR:STRING=Ninja" "-DCMAKE_BUILD_TYPE:STRING=Release" "-DCMAKE_MAKE_PROGRAM=ninja.exe" "-DCMAKE_PREFIX_PATH:PATH=$cmake_prefix_path" "-DCMAKE_INSTALL_PREFIX=../$install_dir" ..
ninja -j4
ninja install
cd ..
编译完成后这个小窗口程序是这样的:

首先jenkins -> nodes -> new node, 拿到启动node的命令

然后在linux端配置启动时链接jenkins:
#!/bin/bash -ex
work_dir=$PWD
#java
sudo apt update
sudo apt install default-jre -y
#java bin
wget http://atian.icu:8080/jnlpJars/agent.jar -O ~/Downloads/agent.jar
#systemd
loginctl enable-linger pi
mkdir -p ~/.config/systemd/user/
cp -f ./systemd/jenkins.service ~/.config/systemd/user/
systemctl --user enable jenkins
echo "vim ~/.config/systemd/user/jenkins.service & reboot"
其中jenkins.service文件的内容需要手动改一下
[Unit]
Description=Jenkins Node Deamon
[Service]
ExecStart=/usr/bin/java -jar /home/pi/Downloads/agent.jar -jnlpUrl http://xxxxxxxxxxxxx -secret xxxxxxxx -workDir "/home/pi/jenkins"
Restart=always
RestartSec=60
[Install]
WantedBy=default.target
默认的源好像没有qt5-default,先下个cmake。编一下qt工程提示缺哪个找哪个。
#!/bin/bash -ex
work_dir=$PWD
sudo apt update
sudo apt install cmake -y
sudo apt install qtbase5-dev-tools -y
sudo apt install qtbase5-dev -y
sudo apt install qttools5-dev -y
编译成功后所有的环境就ok啦,程序打开是这个样子的:

现在手动在任意一边编译代码都能通过了,跨平台功能达成!
随后把一切串起来,写个pipeline让每次merge代码都会自动触发
pipeline {
agent{
node ('rp4')
}
options {
timeout(time: 10, unit: "MINUTES")
}
stages {
stage('build') {
steps {
git credentialsId: 'gitee', url: 'https://gitee.com/yongtian/qt_leetcode_note.git'
sh('./script/build_raspbian.sh')
}
}
}
post {
unsuccessful {
emailext body: '''${SCRIPT, template="groovy-html.template"}''',
subject: '$DEFAULT_SUBJECT',
to: '$DEFAULT_RECIPIENTS'
}
}
}
Happy Codding!