2. 环境搭建:依赖包安装、获取Buildroot源码、首次编译体验
说实话,环境搭建这一步,看着简单,但坑不少。我见过太多新手卡在「装完依赖编译报错」这个环节,一卡就是半天。咱们这节课,就把这条路趟平了再走。
2.1 宿主机的准备工作
先说说宿主机。我个人的习惯是用 Ubuntu 20.04 LTS 或 22.04 LTS。为什么?因为Buildroot的CI测试主要跑在这两个版本上,兼容性最好。你用Debian、Fedora也行,但遇到奇怪的问题时,社区能给你的帮助就少一些。
2.2 安装依赖包
Buildroot对宿主机的依赖其实不多,但一个都不能少。少了哪个,编译到一半就给你报错,那才叫难受。
直接上命令,一行搞定:
sudo apt update
sudo apt install -y \
git \
wget \
curl \
cpio \
unzip \
bc \
gcc \
g++ \
make \
libncurses-dev \
flex \
bison \
libssl-dev \
rsync \
file \
python3 \
python3-pip \
patchelf
这里我重点说几个容易漏的:
- libncurses-dev:没有它,
make menuconfig那个图形界面就起不来。 - flex 和 bison:Buildroot内部有些配置解析器依赖它们,缺了会报语法错误。
- patchelf:这个工具用来修改ELF文件的RPATH,做库裁剪时特别有用。我一开始没装,结果编译某些包时链接器找不到库,折腾了半天才发现是它没装。
python3-pip 可能装不上。建议直接升级系统,别在这上面浪费时间。我曾经在18.04上硬扛,结果为了装一个Python模块,手动编译了半小时,最后发现升级系统只要10分钟。
2.3 获取Buildroot源码
依赖装好了,接下来拿源码。我推荐用Git克隆,这样以后切换版本、打补丁都方便。
git clone https://git.busybox.net/buildroot
cd buildroot
克隆下来后,默认是在 master 分支上。但咱们做产品,最好用稳定版。怎么看稳定版?
git tag -l '2024.*' | sort -V
我个人习惯用 2024.02.x 或 2024.05.x 这种LTS版本。为什么?因为LTS版本会持续修复安全漏洞,而且社区维护周期长。你想想看,如果产品出货后,发现某个CVE需要修复,结果你用的是三个月前的快照版,那得多被动。
切换到稳定版:
git checkout 2024.02.3
git clone https://gitee.com/mirrors/buildroot.git。但注意,镜像可能比官方源晚一两天,不过不影响使用。
2.4 首次编译体验
源码到手了,咱们先别急着改配置。用默认配置编译一次,验证环境是否通。这一步叫「冒烟测试」。我每次搭建新环境,都会先跑一遍默认配置,确保工具链没问题。
Buildroot为很多开发板提供了默认配置。咱们拿 QEMU ARM64 的配置来演示,因为它在任何机器上都能跑,不需要真实硬件。
make qemu_aarch64_virt_defconfig
make
第一行命令会生成 .config 文件。第二行就是编译了。第一次编译时间比较长,取决于你的机器性能。我的笔记本(i7-12700H,32GB内存)大概需要15-20分钟。
编译过程中,你会看到屏幕上刷刷地滚日志。别慌,这是正常的。Buildroot会依次下载源码包、解压、配置、编译、安装。如果一切顺利,最后你会看到类似这样的输出:
>>> Generating root filesystem image rootfs.cpio
...
>>> Generating images
...
编译完成后,生成的镜像在 output/images/ 目录下:
| 文件 | 说明 |
|---|---|
rootfs.cpio |
根文件系统镜像(cpio格式) |
Image |
Linux内核镜像(未压缩) |
qemu.dtb |
设备树文件 |
start-qemu.sh |
启动QEMU的脚本 |
咱们直接用QEMU启动看看:
cd output/images/
./start-qemu.sh
如果看到QEMU窗口弹出来,并且系统启动到了登录提示符,那就说明环境搭建成功了。默认用户名是 root,没有密码。
Unable to download 之类的错误,多半是网络问题。Buildroot会从SourceForge、GitHub等地方下载源码包。在国内,有些站点被墙了。解决办法有两个:一是配置代理,二是用我前面提到的国内镜像源。我曾经在客户现场,网络只能访问内部仓库,最后手动把所有源码包下载下来,放到 dl/ 目录下才搞定。
2.5 理解编译产物
第一次编译成功后,咱们来拆解一下 output/ 目录的结构。这个目录是Buildroot的「工作台」,所有中间产物都在里面。
这四个目录各有各的用处:
- build/:每个软件包解压后,在这里编译。如果某个包编译失败,可以进到对应的目录里看
build.log,排查问题。 - host/:交叉编译工具链、主机工具(比如mkimage、genext2fs)都装在这里。这个目录可以复用,我经常把它打包,换到另一台机器上直接解压用,省去重新编译工具链的时间。
- images/:最终产物,包括内核、文件系统镜像、设备树、启动脚本。咱们做产品,最终交付的就是这个目录里的东西。
- target/:目标板的根文件系统目录。你可以进去看看,里面就是最终系统启动后的目录结构。注意,这个目录里的文件是「软链接版」,真正的文件在
build/里。
target/ 里改文件,因为下次 make 会被覆盖。正确的做法是修改 build/ 里对应包的源码,然后重新编译。我刚开始不懂,在 target/ 里改了半天,一重新编译全没了,气得不行。
2.6 清理与重新编译
编译过程中,难免会改配置、改源码。Buildroot提供了几种清理方式:
| 命令 | 清理范围 | 适用场景 |
|---|---|---|
make clean |
删除 output/build/ 下的所有编译产物 |
修改了某个包的源码,需要重新编译 |
make distclean |
删除整个 output/ 目录和 .config |
想从头开始,或者切换目标平台 |
make <package>-dirclean |
只删除指定包的编译目录 | 只修改了某个包,不想动其他的 |
我个人最常用的是 make <package>-dirclean。比如我只改了busybox的配置,那就执行 make busybox-dirclean,然后 make。这样只重新编译busybox,速度快很多。
make distclean。我有个同事,在服务器上跑了一周的编译,结果想清理一下某个包,手滑打成了 make distclean,然后...嗯,他那天加班到凌晨两点。