希望在使用 Yocto 项目前就知道的事


备注

阅读前,请先查看 技术概览, 其中定义了本文涉及的许多术语。有些内容现在可能还不容易理解, 但开始开发后,你会希望随时能够查到它们。 这些是使用 Yocto 项目时积累的成熟方法,并会定期更新。

使用 Yocto 项目通常不难,直到遇到问题。 如果不了解构建过程,就容易像面对黑盒一样排查故障。 下面整理了新用户希望在第一次构建前就了解的事项,也欢迎补充其他建议。

  1. 使用 Git 获取源码,而不是只下载压缩包。 使用 Git 可以方便地获取包含缺陷修复的更新。 如果使用压缩包,则需要自行负责更新。

  2. 熟悉层索引。 可以在 层索引 中查找各个层。 已申请 Yocto Project Compatible 状态、具有结构一致性保证并经过测试的层, 见 Yocto Project Compatible 层页面。 通常先查兼容层列表,找不到合适条目时再查通用层索引。 层索引最初由 OpenEmbedded 项目提供,并不具有兼容层列表那样的筛选和测试, 但兼容层列表中的条目较少。 各层的成熟度、验证程度和易用性并不相同,搜索结果也不会按这些指标排序。 选择最适合自己需求的层没有简单捷径,往往需要试用、查阅邮件列表, 或通过协作交流向其他开发者请教。

  3. 尽可能使用芯片厂商已有的 BSP 层。 Intel、TI、NXP 等厂商会提供适合其芯片的 BSP 层信息, 例如 meta-intel、meta-ti。 尽量不要从零创建;如果确有定制芯片需求, 可以把这些层作为参考或模板,并熟悉 Yocto Project 板级支持包(BSP)手册。

  4. 不要把所有内容都放在同一个层中。 使用不同的层对构建信息进行逻辑拆分,例如 BSP、图形界面、发行版配置、 中间件或应用层,像 meta-filesystems、meta-python、meta-intel 等。 将整个构建放入单一层,会限制并复杂化后续定制与复用; 按层隔离信息则有助于简化这些工作。

  5. 不要修改核心层。 这里包括 BitBake、OpenEmbedded-Core (OE-Core), 以及可能用到的 meta-yocto。 否则升级到下一个版本时,可能丢失在这些层中直接作出的全部修改。

  6. 注意搜索结果对应的文档版本。 Yocto 文档一直在更新,但 Google 搜索经常会返回旧版手册。 某个主题的搜索结果可能已经落后多个发布版本。 在官方文档站,可以通过页面顶部的下拉菜单确认和切换版本。

    很多开发者会打开 合并版 Mega 手册, 使用 Ctrl-F 搜索整页。这份手册汇总了核心手册, 一次字符串搜索即可找到相关术语或概念的所有出现位置。 找到需要的部分后,再按需进入对应手册。 也可以使用菜单或左侧导航中的搜索框。

  7. 理解构建系统的基本工作流。 了解工作流有助于定位问题发生在哪一步,以及构建为何失败。 流程可分为以下步骤:

    1. Fetch:获取源码。

    2. Extract:解压源码。

    3. Patch:应用缺陷修复或新增功能的补丁。

    4. Configure:设置环境与配置。

    5. Build:编译和链接。

    6. Install:将文件复制到目标目录。

    7. Package:将文件打包供安装使用。

    例如,fetch 阶段失败可能是找不到源码,extract 阶段失败可能是压缩包无效。 根据各阶段的职责,可以初步判断问题所在。

    _images/yp-flow-diagram.svg
  8. 学会生成和阅读依赖关系图。 依赖图显示配方、任务和目标之间的依赖。 使用 BitBake 的 “-g” 选项可以生成依赖图。 构建失败时,可能会看到不熟悉的软件包,不明白它们为何被加入构建; 依赖图可以帮助解释原因。 生成方式见 BitBake 用户手册的 Generating Dependency Graphs。

  9. 理解 tmp/work 中看似神秘的目录名。 构建系统依次获取、解压、预处理和构建源码。 出错时会报告保存临时文件与软件包的目录路径,通常位于 build/tmp。 详细例子见 示例, 但要注意该例使用的是较早的 Yocto 版本。

    构建时,可以通过 BitBake 的 “-u” 选项选择界面, 例如 knotty、ncurses 或 taskexp,以帮助理解构建依赖。

  10. 除了镜像,还可以构建更小的对象。 可以构建单个配方,也可以执行特定软件包的特定任务,包括 devshell。 入门时,Yocto Project 快速构建 会展示镜像的创建、运行和烧录, 但实际也可以只执行 bitbake foo,其中 foo 是一个具体配方。 如果某个依赖或配方有问题,这种方式能帮助缩小范围。 熟悉工作流后,构建失败时也可以先确认源码获取是否正常。 使用开发 Shell 介绍如何使用 devshell 构建和运行具体任务; 相关开发指南 则展示了如何修改和构建单个配方。

  11. 区分软件包与配方。 配方包含构建系统生成软件包所需的指令, 配方与软件包分别对应构建过程的输入和产物。

    构建系统读取配方并按照指令生成软件包。 一个配方的输出通常会拆成多个部分,例如主程序包、文档包、调试符号包、 独立工具包等。这种拆分让你不必安装不需要的部分, 对嵌入式与物联网的小型设备尤其有用。

  12. 了解根文件系统中最终安装了哪些软件包。

  13. 创建自己的镜像配方。 虽然有多种方法,但建议直接编写自己的镜像配方, 不要通过 append 修改现有镜像配方。镜像配方很容易编写, 最好从一开始就按自己的需求建立。

  14. 系统开发者需要具备以下基本能力:

    • 处理企业代理设置。

    • 向镜像添加软件包。

    • 区分配方和软件包。

    • 单独构建软件包,并理解这样做的价值。

    • 查明一个配方会生成哪些软件包。

    • 查明软件包包含哪些文件。

    • 查明镜像包含哪些文件。

    • 向镜像添加 SSH 服务器,以便向目标传输文件。

    • 理解配方结构。

    • 创建并使用层。

    • 借助 OpenEmbedded 层索引 查找配方。

    • 理解 MACHINE 与 DISTRO 设置的区别。

    • 为硬件选择并使用合适的 BSP(机器)。

    • 查找 DISTRO 特性示例,并知道设置位置。

    • 理解任务流水线,并执行单独的任务。

    • 理解 devtool 如何简化工作流。

    • 通过共享下载目录和共享状态缓存加快构建。

    • 生成并理解依赖图。

    • 生成并理解 BitBake 环境。

    • 构建用于应用开发的可扩展 SDK。

  15. 根据自己的兴趣,进一步阅读以下文档:


Yocto 项目中文文档

允许按照 Creative Commons 发布的 知识共享署名—相同方式共享 2.0 英国:英格兰及威尔士许可 条款复制、分发和/或修改本文档。

如发现本手册或其他 Yocto 项目手册存在不准确之处或问题,或希望提交补充和修改, 请向 Yocto 项目文档邮件列表 docs@lists.yoctoproject.org 发送邮件或补丁, 也可以加入 Libera Chat 的 #yocto 频道。