4、第一个Yocto构建:初始化构建环境、配置本地构建(local.conf)、运行BitBake构建最小镜像(core-image-minimal)

好,到了真正动手的时候了。

前面几章我们把Yocto的体系结构、术语、下载都捋了一遍。现在,我们要做第一个真正的构建——用BitBake编译出一个core-image-minimal。这个镜像很小,但五脏俱全,是验证你的Yocto环境是否正常工作的最佳起点。

我个人习惯把这一步叫做“点火测试”。如果这一步能跑通,后面移植BSP、添加软件包就只是时间问题了。

4.1 初始化构建环境

还记得我们之前用git clone拉下来的Poky仓库吗?里面有个脚本叫oe-init-build-env,它就是整个构建环境的入口。

核心命令:

cd ~/yocto/poky
source oe-init-build-env build

执行完这条命令,会发生几件事:

  • 在当前目录下创建一个build文件夹(如果不存在的话)
  • 自动cd进这个build目录
  • 设置一系列环境变量,比如TEMPLATECONF、BBPATH、BUILDDIR
  • 从meta-poky/conf复制默认的local.conf和bblayers.conf到build/conf

嗯,这里要注意:source这个操作不是一次性的。你每次打开新终端想用BitBake,都得先跑一遍source oe-init-build-env。我刚开始学的时候经常忘记,然后直接敲bitbake core-image-minimal,结果报错“command not found”。

小技巧: 我习惯在~/.bashrc里加一个别名:

alias yocto='cd ~/yocto/poky && source oe-init-build-env build'

这样每次只需要敲yocto三个字母,环境就准备好了。

4.2 理解构建目录结构

初始化完成后,你的build目录下会生成这些关键文件:

文件/目录 作用
conf/local.conf 本地构建配置,定义目标机器、并行任务数、下载目录等
conf/bblayers.conf 层配置文件,告诉BitBake去哪里找meta-*层
tmp/ 构建过程中的临时文件、工作目录、最终镜像输出
downloads/ 所有源码包的缓存目录,避免重复下载
sstate-cache/ 共享状态缓存,加速后续构建

说白了,build目录就是你的“施工现场”。所有原材料(源码)、半成品(编译中间产物)、成品(镜像文件)都在这里。

4.3 配置local.conf——最关键的一步

默认生成的local.conf有很多注释掉的选项。我们需要根据实际硬件平台修改几个关键参数。我以qemuarm64为例,这是最通用的模拟器目标。

避坑指南: 我曾经在一个项目里直接用了默认的local.conf,结果编译出来的镜像在目标板上起不来。查了两天才发现是MACHINE变量没改,编译的是qemux86-64的镜像。所以第一步,先确认你的目标机器。

4.3.1 设置MACHINE变量

# 找到这一行,去掉注释并修改
MACHINE ?= "qemuarm64"

这个变量决定了BitBake为哪个硬件平台编译。常见的值有:

  • qemuarm64 —— ARMv8 64位模拟器
  • qemux86-64 —— x86_64模拟器
  • raspberrypi4-64 —— 树莓派4B(需要额外meta-raspberrypi层)
  • beaglebone-yocto —— BeagleBone Black

4.3.2 设置并行编译数

# 根据你的CPU核心数调整
BB_NUMBER_THREADS = "8"
PARALLEL_MAKE = "-j 8"

这两个参数控制并行编译的力度。我建议设置为CPU物理核心数的1.5到2倍。比如4核8线程的CPU,设成-j 8比较合理。设太大反而会因为IO瓶颈变慢。

4.3.3 设置下载目录和缓存目录

# 共享下载目录,避免每个构建目录都下载一遍
DL_DIR ?= "/home/你的用户名/yocto/downloads"

# 共享状态缓存目录
SSTATE_DIR ?= "/home/你的用户名/yocto/sstate-cache"

我个人强烈建议把DL_DIR和SSTATE_DIR放到构建目录外面。为什么?因为如果你删掉build目录重新构建,之前下载的几百兆源码包和编译缓存就全没了。放在外面可以跨项目复用。

4.3.4 其他常用配置

# 设置目标系统的包管理器格式(rpm/deb/ipk)
PACKAGE_CLASSES ?= "package_rpm"

# 设置rootfs的额外空间(单位MB)
IMAGE_ROOTFS_EXTRA_SPACE = "1048576"

# 开启用户态网络(用于QEMU)
QB_NETWORK_DEVICE ?= "-netdev user,id=net0,hostfwd=tcp::2222-:22"

我的经验: 第一次构建时,建议把BB_NUMBER_THREADS设小一点(比如4),等确认环境没问题再调大。因为如果某个recipe编译失败,并行任务太多会导致日志混乱,很难定位问题。

4.4 运行BitBake构建最小镜像

配置好local.conf,就可以开始构建了。确保你已经source了环境,然后在build目录下执行:

bitbake core-image-minimal

这个命令会触发一系列动作:

  1. BitBake解析所有.bb和.bbappend文件
  2. 生成依赖关系树
  3. 按照依赖顺序依次执行fetch、unpack、patch、configure、compile、install、package、image等任务
  4. 最终在tmp/deploy/images/qemuarm64/下生成镜像文件

第一次构建时间会比较长,通常30分钟到2小时不等,取决于你的网络速度和CPU性能。BitBake会在终端实时打印进度,像这样:

Parsing recipes: 100% |####################################| Time: 0:00:15
Initialising tasks: 100% |#################################| Time: 0:00:02
Loading cache: 100% |######################################| Time: 0:00:01
Checking sstate mirror object: 100% |######################| Time: 0:00:01
Executing Tasks (1 of 187): linux-yocto_6.6.bb:do_fetch 0%

常见问题: 如果构建过程中断(比如网络超时、磁盘空间不足),不要慌。重新执行bitbake core-image-minimal,BitBake会从断点继续,不会从头开始。这是Yocto最人性化的设计之一。

4.5 构建成功后的产物

构建完成后,在tmp/deploy/images/qemuarm64/目录下你会看到:

文件 说明
core-image-minimal-qemuarm64.rootfs.ext4 根文件系统镜像(ext4格式)
core-image-minimal-qemuarm64.rootfs.tar.bz2 根文件系统的压缩包
core-image-minimal-qemuarm64.qemuboot.conf QEMU启动配置文件
zImage--6.6.21+git0+...r0-qemuarm64-...bin Linux内核镜像
Image--6.6.21+git0+...r0-qemuarm64-...bin ARM64内核镜像(如果目标支持)

你可以用QEMU直接启动这个镜像验证:

runqemu qemuarm64 nographic

看到登录提示符后,输入root(默认无密码),你就成功进入了自己构建的嵌入式Linux系统。

4.6 本章知识结构图

下面这张图总结了从初始化环境到构建成功的完整流程:

第一个Yocto构建流程 1. 初始化环境 source oe-init-build-env 2. 配置local.conf MACHINE / 并行数 / 缓存 3. 运行BitBake bitbake core-image-minimal 4. 解析Recipes 解析依赖树 5. 执行任务队列 fetch → patch → compile 6. 生成镜像 rootfs + kernel + dtb 7. 验证启动 runqemu qemuarm64 nographic 关键输出文件 • tmp/deploy/images/qemuarm64/core-image-minimal-qemuarm64.rootfs.ext4 • tmp/deploy/images/qemuarm64/zImage-6.6.21+git... • tmp/deploy/images/qemuarm64/core-image-minimal-qemuarm64.qemuboot.conf

4.7 常见问题与排查

第一次构建很少一帆风顺。我整理了几个高频问题:

问题现象 可能原因 解决方法
do_fetch失败 网络不通或源码地址变更 检查代理设置,或手动下载源码放到DL_DIR
do_compile报错 缺少系统依赖包 安装gcc、make、flex、bison等
磁盘空间不足 tmp目录占用过大 清理tmp或挂载大容量分区到build
QEMU启动黑屏 缺少图形库或终端配置错误 使用nographic模式,或安装sdl库

我的排查习惯: 遇到错误先看最后几行日志,找到ERROR:开头的行。然后去tmp/work/对应recipe的工作目录下看temp/log.do_*文件,那里有完整的编译输出。别在终端里翻几千行日志,效率太低。

好了,到这里你已经完成了第一个Yocto构建。虽然只是最小镜像,但整个流程——初始化、配置、构建、验证——和后面移植BSP、定制发行版是完全一致的。这个基础打牢了,后面的路就好走了。