4. 构建第一个镜像:配置构建环境、理解核心配置、运行 bitbake

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

前面我们聊了 Yocto 是什么,也搭好了环境。现在,咱们要干一件实实在在的事——构建第一个镜像。

这一步,说白了就是让 Yocto 真正跑起来。我刚开始接触 Yocto 时,觉得这一步最简单,不就是跑几个命令嘛。结果第一次就栽了跟头——环境没配好,编译到一半报错,找问题找了半天。嗯,这里面的门道,咱们一个一个说清楚。

4.1 配置构建环境:oe-init-build-env 到底干了什么?

你进入 Poky 目录后,第一件事就是执行:

source oe-init-build-env build

这个命令,是 Yocto 项目的“入场券”。

它做了三件关键的事:

  • 设置环境变量——把 TEMPLATECONF、BUILDDIR 等几十个变量一次性注入当前 shell。
  • 创建构建目录——如果你指定的目录(比如 build)不存在,它会自动创建。
  • 生成初始配置文件——把 meta-poky/conf/templates/default 下的模板文件,复制到你的构建目录里。

我个人习惯,每次开新终端都重新 source 一遍。别嫌麻烦,这能保证环境干净,不会出现“上次能编这次不行”的玄学问题。

小技巧: 如果你不想每次手动 source,可以在 ~/.bashrc 里加个 alias:
alias yocto-setup='cd ~/poky && source oe-init-build-env build'

执行完后,你会看到终端提示符变了,多了个 build 前缀。同时,目录下多了个 build/conf 文件夹。里面躺着两个最重要的文件:local.conf 和 bblayers.conf。

4.2 理解 local.conf:你的构建“控制面板”

打开 build/conf/local.conf,你会看到一堆注释和配置项。别被吓到,核心参数其实就几个。

我把它比作汽车的仪表盘——你不需要动所有旋钮,但有几个必须调对。

参数 作用 我的建议值
MACHINE 指定目标硬件平台 qemux86-64(初学者首选)
DL_DIR 源码下载缓存目录 指向一个共享目录,避免重复下载
SSTATE_DIR 共享状态缓存目录 同样指向共享目录,加速二次构建
BB_NUMBER_THREADS BitBake 并行任务数 CPU 核心数 + 1 或 2
PARALLEL_MAKE make 编译并行数 CPU 核心数

举个例子,我的笔记本是 8 核的,通常会这样配:

MACHINE ?= "qemux86-64"
DL_DIR ?= "/home/yocto/downloads"
SSTATE_DIR ?= "/home/yocto/sstate-cache"
BB_NUMBER_THREADS = "10"
PARALLEL_MAKE = "-j 8"
注意: 别把 BB_NUMBER_THREADS 设得太大。我曾经设成 32,结果内存爆了,系统直接卡死。建议不超过物理核心数的 1.5 倍。

还有一个容易被忽略的参数——PACKAGE_CLASSES。默认是 rpm,但我建议改成 package_ipk。为什么?ipk 包体积小,安装快,调试时省时间。

PACKAGE_CLASSES ?= "package_ipk"

4.3 理解 bblayers.conf:告诉 Yocto 去哪里找“菜谱”

打开 bblayers.conf,内容很简单,就是一个 BBLAYERS 变量,里面列了一堆路径。

每个路径,就是一个 Layer(层)。Layer 里放着各种 Recipe(配方)——也就是告诉 BitBake 怎么下载、配置、编译、打包某个软件。

默认情况下,它长这样:

BBLAYERS ?= " \
  /home/yocto/poky/meta \
  /home/yocto/poky/meta-poky \
  /home/yocto/poky/meta-yocto-bsp \
  " 

这三个层分别负责:

  • meta——核心层,包含 OpenEmbedded 的基础配方和类。
  • meta-poky——Poky 发行版配置层,定义默认策略。
  • meta-yocto-bsp——板级支持包层,提供 QEMU 等模拟器的硬件支持。

你想想看,如果以后你要加一个自定义的硬件平台,或者集成某个第三方库,只需要在 BBLAYERS 里加上对应的层路径就行。这就是 Yocto 的模块化思想——层就是积木,想搭什么就拼什么。

核心原则: 永远不要修改 meta 核心层里的配方。想覆盖某个行为,就在自己的层里用 .bbappend 文件。这是 Yocto 社区的黄金法则。

4.4 运行 bitbake core-image-minimal

配置好了,就该真刀真枪地干了。

在 build 目录下,执行:

bitbake core-image-minimal

这个命令,会触发 Yocto 的整个构建流水线。我把它画成一张图,方便你理解整个过程:

BitBake 构建流水线 BitBake 构建流水线(core-image-minimal) 解析配方(Recipe) 获取源码(Fetch) 配置 & 编译 打包(Packaging) 生成镜像(Image) 核心依赖 • DL_DIR:源码缓存 • SSTATE_DIR:编译缓存 • TMPDIR:临时文件 输出产物 • core-image-minimal-*.rootfs.ext4 • core-image-minimal-*.tar.bz2

第一次构建,时间会比较长。我自己的机器(8 核、16G 内存)大概需要 30-40 分钟。别急,去喝杯咖啡,或者看看文档。Yocto 在后台会做很多事:下载源码、打补丁、配置、编译、打包……每一步都有日志输出。

如果一切顺利,最后你会看到:

NOTE: Tasks Summary: Attempted 1234 tasks of which 0 didn't need to be rerun and all succeeded.

看到这个,恭喜你——第一个镜像构建成功了!

镜像文件在 build/tmp/deploy/images/qemux86-64/ 目录下。你可以用 QEMU 直接启动它:

runqemu qemux86-64

一个迷你的 Linux 系统就会在窗口中启动。虽然只有命令行,但五脏俱全——内核、文件系统、网络栈,全都有。

避坑指南: 如果构建过程中断,重新执行 bitbake core-image-minimal 即可。Yocto 会从断点继续,不会从头开始。这就是 SSTATE 缓存的好处。

嗯,到这里,你已经亲手构建了第一个 Yocto 镜像。这个过程,说白了就是 Yocto 的“Hello World”。后面所有的定制化开发,都是在这个基础上做加法。