3. 理解Yocto目录结构

说实话,很多初学者第一次看到Poky目录时,都会有点懵。我当年也是这样——下载完代码,ls一下,好家伙,一堆文件夹,完全不知道从哪下手。这一章,我就带你把这些目录一个一个捋清楚。

3.1 Poky目录剖析

Poky是Yocto的参考构建系统,说白了就是一个大集合。它包含了BitBake、OpenEmbedded-Core以及一些元数据。你下载的poky目录,通常长这样:

poky/
├── bitbake/        # 构建引擎
├── meta/           # OE-Core核心层
├── meta-poky/      # Poky参考发行版配置
├── meta-yocto-bsp/ # 参考BSP支持
├── scripts/        # 辅助脚本
├── oe-init-build-env # 环境初始化脚本
└── README

我个人习惯把poky看作一个「骨架」。你真正要改的东西,大部分不在poky里,而是在你自己的meta层里。嗯,这里要注意——永远不要直接修改poky目录下的文件,否则升级时会哭的。

3.2 meta层结构

meta层是Yocto的灵魂。每个meta层都是一个独立的目录,里面包含了recipes、配置文件、补丁等。一个标准的meta层结构是这样的:

meta-mylayer/
├── conf/
│   ├── layer.conf          # 层配置文件
│   └── machine/            # 机器配置
├── recipes-example/        # 示例配方
├── recipes-core/           # 核心组件
├── recipes-bsp/            # BSP相关
├── recipes-kernel/         # 内核配置
├── recipes-connectivity/   # 网络相关
├── files/                  # 通用文件
└── COPYING.MIT

我在项目中遇到过一个问题:有人把几十个recipe全塞在一个目录里,结果找某个配方时翻半天。我的建议是——按功能分类建子目录,比如recipes-core、recipes-bsp这样,清晰明了。

核心要点:每个meta层必须包含conf/layer.conf文件,否则BitBake不认这个层。

3.3 conf目录详解

conf目录是配置的核心。它主要包含两类文件:

文件/目录 作用 说明
layer.conf 层声明 定义层优先级、路径等
machine/ 机器配置 定义目标硬件参数
distro/ 发行版配置 定义软件包选择策略

举个例子,layer.conf里通常会有这么几行:

BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
            ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "mylayer"
BBFILE_PATTERN_mylayer = "^${LAYERDIR}/"
BBFILE_PRIORITY_mylayer = "6"

你想想看,这个优先级数字很关键。数字越大,优先级越高。我曾经因为优先级设错了,导致两个层里的同名recipe互相覆盖,编译出来的镜像功能不对。排查了一整天……从那以后,我每次新建层都会先检查优先级。

3.4 recipes-example示例

Yocto自带的recipes-example是个很好的学习材料。它展示了一个recipe的基本结构:

recipes-example/example/
├── example_0.1.bb
├── files/
│   └── example.patch
└── example.inc

一个典型的recipe文件长这样:

SUMMARY = "这是一个示例配方"
DESCRIPTION = "展示Yocto recipe的基本写法"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade..."

SRC_URI = "file://example.c \
           file://example.patch"

S = "${WORKDIR}"

do_compile() {
    ${CC} ${CFLAGS} example.c -o example
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 example ${D}${bindir}
}

这里有几个坑,我帮你标一下:

  • SRC_URI:文件路径要写对,否则BitBake找不到源文件
  • S:默认是${WORKDIR}/${BPN}-${PV},如果你改了目录结构,记得同步
  • do_install:一定要用${D}前缀,否则文件会装到宿主机上

小技巧:调试recipe时,可以用bitbake -c devshell <recipe-name>进入临时工作目录,手动执行命令看看效果。

3.5 构建输出目录(tmp/deploy)

构建完成后,所有产出都在tmp/deploy目录下。这是你最关心的目录之一:

tmp/deploy/
├── images/          # 镜像文件
│   └── qemuarm/     # 按机器分类
├── ipk/             # IPK包
├── deb/             # DEB包
├── rpm/             # RPM包
├── licenses/        # 许可证信息
└── sdk/             # SDK工具链

images目录下放的是最终镜像,比如core-image-minimal-qemuarm.ext4、zImage、dtb文件等。我每次构建完,第一件事就是去images目录看看文件大小——如果镜像太大,说明有东西没裁剪干净。

注意:tmp/deploy目录里的文件是构建产物,不要手动修改。如果你改了某个recipe,记得重新构建,否则deploy目录里的还是旧文件。

3.6 知识体系总览

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

Yocto目录结构关系图 Poky 根目录 bitbake/ (构建引擎) meta/ (OE-Core核心层) meta-poky/ (参考配置) meta-mylayer/ (自定义层) conf/ (配置) recipes-*/ (配方) files/ (资源文件) COPYING.MIT (许可证) tmp/deploy/ (构建输出目录) images/ (镜像) ipk/deb/rpm/ (包) licenses/ (许可证) sdk/ (工具链)

这张图展示了从Poky根目录到自定义meta层,再到最终构建产物的完整链路。你想想看,整个流程其实很清晰:Poky提供基础框架,meta层添加你的定制内容,最后tmp/deploy输出成果。

好了,这一章的内容就到这里。记住,目录结构是Yocto的骨架,理解了它,后面写recipe、配BSP都会顺手很多。