第4章:Yocto项目结构——Poky目录结构、元数据层结构
说实话,刚接触Yocto那会儿,我对着Poky目录愣了半天。这玩意儿怎么这么多文件夹?每个文件夹是干嘛的?今天我就带你把这些目录结构掰开揉碎,讲清楚。
4.1 Poky目录结构——Yocto的骨架
Poky说白了就是Yocto的一个参考发行版。你从GitHub上clone下来的poky仓库,里面包含了构建嵌入式Linux所需的核心组件。我个人习惯把Poky比作一个乐高套装——零件都在里面,怎么搭看你自己。
典型的Poky目录长这样:
poky/
├── bitbake/ # BitBake构建引擎
├── meta/ # 核心元数据层
├── meta-poky/ # Poky参考发行版配置
├── meta-yocto-bsp/ # 参考BSP支持
├── scripts/ # 辅助脚本
├── oe-init-build-env # 环境初始化脚本
└── README # 你懂的
这里我重点说几个目录:
- bitbake/:构建系统的核心引擎。你写的recipe最终都由它解析执行。我在项目中遇到过bitbake版本不匹配导致解析失败的情况,所以建议你保持bitbake版本和meta层一致。
- meta/:核心元数据层。所有基础recipe、类文件、配置文件都在这里。这是Yocto的根基,千万别乱改。
- meta-poky/:Poky发行版的默认配置。包括distro配置文件、默认的local.conf示例等。
- meta-yocto-bsp/:参考板级支持包。提供了一些常见开发板的配置,比如qemu模拟器用的机器配置。
4.2 元数据层结构——分层设计的思想
Yocto的元数据层结构,说白了就是「分层叠加」的思想。每一层提供一部分功能,层与层之间通过优先级叠加。你想想看,这跟Linux内核的设备树叠加层是不是一个道理?
一个典型的元数据层目录结构:
meta-custom/
├── conf/
│ ├── layer.conf # 层配置文件
│ └── machine/ # 机器配置文件
├── recipes-*/ # 各种recipe目录
├── classes/ # 自定义类文件
├── files/ # 补丁、配置文件等
└── COPYING # 许可证信息
每个层必须有一个conf/layer.conf文件,告诉bitbake这个层叫什么、依赖哪些层、优先级是多少。我曾经因为忘记设置层优先级,导致两个层里的同名recipe互相覆盖,编译出来功能不对——排查了整整两天。
层优先级(BBFILE_PRIORITY):数值越大,优先级越高。默认是6。如果你想让自己的层覆盖poky里的recipe,把优先级设到7或更高就行。
4.3 meta/conf/machine/目录——机器配置的藏宝图
这个目录存放的是各种机器的配置文件。每个.conf文件定义了一款硬件平台。比如qemux86-64.conf、beaglebone-yocto.conf等。
一个典型的机器配置文件包含:
| 配置项 | 说明 | 示例 |
|---|---|---|
| TUNE_FEATURES | CPU架构特性 | tune-corei7-64 |
| MACHINE_FEATURES | 硬件特性 | wifi, bluetooth, screen |
| PREFERRED_PROVIDER | 首选提供者 | virtual/kernel |
| SERIAL_CONSOLES | 串口控制台 | 115200;ttyS0 |
嗯,这里要注意:机器配置文件里定义的变量,会影响整个构建过程。比如你定义了MACHINE_FEATURES += "wifi",那系统就会自动把Wi-Fi相关的包加进来。我在项目中就遇到过因为忘记加bluetooth特性,导致蓝牙驱动没编译进去的尴尬。
4.4 meta/recipes-*/目录——配方的分类仓库
这个目录是按功能分类的recipe集合。常见的子目录有:
- recipes-core/:核心系统组件,比如init系统、busybox、glibc等
- recipes-bsp/:板级支持包,包括bootloader、设备树、固件等
- recipes-kernel/:Linux内核相关,包括内核源码、模块、设备树编译
- recipes-devtools/:开发工具,比如gcc、gdb、make等
- recipes-connectivity/:网络连接相关,比如wpa_supplicant、dhcpcd等
- recipes-graphics/:图形相关,比如X11、Wayland、GPU驱动等
每个recipe目录里通常包含:
recipes-example/example/
├── example_1.0.bb # 主recipe文件
├── example_1.0.bbappend # 追加文件(可选)
├── files/ # 补丁、配置文件
│ ├── 0001-fix-bug.patch
│ └── example.conf
└── example.inc # 公共包含文件(可选)
说白了,每个recipe就是一个软件的「安装说明书」。bitbake根据这个说明书去下载源码、打补丁、配置、编译、安装。我刚开始写recipe时,经常搞混SRC_URI和S变量的关系——SRC_URI告诉bitbake去哪里下载,S告诉它源码解压到哪个目录。
4.5 构建输出目录tmp/——构建的成果与垃圾
当你运行bitbake core-image-minimal后,所有构建产物都会放在tmp/目录下。这个目录的结构如下:
tmp/
├── deploy/ # 最终产物(镜像、内核、设备树等)
│ ├── images/ # 可烧录的镜像文件
│ └── licenses/ # 许可证信息
├── work/ # 每个recipe的工作目录
│ └── core2-64-poky-linux/
│ ├── linux-yocto/
│ └── busybox/
├── stamps/ # 构建状态标记
├── log/ # 构建日志
└── cache/ # 解析缓存
这里我重点说几个:
- deploy/images/:你最终要烧录到板子上的文件都在这里。比如
core-image-minimal-qemux86-64.rootfs.ext4、bzImage、*.dtb等。 - work/:每个recipe的编译工作目录。里面包含了源码、编译中间文件、安装后的文件。如果你要调试某个包的编译问题,来这里翻日志最直接。
- stamps/:记录每个任务的完成状态。bitbake靠这些文件来判断哪些任务需要重新执行。
tmp/目录有个特点:它占空间特别大。一个完整的构建下来,轻松几十GB。我建议你在local.conf里设置INHERIT += "rm_work",这样构建完成后会自动清理工作目录,能省不少空间。
核心逻辑总结:Poky是骨架,meta层是血肉,machine配置是骨骼,recipe是器官,tmp/是构建过程的「手术室」。理解了这个结构,你就能在Yocto的世界里游刃有余。
这张图把整个Yocto项目结构串起来了。从Poky出发,分出四个核心目录,然后meta/内部又分出机器配置、配方目录、类文件,配方目录再按功能细分,最终所有构建产物汇聚到tmp/。你想想看,这个结构是不是很清晰?
可可精品资料库