3、持续集成初探:Jenkins 安装与第一个自动化构建任务
说到持续集成,我脑子里第一个蹦出来的工具就是 Jenkins。说实话,这玩意儿在嵌入式圈子里有点被低估了。很多人觉得 Jenkins 是互联网后端用的,跟单片机、RTOS 不沾边。但我在几个量产项目里试过之后,发现它简直是嵌入式团队的「救星」。
为什么这么说?你想想看,嵌入式开发最头疼的是什么?编译环境不一致、固件版本混乱、手动烧录容易出错。Jenkins 能把这些痛点全给管起来。今天我们就从零开始,把 Jenkins 装好,跑通第一个自动化构建任务。
3.1 Jenkins 是什么?为什么嵌入式要用它?
Jenkins 是一个开源的自动化服务器。说白了,它就是个「调度中心」。你告诉它什么时候该干什么活,它就会按时按点去执行。比如每天凌晨自动拉代码、编译、跑测试、打包固件。
我在一个车载项目里遇到过这种情况:团队 5 个人,每人本地编译环境都不一样。有人用 GCC 9,有人用 GCC 11,结果同样的代码,有人编译通过,有人报错。后来我把 Jenkins 搭起来,统一了编译环境,这种问题再也没出现过。
3.2 安装 Jenkins:两种主流方式
安装 Jenkins 其实不复杂。我个人习惯用 Docker 部署,干净利落,想换版本也方便。但如果你对 Docker 不熟,直接用系统包管理器安装也行。
方式一:Docker 安装(推荐)
前提是你已经装好了 Docker。没装的话先去官网下个 Docker Desktop,Windows/Mac/Linux 都支持。
# 拉取 Jenkins 镜像(LTS 长期支持版)
docker pull jenkins/jenkins:lts
# 启动容器
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
启动后,打开浏览器访问 http://localhost:8080。第一次进入会让你输入初始密码。
# 查看初始密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
jenkins_home 挂载到宿主机的一个固定目录,比如 /data/jenkins。这样即使容器挂了,配置和任务都不会丢。
方式二:直接安装(Linux 为例)
如果你不想用 Docker,直接在 Ubuntu 上装也很简单。
# 添加 Jenkins 源
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
# 安装
sudo apt update
sudo apt install jenkins
# 启动服务
sudo systemctl start jenkins
sudo systemctl enable jenkins
安装完成后,同样访问 http://localhost:8080。初始密码在 /var/lib/jenkins/secrets/initialAdminPassword 里。
jenkins 用户运行。如果你需要访问 USB 设备(比如烧录器),记得把 jenkins 用户加到 dialout 组里。我曾经因为这个折腾了半天,烧录器死活连不上。
3.3 初始化配置:插件与管理员
第一次登录后,Jenkins 会引导你安装插件。这里我建议选「安装推荐的插件」,省心。等后面有需要再单独装。
插件安装完,创建管理员账号。记住这个账号密码,后面所有操作都靠它。
嗯,这里要注意:如果你是在公司内网用,建议把 Jenkins 的端口改成 8081 或者别的,避免跟其他服务冲突。我遇到过 Jenkins 和 Tomcat 抢 8080 端口的情况,挺尴尬的。
3.4 第一个自动化构建任务:编译嵌入式固件
好,环境搭好了,我们来干点正事。创建一个「自由风格」的任务,让它帮我们自动编译一个嵌入式项目。
步骤 1:创建任务
- 点击「新建任务」
- 输入任务名称,比如
firmware-build - 选择「自由风格项目」
- 点击确定
步骤 2:配置源码管理
在任务配置页面,找到「源码管理」部分,选择 Git。填入你的仓库地址。如果你的仓库是私有的,还需要添加凭据。
Repository URL: https://github.com/your-org/your-firmware.git
Branches to build: */main
步骤 3:配置构建触发器
这里我推荐两种方式:
- 定时构建: 比如每天凌晨 2 点自动编译一次
- 轮询 SCM: 每隔几分钟检查一次代码仓库,有变化就触发构建
定时构建的语法跟 Linux 的 cron 类似:
# 每天凌晨 2 点执行
H 2 * * *
轮询 SCM 的写法:
# 每 5 分钟检查一次
H/5 * * * *
步骤 4:配置构建环境
嵌入式编译通常需要交叉编译工具链。你需要在 Jenkins 所在的机器上装好工具链,然后在构建环境里配置环境变量。
在「构建环境」部分,勾选「Add timestamps to the Console Output」。这个很有用,能帮你定位编译耗时。
步骤 5:添加构建步骤
点击「增加构建步骤」,选择「执行 shell」。然后输入你的编译命令。
#!/bin/bash
# 进入项目目录
cd $WORKSPACE
# 清理之前的编译产物
make clean
# 开始编译
make all
# 如果编译成功,打包固件
if [ $? -eq 0 ]; then
tar -czf firmware.tar.gz build/
echo "编译成功,固件已打包"
else
echo "编译失败,请检查日志"
exit 1
fi
步骤 6:保存并运行
点击保存。回到任务页面,点击「立即构建」。你会看到构建队列里出现一个任务,点击进去就能看到实时控制台输出。
第一次构建可能会慢一些,因为要拉代码、下载依赖。后面就快了。
3.5 查看构建结果与产物
构建完成后,你会看到状态变成蓝色(成功)或红色(失败)。点击具体的构建号,可以查看:
- 控制台输出: 完整的编译日志
- 构建产物: 我们刚才打包的
firmware.tar.gz - 测试结果: 如果有单元测试,这里会显示通过率
**/*.tar.gz。
3.6 常见问题与解决
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 构建一直卡在「等待」状态 | 执行器数量不足 | 在系统管理 → 节点管理中增加执行器数量 |
| 编译报错:找不到头文件 | 工具链路径未配置 | 在构建步骤中 export PATH 或使用全局环境变量 |
| Git 拉取代码失败 | 凭据失效或网络问题 | 检查凭据是否正确,或改用 SSH 方式 |
| 构建产物为空 | 归档路径配置错误 | 检查「归档制品」中的通配符是否匹配实际文件路径 |
3.7 小结与下一步
到这,你已经完成了 Jenkins 的安装和第一个自动化构建任务。说白了,就是让 Jenkins 帮你自动拉代码、编译、打包。别小看这一步,它能让你的团队从「手动编译 → 手动打包 → 手动测试」的泥潭里解脱出来。
下一步,我会带你给这个流水线加上自动化测试和固件烧录。嗯,那才是真正让 Jenkins 发挥价值的地方。
记住,持续集成不是一蹴而就的。先跑通一个简单的编译任务,再慢慢往上加东西。我见过太多团队一上来就想搞全自动化,结果把自己搞崩溃了。
慢慢来,比较快。