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 知识体系总览
为了让你更直观地理解这些目录之间的关系,我画了一张图:
这张图展示了从Poky根目录到自定义meta层,再到最终构建产物的完整链路。你想想看,整个流程其实很清晰:Poky提供基础框架,meta层添加你的定制内容,最后tmp/deploy输出成果。
好了,这一章的内容就到这里。记住,目录结构是Yocto的骨架,理解了它,后面写recipe、配BSP都会顺手很多。