1. 为什么需要自动化构建流水线作为一个写了十几年C/C的老码农我见过太多这样的场景每次代码更新后都要手动执行git pull、make、make test这一系列操作。更可怕的是不同开发者的环境配置还不一样经常出现在我机器上能编译的尴尬情况。这就是为什么我们需要Jenkins这样的自动化构建工具。自动化构建最直接的好处就是解放双手。想象一下你刚提交完代码Jenkins就自动帮你完成拉取、编译、测试、打包等一系列操作还能把结果通过邮件或即时通讯工具通知你。我在一个中型C项目上实测过使用自动化构建后团队每天的等待时间减少了至少2小时。对于C/C项目来说自动化构建尤为重要。因为C/C的编译过程相对复杂依赖管理也比较麻烦。通过Jenkins Pipeline我们可以把这些复杂的构建步骤用代码的形式固化下来确保每次构建的环境和流程完全一致。2. Jenkins环境准备2.1 基础环境安装首先需要准备一台Linux服务器作为Jenkins主机。我推荐使用CentOS 7或Ubuntu 20.04 LTS这样的稳定发行版。安装Java是必须的因为Jenkins本身就是个Java应用# CentOS sudo yum install java-1.8.0-openjdk-devel # Ubuntu sudo apt install openjdk-8-jdk验证Java安装是否成功java -version接下来下载并启动Jenkins。我建议使用war包方式运行这样最灵活wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war java -jar jenkins.war --httpPort8080第一次启动时会生成一个管理员密码记得保存好。打开浏览器访问http://你的服务器IP:8080按照向导完成初始设置。2.2 必要插件安装对于C/C项目这几个插件必不可少Pipeline核心插件支持流水线功能Git代码版本控制Cmake BuilderCMake项目支持Cppcheck静态代码分析Warnings Next Generation编译警告收集安装方法很简单在Jenkins管理界面找到插件管理搜索并安装即可。我建议先把这些插件装好后面用起来会顺手很多。3. 创建第一个Pipeline项目3.1 基础Pipeline脚本在Jenkins首页点击新建任务选择Pipeline给项目起个名字比如cpp-demo。在配置页面找到Pipeline部分我们先写个最简单的脚本pipeline { agent any stages { stage(Hello) { steps { echo Hello World } } } }点击保存后立即构建在控制台输出中就能看到Hello World了。这个简单的例子展示了Pipeline的基本结构pipeline定义整个流水线agent指定在哪台机器上执行stages包含多个stagestage代表一个构建阶段steps具体的执行步骤3.2 集成Git代码库现在我们来点实际的让Pipeline能够拉取代码。假设你有一个托管在GitLab上的C项目pipeline { agent any stages { stage(Checkout) { steps { git branch: main, credentialsId: your-git-credential-id, url: http://your-gitlab-server/your-project.git } } } }这里有几个关键点需要注意credentialsId需要在Jenkins的凭据管理中提前配置好url要换成你实际的Git仓库地址branch指定要拉取的分支构建成功后你可以在Jenkins的工作空间看到拉取下来的代码。我在第一次配置时遇到过权限问题后来发现是Git凭据没配好所以这里要特别注意。4. C/C项目自动化编译4.1 编译环境准备C/C项目通常需要一些额外的工具链。以CMake项目为例我们需要确保服务器上安装了这些工具# 安装编译工具链 sudo yum install gcc gcc-c make # 安装CMake建议使用最新版 wget https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-x86_64.tar.gz tar -xzvf cmake-3.22.1-linux-x86_64.tar.gz sudo mv cmake-3.22.1-linux-x86_64 /opt/cmake echo export PATH/opt/cmake/bin:$PATH ~/.bashrc source ~/.bashrc验证安装cmake --version gcc --version4.2 编写编译Stage现在我们可以扩展Pipeline加入编译阶段pipeline { agent any stages { stage(Checkout) { steps { git branch: main, credentialsId: your-git-credential-id, url: http://your-gitlab-server/your-project.git } } stage(Build) { steps { sh mkdir -p build cd build cmake .. make -j4 } } } }这个脚本做了以下几件事创建一个build目录如果不存在进入build目录执行cmake生成Makefile使用4个线程并行编译-j4参数在实际项目中你可能还需要处理一些特殊情况。比如我在一个项目中发现需要先安装某些依赖库可以在Build阶段前加一个Preparation阶段stage(Preparation) { steps { sh sudo apt install -y libssl-dev libboost-all-dev } }5. 测试与质量检查5.1 自动化测试好的CI流程必须包含自动化测试。假设你的项目使用Google Test框架可以这样添加测试阶段stage(Test) { steps { sh cd build ctest --output-on-failure } post { always { junit build/**/test-results.xml } } }这里使用了ctest来运行测试并通过post always确保无论测试成功与否都会收集测试结果。junit步骤会把测试结果集成到Jenkins的测试报告中方便后续分析。5.2 静态代码分析对于C/C项目静态代码分析能帮助发现潜在问题。我们可以使用cppcheck工具stage(Static Analysis) { steps { sh cppcheck --enableall --projectbuild/compile_commands.json } post { always { recordIssues tools: [cppCheck()] } } }这个配置会运行cppcheck进行全面检查使用compile_commands.json由CMake生成确保分析正确的编译选项通过recordIssues将问题记录到Jenkins中我在实际项目中发现静态分析最好在编译之后进行因为需要compile_commands.json文件。6. 高级Pipeline技巧6.1 参数化构建有时候我们需要在构建时传入一些参数比如编译类型Debug/Release。这可以通过parameters实现pipeline { agent any parameters { choice(name: BUILD_TYPE, choices: [Debug, Release], description: 选择构建类型) } stages { stage(Build) { steps { sh mkdir -p build cd build cmake -DCMAKE_BUILD_TYPE${params.BUILD_TYPE} .. make -j4 } } } }这样每次构建时都会弹出选项让你选择构建类型。我在一个性能敏感的项目中就经常切换Debug和Release模式进行测试。6.2 并行执行如果项目中有独立的测试套件可以并行执行以节省时间stage(Parallel Tests) { parallel { stage(Unit Test) { steps { sh cd build ./unit_tests } } stage(Integration Test) { steps { sh cd build ./integration_tests } } } }这个技巧在我负责的一个大型项目中特别有用将整体构建时间从45分钟缩短到了30分钟。6.3 错误处理与重试网络问题可能导致代码拉取失败我们可以增加重试机制stage(Checkout) { steps { retry(3) { git branch: main, url: http://your-gitlab-server/your-project.git } } }对于不稳定的测试也可以设置重试stage(Flaky Test) { steps { retry(3) { sh ./flaky_test } } }7. 实战中的经验分享在实际项目中配置Jenkins Pipeline时我踩过不少坑这里分享几个最有价值的经验保持构建环境干净每次构建前清理工作空间避免残留文件影响结果。可以在Pipeline开头加一个Clean阶段stage(Clean) { steps { cleanWs() } }合理使用缓存有些依赖下载很耗时可以通过缓存加速。比如C的Conan包stage(Restore Cache) { steps { sh if [ -d $HOME/.conan ]; then echo Using cached Conan packages else conan install .. fi } }日志管理大型项目构建日志可能很大建议按阶段存档post { always { archiveArtifacts artifacts: build/**/*.log, allowEmptyArchive: true } }资源监控在Pipeline中加入资源监控帮助优化构建stage(Build) { steps { sh /usr/bin/time -v make -j4 } }通知机制构建失败时及时通知团队post { failure { emailext body: 构建失败请检查: ${BUILD_URL}, subject: 构建失败: ${JOB_NAME}, to: teamexample.com } }最后提醒一点Pipeline脚本最好也放在版本控制中这样就能实现Pipeline as Code的理念。我现在的做法是在项目根目录放一个Jenkinsfile然后在Jenkins项目中配置从SCM读取Pipeline脚本这样任何构建流程的变更都会经过代码评审。
Jenkins实战指南(一) - 打造C/C++项目自动化构建流水线
发布时间:2026/5/16 5:06:32
1. 为什么需要自动化构建流水线作为一个写了十几年C/C的老码农我见过太多这样的场景每次代码更新后都要手动执行git pull、make、make test这一系列操作。更可怕的是不同开发者的环境配置还不一样经常出现在我机器上能编译的尴尬情况。这就是为什么我们需要Jenkins这样的自动化构建工具。自动化构建最直接的好处就是解放双手。想象一下你刚提交完代码Jenkins就自动帮你完成拉取、编译、测试、打包等一系列操作还能把结果通过邮件或即时通讯工具通知你。我在一个中型C项目上实测过使用自动化构建后团队每天的等待时间减少了至少2小时。对于C/C项目来说自动化构建尤为重要。因为C/C的编译过程相对复杂依赖管理也比较麻烦。通过Jenkins Pipeline我们可以把这些复杂的构建步骤用代码的形式固化下来确保每次构建的环境和流程完全一致。2. Jenkins环境准备2.1 基础环境安装首先需要准备一台Linux服务器作为Jenkins主机。我推荐使用CentOS 7或Ubuntu 20.04 LTS这样的稳定发行版。安装Java是必须的因为Jenkins本身就是个Java应用# CentOS sudo yum install java-1.8.0-openjdk-devel # Ubuntu sudo apt install openjdk-8-jdk验证Java安装是否成功java -version接下来下载并启动Jenkins。我建议使用war包方式运行这样最灵活wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war java -jar jenkins.war --httpPort8080第一次启动时会生成一个管理员密码记得保存好。打开浏览器访问http://你的服务器IP:8080按照向导完成初始设置。2.2 必要插件安装对于C/C项目这几个插件必不可少Pipeline核心插件支持流水线功能Git代码版本控制Cmake BuilderCMake项目支持Cppcheck静态代码分析Warnings Next Generation编译警告收集安装方法很简单在Jenkins管理界面找到插件管理搜索并安装即可。我建议先把这些插件装好后面用起来会顺手很多。3. 创建第一个Pipeline项目3.1 基础Pipeline脚本在Jenkins首页点击新建任务选择Pipeline给项目起个名字比如cpp-demo。在配置页面找到Pipeline部分我们先写个最简单的脚本pipeline { agent any stages { stage(Hello) { steps { echo Hello World } } } }点击保存后立即构建在控制台输出中就能看到Hello World了。这个简单的例子展示了Pipeline的基本结构pipeline定义整个流水线agent指定在哪台机器上执行stages包含多个stagestage代表一个构建阶段steps具体的执行步骤3.2 集成Git代码库现在我们来点实际的让Pipeline能够拉取代码。假设你有一个托管在GitLab上的C项目pipeline { agent any stages { stage(Checkout) { steps { git branch: main, credentialsId: your-git-credential-id, url: http://your-gitlab-server/your-project.git } } } }这里有几个关键点需要注意credentialsId需要在Jenkins的凭据管理中提前配置好url要换成你实际的Git仓库地址branch指定要拉取的分支构建成功后你可以在Jenkins的工作空间看到拉取下来的代码。我在第一次配置时遇到过权限问题后来发现是Git凭据没配好所以这里要特别注意。4. C/C项目自动化编译4.1 编译环境准备C/C项目通常需要一些额外的工具链。以CMake项目为例我们需要确保服务器上安装了这些工具# 安装编译工具链 sudo yum install gcc gcc-c make # 安装CMake建议使用最新版 wget https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-x86_64.tar.gz tar -xzvf cmake-3.22.1-linux-x86_64.tar.gz sudo mv cmake-3.22.1-linux-x86_64 /opt/cmake echo export PATH/opt/cmake/bin:$PATH ~/.bashrc source ~/.bashrc验证安装cmake --version gcc --version4.2 编写编译Stage现在我们可以扩展Pipeline加入编译阶段pipeline { agent any stages { stage(Checkout) { steps { git branch: main, credentialsId: your-git-credential-id, url: http://your-gitlab-server/your-project.git } } stage(Build) { steps { sh mkdir -p build cd build cmake .. make -j4 } } } }这个脚本做了以下几件事创建一个build目录如果不存在进入build目录执行cmake生成Makefile使用4个线程并行编译-j4参数在实际项目中你可能还需要处理一些特殊情况。比如我在一个项目中发现需要先安装某些依赖库可以在Build阶段前加一个Preparation阶段stage(Preparation) { steps { sh sudo apt install -y libssl-dev libboost-all-dev } }5. 测试与质量检查5.1 自动化测试好的CI流程必须包含自动化测试。假设你的项目使用Google Test框架可以这样添加测试阶段stage(Test) { steps { sh cd build ctest --output-on-failure } post { always { junit build/**/test-results.xml } } }这里使用了ctest来运行测试并通过post always确保无论测试成功与否都会收集测试结果。junit步骤会把测试结果集成到Jenkins的测试报告中方便后续分析。5.2 静态代码分析对于C/C项目静态代码分析能帮助发现潜在问题。我们可以使用cppcheck工具stage(Static Analysis) { steps { sh cppcheck --enableall --projectbuild/compile_commands.json } post { always { recordIssues tools: [cppCheck()] } } }这个配置会运行cppcheck进行全面检查使用compile_commands.json由CMake生成确保分析正确的编译选项通过recordIssues将问题记录到Jenkins中我在实际项目中发现静态分析最好在编译之后进行因为需要compile_commands.json文件。6. 高级Pipeline技巧6.1 参数化构建有时候我们需要在构建时传入一些参数比如编译类型Debug/Release。这可以通过parameters实现pipeline { agent any parameters { choice(name: BUILD_TYPE, choices: [Debug, Release], description: 选择构建类型) } stages { stage(Build) { steps { sh mkdir -p build cd build cmake -DCMAKE_BUILD_TYPE${params.BUILD_TYPE} .. make -j4 } } } }这样每次构建时都会弹出选项让你选择构建类型。我在一个性能敏感的项目中就经常切换Debug和Release模式进行测试。6.2 并行执行如果项目中有独立的测试套件可以并行执行以节省时间stage(Parallel Tests) { parallel { stage(Unit Test) { steps { sh cd build ./unit_tests } } stage(Integration Test) { steps { sh cd build ./integration_tests } } } }这个技巧在我负责的一个大型项目中特别有用将整体构建时间从45分钟缩短到了30分钟。6.3 错误处理与重试网络问题可能导致代码拉取失败我们可以增加重试机制stage(Checkout) { steps { retry(3) { git branch: main, url: http://your-gitlab-server/your-project.git } } }对于不稳定的测试也可以设置重试stage(Flaky Test) { steps { retry(3) { sh ./flaky_test } } }7. 实战中的经验分享在实际项目中配置Jenkins Pipeline时我踩过不少坑这里分享几个最有价值的经验保持构建环境干净每次构建前清理工作空间避免残留文件影响结果。可以在Pipeline开头加一个Clean阶段stage(Clean) { steps { cleanWs() } }合理使用缓存有些依赖下载很耗时可以通过缓存加速。比如C的Conan包stage(Restore Cache) { steps { sh if [ -d $HOME/.conan ]; then echo Using cached Conan packages else conan install .. fi } }日志管理大型项目构建日志可能很大建议按阶段存档post { always { archiveArtifacts artifacts: build/**/*.log, allowEmptyArchive: true } }资源监控在Pipeline中加入资源监控帮助优化构建stage(Build) { steps { sh /usr/bin/time -v make -j4 } }通知机制构建失败时及时通知团队post { failure { emailext body: 构建失败请检查: ${BUILD_URL}, subject: 构建失败: ${JOB_NAME}, to: teamexample.com } }最后提醒一点Pipeline脚本最好也放在版本控制中这样就能实现Pipeline as Code的理念。我现在的做法是在项目根目录放一个Jenkinsfile然后在Jenkins项目中配置从SCM读取Pipeline脚本这样任何构建流程的变更都会经过代码评审。