3. 获取源码:使用 repo 工具下载 Poky 和 Meta 层

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

上一章我们聊了 Yocto 的哲学和整体架构。这一章,咱们直接开干——把源码拉下来。

你可能会问:「不就是 git clone 吗?有什么好讲的?」

嗯,如果只是 clone 一个 Poky,确实简单。但实际项目里,你往往需要同时管理十几个甚至几十个 Git 仓库。这时候,repo 工具就派上用场了。

3.1 为什么需要 repo?

Yocto 项目本身由上百个独立仓库组成。Poky 只是其中一个「聚合仓库」。除此之外,还有各种 BSP(板级支持包)、软件层、工具链仓库。

手动一个一个 git clone?不现实。

repo 是 Google 为 Android 开发的一个仓库管理工具,后来被 Yocto 社区广泛采用。它的核心能力就一句话:用一个 manifest 文件,描述一堆仓库该从哪里拉、拉到哪个目录、切到哪个分支。

核心概念:repo 本身不存代码,它只是帮你批量执行 git 命令。你最终看到的,还是一个个独立的 Git 仓库。

3.2 安装 repo

安装 repo 很简单。我个人习惯把它放在 ~/bin 下:

mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

然后把 ~/bin 加到 PATH 里:

export PATH=$PATH:~/bin

你可以把这行加到 ~/.bashrc 或 ~/.zshrc 里,省得每次都要手动 export。

小提示:如果你在公司内网,或者网络不稳定,可以先把 repo 脚本下载到本地,然后离线使用。repo 脚本本身只有几百 KB,不依赖其他外部资源。

3.3 初始化 repo 工作区

接下来,我们创建一个工作目录,然后用 repo 初始化:

mkdir yocto-project
cd yocto-project
repo init -u https://git.yoctoproject.org/poky -b kirkstone

这里解释一下参数:

  • -u:指定 manifest 仓库的 URL。Poky 的 manifest 仓库里,记录了所有子仓库的地址和默认分支。
  • -b:指定分支。我用的是 kirkstone,这是 Yocto 4.0 的长期支持版本(LTS)。

执行完 repo init 后,你会看到类似这样的输出:

...
repo has been initialized in /home/user/yocto-project

这时候,目录下会多出一个 .repo 隐藏文件夹。里面存放了 manifest 文件和 repo 的元数据。

注意:.repo 目录可能很大(几百 MB 到几 GB),因为它包含了所有仓库的 Git 对象。不要随意删除或修改里面的内容。

3.4 同步所有仓库

初始化只是拉取了 manifest 文件。真正的代码下载,需要执行:

repo sync

这个命令会按照 manifest 里的描述,把每个仓库都 clone 到本地。repo sync 支持并行下载,默认是 4 个线程。你可以用 -j 参数调整:

repo sync -j8

我建议第一次同步时用 -j4,避免网络拥堵。之后增量更新时,可以开到 -j8 甚至 -j16。

同步完成后,你会看到类似这样的目录结构:

yocto-project/
├── .repo/
│   ├── manifests/
│   ├── manifests.git/
│   ├── repo/
│   └── projects/
├── bitbake/
├── documentation/
├── meta/
├── meta-poky/
├── meta-selftest/
├── meta-skeleton/
├── meta-yocto-bsp/
├── oe-init-build-env
├── README
├── README.hardware
└── ...

每个文件夹都是一个独立的 Git 仓库。你可以进入任意一个目录,执行 git log 查看历史。

3.5 理解层(Layer)的概念

好,源码拉下来了。现在我们来聊聊 Yocto 里最核心的概念——层(Layer)。

说白了,层就是一个「功能模块」。它把相关的配方(recipes)、配置文件、补丁、类文件打包在一起。

为什么需要层?

  • 模块化:不同的硬件平台、不同的软件栈,可以拆成独立的层。比如,meta-ti 负责 TI 的 AM335x 系列,meta-raspberrypi 负责树莓派。
  • 复用:一个层可以被多个项目共享。你不需要重复造轮子。
  • 隔离:层的优先级机制,允许你覆盖(override)其他层的配方,而不需要修改原始层。

我举个例子。你在 Poky 默认的 meta 层里,有一个 busybox 的配方。但你想用自己修改过的版本。怎么办?

很简单。创建一个新的层,比如 meta-custom,在里面放一个同名的 busybox 配方,然后把 meta-custom 的优先级设得比 meta 高。BitBake 会自动选择优先级高的那个。

关键点:层不是文件夹,而是有特定结构的目录。一个合法的层,必须包含 conf/layer.conf 文件。

3.6 查看源码目录结构

我们以 Poky 为例,看看它的核心目录结构:

目录/文件 作用
bitbake/ BitBake 构建引擎的源码。Yocto 的核心调度器。
meta/ 核心层。包含基础配方、类文件、配置文件。几乎所有项目都会用到。
meta-poky/ Poky 发行版配置层。定义了默认的发行版策略。
meta-yocto-bsp/ Yocto 官方支持的 BSP 层。包含 QEMU 和一些参考板的配置。
meta-skeleton/ 骨架层。给你做参考用的,教你如何创建自己的层。
meta-selftest/ 自测试层。用于 Yocto 项目的自动化测试。
documentation/ Yocto 项目的文档源码(基于 Yocto 文档工具链)。
oe-init-build-env 环境初始化脚本。每次开始构建前,都要 source 这个文件。

我们重点看看 meta/ 层的内部结构:

meta/
├── classes/
│   ├── base.bbclass
│   ├── kernel.bbclass
│   ├── autotools.bbclass
│   └── ...
├── conf/
│   ├── layer.conf
│   ├── machine/
│   │   ├── qemuarm.conf
│   │   ├── qemux86.conf
│   │   └── ...
│   └── distro/
│       ├── poky.conf
│       └── ...
├── recipes-bsp/
├── recipes-connectivity/
├── recipes-core/
├── recipes-devtools/
├── recipes-extended/
├── recipes-graphics/
├── recipes-kernel/
└── ...

这里有几个关键目录:

  • classes/:存放 .bbclass 文件。这些是 BitBake 的「类」,定义了通用的构建逻辑。比如 autotools.bbclass 封装了 autotools 的构建流程。
  • conf/:配置文件。包括层配置(layer.conf)、机器配置(machine/)、发行版配置(distro/)。
  • recipes-*/:配方目录。按功能分类,比如 recipes-core 放核心系统组件(busybox、udev 等),recipes-kernel 放内核相关。

每个配方目录下,通常包含多个版本的配方文件(.bb)和附加文件(.bbappend)。

我的习惯:拿到一个新层,我第一件事就是看 conf/layer.conf。这里面定义了层的优先级、依赖关系、以及哪些目录会被搜索。理解了 layer.conf,你就理解了这个层的「边界」。

3.7 层的关系图

为了让你更直观地理解层之间的关系,我画了一张图:

Yocto 层关系图 Yocto 层(Layer)关系图 用户自定义层(meta-custom) 优先级最高,可覆盖下层 BSP 层(meta-raspberrypi) 板级支持包 软件层(meta-qt5) 功能模块 Poky 核心层(meta + meta-poky) 基础配方、类文件、默认配置 BitBake 构建引擎 解析配方、调度任务 说明:上层可以覆盖下层的配方。优先级由 layer.conf 中的 BBFILE_COLLECTIONS 和 BBFILE_PATTERN 决定。

这张图展示了典型的层叠结构:

  • 最底层:BitBake 引擎。它不包含任何配方,只负责解析和执行。
  • 核心层:Poky 提供的 meta 和 meta-poky。这是所有项目的基石。
  • 中间层:BSP 层和软件层。它们扩展了核心层的功能。
  • 最顶层:你的自定义层。优先级最高,可以覆盖下面任何层的配方。

我曾经踩过的坑:有一次,我在自定义层里修改了 base-files 的配方,但忘记检查 layer.conf 里的优先级。结果 BitBake 一直用旧版本的配方,我排查了半天才发现是优先级设低了。记住:数字越大,优先级越高。默认是 6,我建议自定义层设到 10 以上。

3.8 小结

这一章我们做了三件事:

  1. 用 repo 工具下载了 Poky 和相关的 meta 层。
  2. 理解了层(Layer)的概念——它是 Yocto 模块化的基石。
  3. 查看了源码目录结构,知道了每个目录是干什么的。