yocto 知:BitBake用户手册

BitBake 用户手册

作者:Richard Purdie, Chris Larson, and Phil Blundell

译者:maminjie

BitBake社区

bitbake-devel@lists.openembedded.org

Copyright © 2004-2016 Richard Purdie, Chris Larson, and Phil Blundell
这项工作是根据知识共享署名许可获得许可的。要查看此许可证的副本,请访问 http://creativecommons.org/licenses/by/2.5/ 或致函 Creative Commons, 444 Castro Street, Suite 900, Mountain View, California 94041, USA。

原文链接:https://www.yoctoproject.org/docs/2.1/bitbake-user-manual/bitbake-user-manual.html

文章目录

1. 概述

欢迎使用 《BitBake 用户手册》。本手册提供有关 BitBake 工具的信息。这些信息试图尽可能独立于使用 BitBake 的系统,例如 OpenEmbedded 和 Yocto 项目。在某些情况下,手册中会使用构建系统上下文中的场景或示例来帮助理解。对于这些情况,手册清楚地说明了上下文。

1.1. 介绍

从根本上说,BitBake 是一个通用的任务执行引擎,它允许 shell 和 Python 任务在复杂的任务间依赖约束下高效并行运行。BitBake 的主要用户之一 OpenEmbedded 使用此核心程序,并使用面向任务的方法构建嵌入式 Linux 软件栈。

从概念上讲,BitBake 在某些方面类似于 GNU Make,但有显着差异:

  • BitBake 根据提供的构建任务的元数据执行任务。元数据存储在配方 ( .bb) 和相关配方“追加” ( .bbappend) 文件、配置 ( .conf) 和底层包含 ( .inc) 文件以及类 ( .bbclass) 文件中。元数据为 BitBake 提供了有关要运行哪些任务以及这些任务之间的依赖关系的说明。

  • BitBake 包含一个 fetcher 库,用于从各种地方(例如本地文件、源代码控制系统或网站)获取源代码。

  • 要构建的每个单元(例如,一款软件)的指令称为“配方”文件,包含有关该单元的所有信息(依赖项、源文件位置、校验和、描述等)。

  • BitBake 包括客户端/服务器抽象,可以从命令行使用,也可以作为 XML-RPC 上的服务使用,并且有几个不同的用户界面。

1.2. 历史和目标

BitBake 最初是 OpenEmbedded 项目的一部分。它的灵感来自 Gentoo Linux 发行版使用的 Portage 包管理系统。2004 年 12 月 7 日,OpenEmbedded 项目团队成员 Chris Larson 将该项目分为两个不同的部分:

  • BitBake,一个通用的任务执行器

  • OpenEmbedded,BitBake 使用的元数据集

今天,BitBake 是OpenEmbedded 项目的主要基础,该项目被用于构建和维护 Linux 发行版,例如 Angstrom 发行版,也被用作 Linux 项目的构建工具,例如 Yocto 项目。

在 BitBake 之前,没有其他构建工具能够充分满足有抱负的嵌入式 Linux 发行版的需求。传统桌面 Linux 发行版使用的所有构建系统都缺乏重要的功能,而且在嵌入式领域中流行的基于 Buildroot 的特定系统中没有一个是可扩展或可维护的。

BitBake 的一些重要最初目标是:

  • 处理交叉编译。

  • 处理包之间依赖关系(目标架构上的构建时依赖、本机架构上的构建时依赖,和运行时依赖)。

  • 支持在给定的包中运行任意数量的任务,包括但不限于获取上游源码、解压、打补丁、配置等。

  • 对于构建系统和目标系统都与 Linux 发行版无关。

  • 架构无关。

  • 支持多种构建和目标操作系统(例如 Cygwin、BSD 等)。

  • 是自包含的,而不是紧密集成到构建机器的根文件系统中。

  • 处理目标架构、操作系统、发行版和机器上的条件元数据。

  • 易于使用这些工具来提供要操作的本地元数据和包。

  • 易于使用 BitBake 在多个项目之间进行协作,以进行构建。

  • 提供继承机制,以在多个包之间共享公共元数据。

随着时间的推移,显然需要一些进一步的要求:

  • 处理基本配方的变体(variants)(例如:native、sdk 和 multilib)。

  • 将元数据拆分为层,并允许层增强或覆盖其他层。

  • 允许将任务的给定输入变量集表示为校验和。基于该校验和,允许使用预构建的组件加速构建。

BitBake 满足所有最初要求,并且对基本功能进行了扩展以反映附加要求。灵活性和强大(power)一直是其首要任务。BitBake 具有高度可扩展性,支持嵌入式 Python 代码和任意任务的执行。

1.3. 概念

BitBake 是一个用 Python 语言编写的程序。在最上层,BitBake 解释元数据,决定需要运行哪些任务,并执行这些任务。与 GNU Make 类似,BitBake 控制软件的构建方式。GNU Make 通过“makefiles”实现其控制,而 BitBake 使用“recipes”。

BitBake 允许定义更复杂的任务,例如构建整个嵌入式 Linux 发行版,从而扩展了像 GNU Make 这样的简单工具的功能。

本节的其余部分介绍了几个应该理解的概念,以便更好地利用 BitBake 的强大功能。

1.3.1. 配方(Recipes)

BitBake 配方(Recipes),以文件扩展名 .bb表示,是最基本的元数据文件。这些配方文件为 BitBake 提供了以下内容:

  • 关于包的描述信息(作者、主页、许可证等)

  • 配方的版本

  • 现有依赖关系(构建和运行时依赖关系)

  • 源代码所在的位置以及如何获取它

  • 源代码是否需要任何补丁,在哪里可以找到它们,以及如何应用它们

  • 如何配置和编译源代码

  • 如何将生成的文件打包到一个或多个可安装的软件包中

  • 在目标机器上的哪个位置安装软件包

在 BitBake 或任何使用 BitBake 作为其构建系统的项目的上下文中,具有.bb 扩展名的文件称为配方。

说明
术语“package”也常用于描述配方(recipes)。但是,由于同一个词又用于描述项目的打包输出,所以最好保持一个单一的描述性术语——“recipes”。换句话说,单个“recipe”文件完全能够生成许多相关但可单独安装的“package”。事实上,这种能力相当普遍。

1.3.2. 配置文件(Configuration Files)

配置文件,以文件扩展名.conf表示,定义了管理项目构建过程的各种配置变量。这些文件分为几个区域,定义机器配置(machine configuration)选项、分发配置(distribution configuration)选项、编译器调整(compiler tuning)选项、通用配置选项和用户配置选项。主要的配置文件是示例 bitbake.conf文件,它位于 BitBake 源代码树 conf目录中。

1.3.3. 类(Classes)

类文件,以文件扩展名.bbclass表示,包含有助于在元数据文件之间共享的信息。BitBake 源代码树当前带有一个名为base.bbclass 的类元数据文件,您可以在classes目录中找到该文件 。这个base.bbclass 文件很特别,因为它总是自动包含在所有配方和类中。此类包含标准基本任务的定义,例如获取、解包、配置(默认为空)、编译(运行任何存在的 Makefile)、安装(默认为空)和打包(默认为空)。这些任务通常会被项目开发过程中添加的其他类覆盖或扩展。

1.3.4. 层(Layers)

层允许您将不同类型的自定义相互隔离。虽然您可能会发现在处理单个项目时将所有内容都保留在一个层中很诱人,但是您组织元数据的模块化程度越高,应对未来变化就越容易。

为了说明如何使用层来保持模块化,请考虑您可能进行的自定义以支持特定的目标机器。这些类型的定制通常位于一个特殊层,而不是一个称为板级支持包 (BSP) 层的通用层。此外,机器定制应该与支持新 GUI 环境的配方和元数据隔离,例如。这种情况为您提供了两层:一层用于机器配置,一层用于 GUI 环境。然而,重要的是要了解,BSP 层仍然可以对 GUI 环境层中的配方进行特定于机器的添加,而不会因这些特定于机器的更改而污染 GUI 层本身。您可以通过一个叫 BitBake 附加(.bbappend)文件的配方来实现此目的。

1.3.5. 附加文件(Append Files)

附加文件,即具有.bbappend文件扩展名的文件,用于扩展或覆盖现有配方文件中的信息。

BitBake 期望每个附加文件都有一个相应的配方文件。此外,附加文件和相应的配方文件必须使用相同的根文件名。文件名只能在使用的文件类型后缀(例如:formfactor_0.0.bb和 formfactor_0.0.bbappend)上有所不同。

附加文件中的信息扩展或覆盖了底层的、名称相似的配方文件中的信息。

命名附加文件时,可以使用通配符 (%) 来匹配配方名称。例如,假设您有一个名为如下的附加文件:

 busybox_1.21.%.bbappend

该附加文件将匹配任何busybox_1.21.x.bb 版本的配方。因此,附加文件将匹配以下配方名称:

 busybox_1.21.1.bb
 busybox_1.21.2.bb
 busybox_1.21.3.bb

说明:
“%”字符的使用受到限制,因为它只能直接在附加文件名的.bbappend部分前面使用。您不能在名称的任何其他位置使用通配符。

如果busybox配方更新为 busybox_1.3.0.bb,则附加名称将不匹配。但是,如果您将附加文件命名为 busybox_1.%.bbappend,则可以匹配。

通常,您可以将附加文件命名为busybox_%.bbappend之类的简单名称,使其完全独立于版本。

1.4. 获取BitBake

您可以通过几种不同的方式获得 BitBake:

  • 克隆 BitBake: 使用 Git 克隆 BitBake 源代码库是获取 BitBake 的推荐方法。克隆存储库可以轻松修复错误并访问稳定分支和主分支。克隆 BitBake 后,您应该使用最新的稳定分支进行开发,因为主分支用于 BitBake 开发并且可能包含不太稳定的更改。

    您通常需要一个与您使用的元数据相匹配的 BitBake 版本。元数据通常向后兼容但不向前兼容。

    这是一个克隆 BitBake 存储库的示例:

     $ git clone git://git.openembedded.org/bitbake
    

    此命令将 BitBake Git 存储库克隆到名为bitbake的目录中。另外,如果您不想将目录命名为bitbake,则可以在git clone命令之后指定目录。这是一个命名目录bbdev的示例:

     $ git clone git://git.openembedded.org/bitbake bbdev
    
  • 使用您的分发包管理系统来安装: 不建议使用此方法,因为在大多数情况下,您的分发提供的 BitBake 版本是 BitBake 存储库快照后面的几个版本。

  • 获取 BitBake 的快照:从源代码存储库下载BitBake的快照,您可以访问 BitBake 的已知分支或版本。

    说明
    如前所述,克隆 Git 存储库是获取 BitBake 的首选方法。当补丁被添加到稳定分支时,克隆存储库可以更容易地更新。

    以下示例下载 BitBake 版本 1.17.0 的快照:

     $ wget http://git.openembedded.org/bitbake/snapshot/bitbake-1.17.0.tar.gz
     $ tar zxpvf bitbake-1.17.0.tar.gz
    

    使用 tar 实用程序提取 tarball 后,您将拥有一个名为 bitbake-1.17.0.

  • 使用您构建系统检出附带的 BitBake: 获得 BitBake 副本的最后一种可能性是,它已经随您检出的基于 Bitbake 的大型构建系统(例如 Poky 或 Yocto Project)一起提供。您可以检出整个构建系统,而不是手动检查各个层并将它们自己粘合在一起。这个检出将包含一个 BitBake 版本,该版本已经过全面测试与其他组件的兼容性。有关如何检出特定基于 BitBake 的构建系统的信息,请参阅该构建系统的支持文档。

1.5. BitBake 命令

该bitbake命令是 BitBake 工具的主要接口。本节介绍 BitBake 命令语法并提供几个执行示例。

1.5.1. 用法和语法

以下是 BitBake 的用法和语法:

$ bitbake -h
Usage: bitbake [options] [recipename/target recipe:do_task ...]

     Executes the specified task (default is 'build') for a given set of target recipes (.bb files).
     It is assumed there is a conf/bblayers.conf available in cwd or in BBPATH which
     will provide the layer, BBFILES and other configuration information.
     为一组给定的目标配方(.bb 文件)执行指定的任务(默认为“构建”)。
     假设在 cwd 或 BBPATH 中有一个 conf/bblayers.conf 可用,它将提供层、BBFILES 和其他配置信息。

Options:
     --version           show program's version number and exit
     -h, --help          show this help message and exit
     -b BUILDFILE, --buildfile=BUILDFILE
                         Execute tasks from a specific .bb recipe directly.
                         WARNING: Does not handle any dependencies from other
                         recipes.
                         直接从特定的 .bb 配方执行任务。
                         警告:不处理来自其他配方的任何依赖项。
     -k, --continue      Continue as much as possible after an error. While the
                         target that failed and anything depending on it cannot
                         be built, as much as possible will be built before
                         stopping.
                         出错后尽可能继续。虽然失败的目标和任何依赖它的东西都无法构建,
                         但在停止之前将尽可能多地构建。
     -a, --tryaltconfigs Continue with builds by trying to use alternative
                         providers where possible.
                         在可能的情况下尝试使用替代提供程序继续构建
     -f, --force         Force the specified targets/task to run (invalidating
                         any existing stamp file).
                         强制运行指定的目标/任务(使任何现有的戳文件无效)
     -c CMD, --cmd=CMD   Specify the task to execute. The exact options
                         available depend on the metadata. Some examples might
                         be 'compile' or 'populate_sysroot' or 'listtasks' may
                         give a list of the tasks available.
                         指定要执行的任务。可用的确切选项取决于元数据。
                         一些示例可能是 'compile' 或 'populate_sysroot'
                         或 'listtasks' 可能会给出可用任务的列表。
     -C INVALIDATE_STAMP, --clear-stamp=INVALIDATE_STAMP
                         Invalidate the stamp for the specified task such as
                         'compile' and then run the default task for the
                         specified target(s).
                         使指定任务的标记无效,例如“编译”,然后运行指定目标的默认任务。
     -r PREFILE, --read=PREFILE
                         Read the specified file before bitbake.conf.
                         在 bitbake.conf 之前读取指定文件。
     -R POSTFILE, --postread=POSTFILE
                         Read the specified file after bitbake.conf.
                         读取 bitbake.conf 后的指定文件。
     -v, --verbose       Output more log message data to the terminal.
     -D, --debug         Increase the debug level. You can specify this more
                         than once.
                         提高调试级别。您可以多次指定此项。
     -n, --dry-run       Don't execute, just go through the motions.
     -S SIGNATURE_HANDLER, --dump-signatures=SIGNATURE_HANDLER
                         Dump out the signature construction information, with
                         no task execution. The SIGNATURE_HANDLER parameter is
                         passed to the handler. Two common values are none and
                         printdiff but the handler may define more/less. none
                         means only dump the signature, printdiff means compare
                         the dumped signature with the cached one.
     -p, --parse-only    Quit after parsing the BB recipes.
                         解析 BB 配方后退出。
     -s, --show-versions Show current and preferred versions of all recipes.
                         显示所有配方的当前和首选版本。
     -e, --environment   Show the global or per-recipe environment complete
                         with information about where variables were
                         set/changed.
                         显示完整的全局或每个配方环境以及有关设置/更改变量位置的信息。
     -g, --graphviz      Save dependency tree information for the specified
                         targets in the dot syntax.
                         以点语法保存指定目标的依赖树信息。
     -I EXTRA_ASSUME_PROVIDED, --ignore-deps=EXTRA_ASSUME_PROVIDED
                         Assume these dependencies don't exist and are already
                         provided (equivalent to ASSUME_PROVIDED). Useful to
                         make dependency graphs more appealing
                         假设这些依赖项不存在并且已经提供(相当于 ASSUME_PROVIDED)。有助于使依赖图更具吸引力
     -l DEBUG_DOMAINS, --log-domains=DEBUG_DOMAINS
                         Show debug logging for the specified logging domains
     -P, --profile       Profile the command and save reports.
     -u UI, --ui=UI      The user interface to use (depexp, goggle, hob, knotty
                         or ncurses - default knotty).
     -t SERVERTYPE, --servertype=SERVERTYPE
                         Choose which server type to use (process or xmlrpc -
                         default process).
     --token=XMLRPCTOKEN Specify the connection token to be used when
                         connecting to a remote server.
     --revisions-changed Set the exit code depending on whether upstream
                         floating revisions have changed or not.
     --server-only       Run bitbake without a UI, only starting a server
                         (cooker) process.
     -B BIND, --bind=BIND  The name/address for the bitbake server to bind to.
                         要绑定到的 bitbake 服务器的名称/地址
     --no-setscene       Do not run any setscene tasks. sstate will be ignored
                         and everything needed, built.
     --remote-server=REMOTE_SERVER
                         Connect to the specified server.
     -m, --kill-server   Terminate the remote server.
     --observe-only      Connect to a server as an observing-only client.
     --status-only       Check the status of the remote bitbake server.
     -w WRITEEVENTLOG, --write-log=WRITEEVENTLOG
                         Writes the event log of the build to a bitbake event
                         json file. Use '' (empty string) to assign the name
                         automatically.
                         将构建的事件日志写入 bitbake 事件 json 文件。
                         使用 ''(空字符串)自动分配名称。

1.5.2. 例子

本节提供了一些示例,说明如何使用 BitBake。

1.5.2.1. 针对单个配方执行任务

为单个配方文件执行任务相对简单。你指定相关的文件,BitBake 解析它并执行指定的任务。如果不指定任务,BitBake 将执行默认任务“build”。BitBake 执行此操作时遵守任务间依赖关系。

以下命令在foo_1.0.bb 配方文件上运行构建任务,这是默认任务:

 $ bitbake -b foo_1.0.bb

以下命令在foo.bb配方文件上运行清理任务 :

 $ bitbake -b foo.bb -c clean

说明
“-b”选项明确不处理配方依赖性。除了用于调试目的之外,建议您使用下一节中介绍的语法。

1.5.2.2. 针对一组配方文件执行任务

当您想要管理多个.bb 文件时,会引入许多额外的复杂性。显然,需要有一种方法来告诉 BitBake 哪些文件可用,以及哪些文件是您想要执行的。每个配方还需要有一种方法来表达其依赖关系,包括构建时和运行时的。当多个配方提供相同的功能时,或者当一个配方有多个版本时,您必须有一种方法来表达配方首选项。

当bitbake命令在不使用“–buildfile”或“-b”时,仅接受“PROVIDES”。你不能提供任何其他东西。默认情况下,配方文件通常“PROVIDES”其“packagename(包名称)”,如以下示例所示:

 $ bitbake foo

下一个示例“PROVIDES”包名称,并使用“-c”选项告诉 BitBake 只执行do_clean任务:

 $ bitbake -c clean foo
1.5.2.3. 生成依赖图

BitBake 能够使用dot语法生成依赖图。您可以使用Graphviz 中的dot工具 将这些图形转换为图像。

生成依赖图时,BitBake 将四个文件写入当前工作目录:

  • package-depends.dot:显示 BitBake 对运行时目标之间的依赖关系。

  • pn-depends.dot:显示构建时目标(即配方)之间的依赖关系。

  • task-depends.dot:显示任务之间的依赖关系。

  • pn-buildlist:显示要构建的目标的简单列表。

要停止依赖公共的依赖,请使用“-I”依赖选项,BitBake 会从图中省略它们。忽略这些信息可以生成更具可读性的图表。这样,您可以从图中删除来自继承类(例如:base.bbclass)中的依赖(DEPENDS)。

下面是创建依赖关系图的两个示例。第二个示例从图中省略了 OpenEmbedded 中的公共项:

 $ bitbake -g foo

 $ bitbake -g -I virtual/kernel -I eglibc foo

2. 执行

运行 BitBake 的主要目的是生成某种输出,例如单个可安装包、内核、软件开发工具包(SDK),甚至是完整的、特定于板卡的可引导 Linux 映像,包括引导加载程序、内核和根文件系统。当然,您可以带一些选项来执行bitbake命令,使其执行单个任务、编译单个配方文件、捕获或清除数据,或者只是返回有关执行环境的信息。

本章介绍使用 BitBake 创建镜像时从头到尾的执行过程。使用以下命令形式启动执行过程:

 $bitbake target

有关 BitBake 命令及其选项的信息,请参阅“BitBake 命令”部分。

说明
在执行 BitBake 之前,您应该通过在项目的local.conf 配置文件中设置BB_NUMBER_THREADS 变量来利用构建主机上可用的并行线程执行 。

确定构建主机上此值的常用方法是运行以下命令:

 $ grep processor /proc/cpuinfo

此命令返回处理器的数量,其中考虑了超线程。因此,具有超线程的四核构建主机最有可能显示八个处理器,这是您随后将分配给 BB_NUMBER_THREADS 的值 。

一个可能更简单的解决方案是某些 Linux 发行版(例如 Debian 和 Ubuntu)提供ncpus命令。

2.1. 解析基础配置元数据

BitBake 做的第一件事是解析基础配置元数据。基础配置元数据由项目的bblayers.conf 文件(用于确定 BitBake 需要识别哪些层)、所有必要的 layer.conf 文件(每层一个)和 bitbake.conf 文件组成。数据本身有多种类型:

  • 配方:有关特定软件的详细信息。

  • 类数据:通用构建信息的抽象(例如如何构建 Linux 内核)。

  • 配置数据:特定于机器的设置、策略决策等。配置数据充当将所有内容绑定在一起的粘合剂。

这些layer.conf文件用于构造关键变量,例如 BBPATH 和 BBFILES。BBPATH用于分别在conf和classes目录下搜索配置文件和类文件。BBFILES用于定位配方和配方附加文件(.bb和.bbappend)。如果没有bblayers.conf文件,则假定用户已直接在环境中设置了BBPATH 和BBFILES。

接下来,使用BBPATH刚刚构造的变量定位bitbake.conf文件。该bitbake.conf文件还可以包括其他使用include或require指令的配置文件 。

在解析配置文件之前,Bitbake 会查看某些变量,包括:

  • BB_ENV_WHITELIST
  • BB_ENV_EXTRAWHITE
  • BB_PRESERVE_ENV
  • BB_ORIGENV
  • BITBAKE_UI

此列表中的前四个变量与 BitBake 在任务执行期间如何处理 shell 环境变量有关。默认情况下,BitBake 会清除环境变量并提供对 shell 执行环境的严格控制。但是,通过使用前四个变量,您可以控制 BitBake 在执行任务期间允许在 shell 中使用的环境变量。请参阅“将信息传递到构建任务环境中”部分以及变量词汇表中有关这些变量的信息,以获取有关它们如何工作以及如何使用它们的更多信息。

基础配置元数据是全局的,因此会影响所有执行的配方和任务。

BitBake 首先在当前工作目录中搜索可选conf/bblayers.conf配置文件。该文件应包含一个BBLAYERS 变量,该变量是一个以空格分隔的“layer”目录列表。回想一下,如果 BitBake 找不到bblayers.conf 文件,则假定用户已直接在环境中设置了BBPATH 和BBFILES变量。

对于此列表中的每个目录(层),定位并解析 conf/layer.conf 文件,并将 LAYERDIR 变量设置为找到该层的目录。这个想法是这些文件自动为给定的构建目录正确设置 BBPATH 和其他变量。

然后 BitBake 期望在用户指定的 BBPATH 中的某处找到 conf/bitbake.conf 文件。该配置文件通常具有包含任何其他元数据的指令,例如特定于体系结构、机器、本地环境等的文件。

bitbake.conf文件中只允许使用变量定义和包含指令。一些变量直接影响 BitBake 的行为。这些变量可能是从环境中设置的,具体取决于前面提到的或在配置文件中设置的环境变量。“变量词汇表”一章提供了完整的变量列表。

解析配置文件后,BitBake 使用其基本的继承机制,即通过类文件,继承一些标准类。当遇到负责获取该类的继承指令时,BitBake 会解析该类。

base.bbclass文件始终包含在内。还包括在配置中使用 INHERIT 变量指定的其他类。BitBake 以与配置文件相同的方法在 BBPATH 路径下的classes子目录中搜索类文件。

了解执行环境中使用的配置文件和类文件的一个好方法是运行以下 BitBake 命令:

 $ bitbake -e > mybb.log

检查mybb.log文件的顶部,其显示您的执行环境中使用的许多配置文件和类文件。

说明
您需要了解 BitBake 如何解析花(大)括号。如果配方在函数内使用右花括号并且字符没有前导空格,则 BitBake 会产生解析错误。如果在 shell 函数中使用一对大括号,则结束大括号不能位于没有前导空格的行的开头。

以下是导致 BitBake 产生解析错误的示例:

 fakeroot create_shar() {
     cat << "EOF" > ${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh
 usage()
 {
   echo "test"
   ###### The following "}" at the start of the line causes a parsing error ######
 }
 EOF
 }

以这种方式编写配方可以避免错误:

 fakeroot create_shar() {
     cat << "EOF" > ${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh
 usage()
 {
   echo "test"
   ######The following "}" with a leading space at the start of the line avoids the error ######
  }
 EOF
 }

2.2. 定位和解析配方

在配置阶段,BitBake 将设置 BBFILES。BitBake 现在使用它来构建要解析的配方列表,以及要应用的任何附加文件(.bbappend)。BBFILES是一个空格分隔可用文件的列表,支持通配符。一个例子是:

 BBFILES = "/path/to/bbfiles/*.bb /path/to/appends/*.bbappend"

BitBake 解析位于 BBFILES 中的每个配方和附加文件,并将各种变量的值存储到数据存储中。

说明
附加文件按照它们在 BBFILES 中遇到的顺序应用。

对于每个文件,都会制作基础配置的新副本,然后逐行解析配方。任何继承语句都会导致 BitBake 使用 BBPATH 作为搜索路径查找并解析类文件(.bbclass)。最后,BitBake 按顺序解析在 BBFILES 中找到的任何附加文件。

一种常见的约定是使用配方文件名来定义元数据片段。例如,在 bitbake.conf 中,配方名称和版本用于设置变量 PN 和 PV:

 PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
 PV = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[1] or '1.0'}"

在此示例中,名为“something_1.2.3.bb”的配方会将 PN 设置为“something”,将 PV 设置为“1.2.3”。

当一个配方的解析完成时,BitBake 有一个配方定义的任务列表和一组由键和值组成的数据以及关于任务的依赖信息。

BitBake 不需要所有这些信息。它只需要一小部分信息即可做出有关配方的决策。因此,BitBake 会缓存它感兴趣的值,而不存储其余信息。经验表明,重新解析元数据比尝试将其写入磁盘然后重新加载要快。

在可能的情况下,后续的 BitBake 命令会重用此配方信息缓存。该缓存的有效性通过首先计算基本配置数据的校验和(参见 BB_HASHCONFIG_WHITELIST),然后检查校验和是否匹配来确定。如果校验和匹配缓存中的内容,并且配方和类文件没有改变,Bitbake 就可以使用缓存。BitBake 然后重新加载有关配方的缓存信息,而不是从头开始重新解析它。

配方文件集合的存在允许用户拥有包含完全相同的包的多个 .bb 文件存储库。例如,人们可以轻松地使用它们来制作自己的上游存储库的本地副本,但可以进行自定义修改,而这是上游不想要的。下面是一个例子:

BBFILES = "/stuff/openembedded/*/*.bb /stuff/openembedded.modified/*/*.bb"
BBFILE_COLLECTIONS = "upstream local"
BBFILE_PATTERN_upstream = "^/stuff/openembedded/"
BBFILE_PATTERN_local = "^/stuff/openembedded.modified/"
BBFILE_PRIORITY_upstream = "5"
BBFILE_PRIORITY_local = "10"

说明
层机制现在是收集代码的首选方法。虽然集合代码保留,但它的主要用途是设置层优先级和处理层之间的重叠(冲突)。

2.3. 提供(Providers)

假设 BitBake 已被指示执行目标并且所有配方文件都已解析,BitBake 开始弄清楚如何构建目标。BitBake 查看每个配方的 PROVIDES 列表。PROVIDES 列表是可以知道配方的名称列表。每个配方的 PROVIDES 列表是通过配方的 PN 变量隐式创建的,并通过配方的 PROVIDES 变量显式创建,该变量是可选的。

当配方使用 PROVIDES 时,可以在一个或多个替代名称下找到该配方的功能,而不是隐式 PN 名称。例如,假设名为 keyboard_1.0.bb 的配方包含以下内容:

 PROVIDES += "fullkeyboard"

此配方的 PROVIDES 列表变为隐式的“keyboard”和显式的“fullkeyboard”。因此,可以在两个不同的名称下找到 keyboard_1.0.bb 中的功能。

2.4. 首选项(Preferences)

PROVIDES 列表只是找出目标配方的解决方案的一部分。由于目标可能有多个提供者,BitBake 需要通过确定提供者偏好来确定提供者的优先级。

一个目标具有多个提供程序的常见示例是“virtual/kernel”,它位于每个内核配方的 PROVIDES 列表中。每台机器通常通过在机器配置文件中使用类似于以下内容的行来选择最佳内核提供程序:

 PREFERRED_PROVIDER_virtual/kernel = "linux-yocto"

默认的 PREFERRED_PROVIDER 是与目标同名的提供者。Bitbake 遍历构建所需的每个目标,并使用此过程解析它们及其依赖项。

由于给定提供者可能存在多个版本,因此了解如何选择提供者变得很复杂。BitBake 默认为提供者的最高版本。使用与 Debian 相同的方法进行版本比较。您可以使用 PREFERRED_VERSION 变量来指定特定版本。您可以使用 DEFAULT_PREFERENCE 变量影响顺序。

默认情况下,文件的首选项为“0”。将 DEFAULT_PREFERENCE 设置为“-1”会使配方不太可能被使用,除非它被明确引用。将 DEFAULT_PREFERENCE 设置为“1”使得很可能使用了配方。PREFERRED_VERSION 覆盖任何 DEFAULT_PREFERENCE 设置。DEFAULT_PREFERENCE 通常用于标记更新和更具实验性的配方版本,直到它们经过足够的测试被认为是稳定的。

当给定配方有多个“版本”时,除非另有说明,BitBake 默认选择最新版本。如果有问题的配方的 DEFAULT_PREFERENCE 设置低于其他配方(默认值为 0),则不会选择它。这允许维护配方文件存储库的一个或多个人指定他们对默认选择版本的偏好。此外,用户可以指定他们的首选版本。

如果第一个配方命名为 a_1.1.bb,则 PN 变量将设置为“a”,PV 变量将设置为 1.1。

因此,如果存在名为 a_1.2.bb 的配方,BitBake 将默认选择 1.2。但是,如果您在 BitBake 解析的 .conf 文件中定义以下变量,则可以更改该首选项:

 PREFERRED_VERSION_a = "1.1"

说明
一个配方提供两个版本是很常见的 – 一个稳定的、编号的(和首选的)版本,以及一个从源代码存储库自动检出的版本,该版本被认为更“前沿”,但只能明确选择。

例如,在 OpenEmbedded 代码库中,有一个 BusyBox 的标准的、版本化的配方文件,busybox_1.22.1.bb,但也有一个基于 Git 的版本,busybox_git.bb,它明确包含以下行

DEFAULT_PREFERENCE = "-1"

以确保编号的稳定版本始终是首选,除非开发人员另有选择。

2.5. 依赖项(Dependencies)

每个目标 BitBake 构建都包含多个任务,例如获取、解包、打补丁、配置和编译。为了在多核系统上获得最佳性能,BitBake 将每个任务视为具有自己的一组依赖项的独立实体。

依赖关系是通过几个变量定义的。您可以在本手册末尾附近的“变量词汇表”中找到有关 BitBake 使用的变量的信息。在基本层面上,知道 BitBake 在计算依赖项时使用 DEPENDS 和 RDEPENDS 变量就足够了。

有关 BitBake 如何处理依赖项的更多信息,请参阅“依赖项”部分。

2.6. 任务列表

根据生成的提供者列表和依赖信息,BitBake 现在可以准确计算它需要运行哪些任务以及它需要以什么顺序运行它们。“执行任务”部分有更多关于 BitBake 如何选择下一步执行哪个任务的信息。

构建现在从 BitBake fork线程开始,直到 BB_NUMBER_THREADS 变量中设置的限制。只要有任务准备好运行,这些任务的所有依赖都得到满足,并且没有超过线程阈值,BitBake 就会继续fork线程。

值得注意的是,您可以通过正确设置 BB_NUMBER_THREADS 变量来大大加快构建时间。

当每个任务完成时,时间戳被写入由 STAMP 变量指定的目录。在后续运行中,BitBake 在 tmp/stamps 中的 build 目录中查找并且不会重新运行已经完成的任务,除非发现时间戳无效。目前,仅在每个配方文件的基础上考虑无效时间戳。因此,例如,如果配置标记的时间戳大于给定目标的编译时间戳,则编译任务将重新运行。但是,再次运行编译任务对依赖该目标的其他提供程序没有影响。

stamps的确切格式是部分可配置的。在现代版本的 BitBake 中,一个哈希被附加到标记上,这样如果配置发生变化,标记就会失效,任务会自动重新运行。此散列或使用的签名由配置的签名策略管理(有关信息,请参阅“校验和(签名)”部分)。还可以使用“stamp-extra-info”任务标志将额外的元数据附加到stamp。例如,OpenEmbedded 使用此标志使某些任务特定于机器。

说明
一些任务被标记为“nostamp”任务。运行这些任务时不会创建时间戳文件。因此,“nostamp”任务总是会重新运行。

有关任务的更多信息,请参阅“任务”部分。

2.7. 执行任务

任务可以是 shell 任务或 Python 任务。

对于shell任务,BitBake将shell脚本写入${T}/run.do_taskname.pid,然后执行该脚本。生成的 shell 脚本包含所有导出的变量,以及扩展所有变量的 shell 函数。shell 脚本的输出写到文件 ${T}/log.do_taskname.pid。查看运行文件中扩展的 shell 函数和日志文件中的输出是一种有用的调试技术。

对于 Python 任务,BitBake 在内部执行任务并将信息记录到控制终端。BitBake 的未来版本会将函数写入文件,类似于处理 shell 任务的方式。日志记录的处理方式也类似于 shell 任务。

BitBake 运行任务的顺序由其任务调度程序控制。可以配置调度程序并为特定用例定义自定义实现。有关更多信息,请参阅这些控制行为的变量:

  • BB_SCHEDULER
  • BB_SCHEDULERS

可以在任务的主函数之前和之后运行函数。这是使用任务的“prefuncs”和“postfuncs”标志来列出要运行的函数完成的。

2.8. 校验和(签名)

校验和是任务输入的唯一签名。任务的签名可用于确定是否需要运行任务。因为它是触发任务运行的任务输入的变化,BitBake 需要检测给定任务的所有输入。对于 shell 任务,事实证明这相当容易,因为 BitBake 为每个任务生成一个“运行”shell 脚本,并且可以创建一个校验和,让您很好地了解任务的数据何时发生变化。

使问题复杂化的是,校验和中不应包含某些内容。首先,存在给定任务的实际特定构建路径 - 工作目录。工作目录是否更改并不重要,因为它不应该影响目标包的输出。排除工作目录的简单方法是将其设置为某个固定值并为“运行”脚本创建校验和。BitBake 更进一步,并使用 BB_HASHBASE_WHITELIST 变量来定义生成签名时不应包含的变量列表。

另一个问题是“运行”脚本包含可能会或可能不会被调用的函数。增量构建解决方案包含计算 shell 函数之间依赖关系的代码。此代码用于将“运行”脚本修剪到最小集,从而缓解此问题并使“运行”脚本更具可读性作为奖励。

到目前为止,我们已经有了 shell 脚本的解决方案。Python 任务呢?即使这些任务更加困难,同样的方法也适用。该过程需要弄清楚 Python 函数访问哪些变量以及它调用哪些函数。同样,增量构建解决方案包含的代码首先计算变量和函数的依赖关系,然后为用作任务输入的数据创建校验和。

与工作目录的情况一样,存在应忽略依赖项的情况。对于这些情况,您可以使用如下所示的行指示构建过程忽略依赖项:

 PACKAGE_ARCHS[vardepsexclude] = "MACHINE"

此示例确保 PACKAGE_ARCHS 变量不依赖于 MACHINE 的值,即使它确实引用了它。

同样,在某些情况下,我们需要添加 BitBake 无法找到的依赖项。您可以使用如下所示的行来完成此操作:

  PACKAGE_ARCHS[vardeps] = "MACHINE"

此示例显式添加 MACHINE 变量作为 PACKAGE_ARCHS 的依赖项。

例如,考虑使用内联 Python 的情况,其中 BitBake 无法确定依赖项。在调试模式下运行时(即使用 -DDD),当 BitBake 发现无法确定依赖关系的东西时,它会产生输出。

到目前为止,本节的讨论仅限于对任务的直接输入。基于直接输入的信息在代码中称为“basehash”。但是,仍然存在任务的间接输入的问题 - 已经构建并存在于构建目录中的内容。特定任务的校验和(或签名)需要添加特定任务所依赖的所有任务的哈希值。选择要添加的依赖项是一项策略决定。但是,其效果是生成一个主校验和,该校验和结合了 basehash 和任务依赖项的哈希。

在代码级别,有多种方式可以影响 basehash 和相关任务哈希。在 BitBake 配置文件中,我们可以给 BitBake 一些额外的信息来帮助它构建 basehash。以下语句有效地生成了一个全局变量依赖项排除列表 - 变量从未包含在任何校验和中。此示例使用来自 OpenEmbedded 的变量来帮助说明该概念:

 BB_HASHBASE_WHITELIST ?= "TMPDIR FILE PATH PWD BB_TASKHASH BBPATH DL_DIR \
     SSTATE_DIR THISDIR FILESEXTRAPATHS FILE_DIRNAME HOME LOGNAME SHELL TERM \
     USER FILESPATH STAGING_DIR_HOST STAGING_DIR_TARGET COREBASE PRSERV_HOST \
     PRSERV_DUMPDIR PRSERV_DUMPFILE PRSERV_LOCKDOWN PARALLEL_MAKE \
     CCACHE_DIR EXTERNAL_TOOLCHAIN CCACHE CCACHE_DISABLE LICENSE_PATH SDKPKGSUFFIX"

前面的示例不包括工作目录,它是 TMPDIR 的一部分。

决定通过依赖链包含哪些依赖任务的哈希的规则更复杂,通常使用 Python 函数完成。meta/lib/oe/sstatesig.py 中的代码显示了这方面的两个示例,并且还说明了如何在需要时将自己的策略插入到系统中。该文件定义了 OpenEmbedded Core 使用的两个基本签名生成器:“OEBasic”和“OEBasicHash”。默认情况下,BitBake 中启用了一个虚拟的“noop”签名处理程序。这意味着行为与以前的版本没有变化。默认情况下,OE-Core 通过 bitbake.conf 文件中的此设置使用“OEBasicHash”签名处理程序:

 BB_SIGNATURE_HANDLER ?= "OEBasicHash"

“OEBasicHash” BB_SIGNATURE_HANDLER 与“OEBasic”版本相同,但将任务哈希添加到stamp文件中。这会导致更改任务哈希的任何元数据更改,自动导致任务再次运行。这消除了增加 PR 值的需要,并且对元数据的更改会在整个构建过程中自动波动。

还值得注意的是,这些签名生成器的最终结果是为构建提供一些依赖和哈希信息。这些信息包括:

  • BB_BASEHASH_task-taskname:配方中每个任务的基本哈希值。
  • BB_BASEHASH_filename:taskname:每个依赖任务的基本哈希值。
  • BBHAHDEPS_filename:taskname:每个任务的任务依赖关系。
  • BB_TASKHASH:当前运行任务的哈希值。

值得注意的是,BitBake 的“-S”选项可以让您调试 Bitbake 对签名的处理。传递给 -S 的选项允许使用不同的调试模式,使用 BitBake 自己的调试功能或可能在元数据/签名处理程序本身中定义的那些。要传递的最简单的参数是“none”,它会导致将一组签名信息写出到与指定目标对应的 STAMP_DIR 中。另一个当前可用的参数是“printdiff”,它会导致 BitBake 尝试建立它可以(例如在 sstate 缓存中)最接近的签名匹配,然后在匹配上运行 bitbake-diffsigs 以确定这两个stamp树的stamp和增量发散。

说明
BitBake 的未来版本很可能会提供通过附加“-S”参数触发的其他签名处理程序。

您可以在“任务校验和与设置场景”部分找到有关校验和元数据的更多信息。

2.9. 设置场景(Setscene)

setscene 过程使 BitBake 能够处理“预先构建”的工件。处理和重用这些工件的能力使 BitBake 不必每次都从头开始构建东西。相反,BitBake 可以在可能的情况下使用现有的构建工件。

BitBake 需要有可靠的数据来指示工件是否兼容。上一节中描述的签名提供了一种表示工件是否兼容的理想方式。如果签名相同,则可以重用对象。

如果一个对象可以被重用,那么问题就变成了如何用预先构建的工件替换给定的任务或任务集。BitBake 通过“setscene”过程解决了这个问题。

当 BitBake 被要求构建一个给定的目标时,在构建任何东西之前,它首先询问缓存信息是否可用于它正在构建的任何目标或任何中间目标。如果缓存信息可用,BitBake 将使用此信息而不是运行主要任务。

BitBake 首先调用由 BB_HASHCHECK_FUNCTION 变量定义的函数,其中包含要构建的任务列表和相应的哈希值。这个函数被设计得很快,并返回一个它认为可以获得工件的任务列表。

接下来,对于作为可能性返回的每个任务,BitBake 执行可能的工件覆盖的任务的场景版本。任务的 Setscene 版本将字符串“_setscene”附加到任务名称。因此,例如,名为 xxx 的任务有一个名为 xxx_setscene 的 setscene 任务。任务的 setscene 版本执行并提供返回成功或失败的必要工件。

如前所述,一个工件可以涵盖多个任务。例如,如果您已经拥有已编译的二进制文件,那么获取编译器就毫无意义。为了解决这个问题,BitBake 为每个成功的 setscene 任务调用 BB_SETSCENE_DEPVALID 函数,以了解它是否需要获取该任务的依赖项。

最后,在所有 setscene 任务执行完毕后,BitBake 调用 BB_SETSCENE_VERIFY_FUNCTION 中列出的函数以及 BitBake 认为已“覆盖”的任务列表。然后元数据可以确保这个列表是正确的,并且可以通知 BitBake 它想要运行特定的任务,而不管 setscene 结果如何。

您可以在“任务校验和与设置场景”部分中找到有关场景元数据的更多信息。

3. 语法和操作符

Bitbake 文件有自己的语法。语法与其他几种语言有相似之处,但也有一些独特的功能。本节介绍可用的语法和操作符并提供示例。

3.1. 基本语法

本节提供了一些基本的语法示例。

3.1.1. 基本变量设置(=)

以下示例设置VARIABLE为"value"。这个赋值会在语句被解析时立即发生。这是一项“艰巨”的任务。

 VARIABLE = "value"

正如预期的那样,如果您在作业中包含前导或尾随空格,则这些空格将被保留:

 VARIABLE = " value"
 VARIABLE = "value "

设置VARIABLE为 “” 将其设置为空字符串,而将变量设置为 " " 将其设置为空格(即这些值不同)。

 VARIABLE = ""
 VARIABLE = " "

3.1.2. 变量扩展

BitBake 支持使用类似于 shell 脚本的语法引用彼此内容的变量。以下示例导致 A 包含“aval”,B 根据 A 的当前值评估为“preavalpost”。

 A = "aval"
 B = "pre${A}post"

你应该意识到每当 B 被引用时,它的评估将取决于 A 在当时的状态。因此,前面示例中 B 的后续评估可能会导致不同的值,具体取决于 A 的值。

3.1.3. 设置默认值 (?=)

您可以使用“?=”操作符为变量实现“softer”的赋值。这种类型的赋值允许您在解析语句时定义未定义的变量,但如果变量有值,则不考虑该值。下面是一个例子:

 A ?= "aval"

如果在解析此语句时设置了 A,则变量将保留其值。但是,如果未设置 A,则将变量设置为“aval”。

说明
这个任务是即时的。因此,如果存在对单个变量的多个“?=”赋值,则最终会使用第一个。

3.1.4. 设置弱默认值 (??=)

通过使用“??=”操作符,可以使用比上一节中“弱(weaker)”的赋值。此赋值的行为与“?=”相同,只是在解析过程结束时而不是立即进行赋值。因此,当存在多个“??=”赋值时,将使用最后一个。此外,任何“=”或“?=”赋值都将覆盖用“??=”设置的值。下面是一个例子:

 A ??= "somevalue"
 A ??= "someothervalue"

如果在解析上述语句之前设置了 A,则变量保留其值。如果未设置 A,则将变量设置为“someothervalue”。

同样,这个赋值是一个“延迟(lazy)”或“弱(weaker)”赋值,因为它直到解析过程结束才会发生。

3.1.5. 立即变量扩展 (:=)

“:=” 操作符导致变量的内容被立即扩展,而不是在实际使用变量时:

 T = "123"
 A := "${B} ${A} test ${T}"
 T = "456"
 B = "${T} bval"
 C = "cval"
 C := "${C}append"

在此示例中,A 包含“test 123”,因为解析时 ${B} 和 ${A} 未定义,从而留下“test 123”。并且,变量 C 包含“cvalappend”,因为 ${C} 立即扩展为“cval”。

3.1.6. 用空格附加 (+=) 和前置 (=+)

附加和前置值很常见,可以使用“+=”和“=+”操作符来完成。这些操作符在当前值和前置或附加值之间插入一个空格。

这些操作符在解析过程中立即生效。这里有些例子:

 B = "bval"
 B += "additionaldata"
 C = "cval"
 C =+ "test"

变量 B 包含“bval additionaldata”,C 包含“test cval”。

3.1.7. 不带空格附加 (.=) 和前置 (=.)

如果您想在没有插入空格的情况下附加或前置值,请使用“.=”和“=.”操作符。

这些操作符在解析过程中立即生效。这里有些例子:

 B = "bval"
 B .= "additionaldata"
 C = "cval"
 C =. "test"

变量 B 包含“bvaladditionaldata”,C 包含“testcval”。

3.1.8. 附加和前置(覆盖样式语法)

您还可以使用覆盖样式语法附加和前置变量的值。使用此语法时,不会插入空格。

这些操作符与“:=”、“.=”、“=.”、“+=”和“=+”操作符的不同之处在于它们的作用被推迟到解析完成后而不是立即应用。这里有些例子:

 B = "bval"
 B_append = " additional data"
 C = "cval"
 C_prepend = "additional data "
 D = "dval"
 D_append = "additional data"

变量 B 变为“bval additional data”,C 变为“additional data cval”。变量 D 成为“dvaladditional data”。

说明
使用覆盖语法时,您必须控制所有间距。

3.1.9. 移除(覆盖样式语法)

您可以使用删除覆盖样式语法从列表中删除值。指定要删除的值会导致从变量中删除所有出现的该值。

当您使用此语法时,BitBake 需要一个或多个字符串。周围的空格也被删除。下面是一个例子:

 FOO = "123 456 789 123456 123 456 123 456"
 FOO_remove = "123"
 FOO_remove = "456"
 FOO2 = "abc def ghi abcdef abc def abc def"
 FOO2_remove = "abc def"

变量FOO变为“789 123456”并FOO2变为“ghi abcdef”。

3.1.10. 变量标志语法

变量标志是 BitBake 对变量属性或属性的实现。这是一种将额外信息标记到变量上的方法。您可以在“变量标志”部分中找到有关一般变量标志的更多信息。

您可以为变量标志定义、附加和预置值。前面提到的所有标准语法操作都适用于变量标志,除了覆盖样式语法(即 _prepend、_append 和 _remove)。

以下是一些显示如何设置变量标志的示例:

 FOO[a] = "abc"
 FOO[b] = "123"
 FOO[a] += "456"

变量 FOO 有两个标志:a 和 b。标志分别被立即设置为“abc”和“123”。a 标志变为“abc 456”。

不需要预先定义变量标志。您可以简单地开始使用它们。一个非常常见的应用是将一些简短的文档附加到 BitBake 变量,如下所示:

 CACHE[doc] = "The directory holding the cache of the metadata."

3.1.11. 内联 Python 变量扩展

您可以使用内联 Python 变量扩展来设置变量。下面是一个例子:

 DATE = "${@time.strftime('%Y%m%d',time.gmtime())}"

此示例结果是将DATE 变量设置为当前日期。

此功能最常见的用途可能是从 BitBake 的内部数据字典 d 中提取变量的值。以下几行分别选择包名称及其版本号的值:

 PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
 PV = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[1] or '1.0'}"

3.1.12. 提供路径名

指定用于 BitBake 的路径名时,请勿使用波浪号 (“~”) 字符作为主目录的快捷方式。这样做可能会导致 BitBake 无法识别路径,因为 BitBake 不会像 shell 那样扩展这个字符。

相反,请提供更完整的路径,如以下示例所示:

 BBLAYERS ?= " \
   /home/scott-lenovo/LayerA \
   ”

3.2. 条件语法(覆盖)

BitBake 使用 OVERRIDES 来控制在 BitBake 解析配方和配置文件后覆盖哪些变量。本节介绍如何使用 OVERRIDES 作为条件元数据,讨论与 OVERRIDES 相关的键(key)扩展,并提供一些示例以帮助理解。

3.2.1. 条件元数据

您可以使用 OVERRIDES 有条件地选择变量的特定版本,并有条件地附加或前置变量的值。

说明
1)覆盖只能使用小写字符。此外,覆盖名称中不允许使用下划线,因为它们用于将覆盖彼此分开以及与变量名称分开。
2)BitBake 从右到左处理条件,也就是说,右边的优先级高于左边

  • 选择变量:OVERRIDES 变量是一个冒号字符分隔的列表,其中包含您想要满足条件的项目。因此,如果您有一个以“arm”为条件的变量,并且“arm”在 OVERRIDES 中,那么将使用该变量的“arm”特定版本而不是非条件版本。下面是一个例子:

    OVERRIDES = “architecture:os:machine”
    TEST = “default”
    TEST_os = “osspecific”
    TEST_nooverride = “othercondvalue”

在此示例中,OVERRIDES 变量列出了三个覆盖:“architecture”、“os”和“machine”。变量 TEST 本身具有默认值“default”。您可以通过将“os”覆盖附加到变量 TEST(即 TEST_os)来选择 TEST 变量的特定于操作系统的版本。

为了更好地理解这一点,请考虑一个实际示例,该示例假定基于 OpenEmbedded 元数据的 Linux 内核配方文件。配方文件中的以下几行首先将内核分支变量 KBRANCH 设置为默认值,然后根据构建的体系结构有条件地覆盖该值:

 KBRANCH = "standard/base"
 KBRANCH_qemuarm  = "standard/arm-versatile-926ejs"
 KBRANCH_qemumips = "standard/mti-malta32"
 KBRANCH_qemuppc  = "standard/qemuppc"
 KBRANCH_qemux86  = "standard/common-pc/base"
 KBRANCH_qemux86-64  = "standard/common-pc-64/base"
 KBRANCH_qemumips64 = "standard/mti-malta64"
  • 追加和前置: BitBake 还支持根据特定项目是否在 OVERRIDES 中列出,对变量值进行追加和前置操作。下面是一个例子:

    DEPENDS = “glibc ncurses”
    OVERRIDES = “machine:local”
    DEPENDS_append_machine = “libmad”

在这个例子中,DEPENDS变成了“glibc ncurses libmad”。

同样,使用基于 OpenEmbedded 元数据的内核配方文件作为示例,以下几行将根据架构有条件地附加到 KERNEL_FEATURES 变量::

 KERNEL_FEATURES_append = " ${KERNEL_EXTRA_FEATURES}"
 KERNEL_FEATURES_append_qemux86=" cfg/sound.scc cfg/paravirt_kvm.scc"
 KERNEL_FEATURES_append_qemux86-64=" cfg/sound.scc cfg/paravirt_kvm.scc"

3.2.2. 键扩展

当 BitBake 数据存储在 BitBake 扩展覆盖之前完成时,会发生键扩展。为了更好地理解这一点,请考虑以下示例:

 A${B} = "X"
 B = "2"
 A2 = "Y"

在这种情况下,在所有解析完成后,在处理任何覆盖之前,BitBake 将 ${B} 扩展为“2”。该扩展导致在扩展之前设置为“Y”的 A2 变为“X”。

3.2.3. 例子

尽管前面的解释显示了变量定义的不同形式,但很难弄清楚当变量操作符、条件覆盖和无条件覆盖组合在一起时会发生什么。本节介绍了一些常见的场景,并解释了通常会使用户感到困惑的可变交互。

关于覆盖和各种“附加”操作符生效的顺序,经常会出现混淆。回想一下,使用 “_append” 和 “_prepend” 的追加或前置操作不会像 “+=”、“.=”、“=+” 或 “=.” 那样导致立即赋值。考虑以下示例:

 OVERRIDES = "foo"
 A = "Z"
 A_foo_append = "X"

对于这种情况,A 无条件设置为“Z”,而“X”无条件立即附加到变量 A_foo。由于尚未应用覆盖,因此 A_foo 由于追加而设置为“X”,而 A 仅等于“Z”。

然而,应用覆盖会改变事情。由于“foo”在 OVERRIDES 中列出,条件变量 A 被替换为“foo”版本,它等于“X”。如此有效,A_foo 替换了 A。

下一个示例更改覆盖和附加的顺序:

 OVERRIDES = "foo"
 A = "Z"
 A_append_foo = "X"

对于这种情况,在处理覆盖之前,A 设置为“Z”并且 A_append_foo 设置为“X”。但是,一旦应用了“foo”的覆盖,A 就会附加“X”。因此,A 变为“ZX”。请注意,没有附加空格。

下一个示例将追加和覆盖的顺序颠倒为第一个示例:

 OVERRIDES = "foo"
 A = "Y"
 A_foo_append = "Z"
 A_foo_append += "X"

对于这种情况,在解决任何覆盖之前,使用立即分配将 A 设置为“Y”。在此立即赋值之后,A_foo 被设置为“Z”,然后进一步附加“X”,将变量设置为“Z X”。最后,对“foo”应用覆盖会导致条件变量 A 变为“Z X”(即 A 被 A_foo 替换)。

最后一个示例混合了一些不同的操作符:

 A = "1"
 A_append = "2"
 A_append = "3"
 A += "4"
 A .= "5"

对于这种情况,当 BitBake 多次通过代码时,追加操作符的类型会影响赋值的顺序。最初,由于三个使用立即操作符的语句,A 被设置为“1 45”。完成这些分配后,BitBake 应用 _append 操作。这些操作导致 A 变为“1 4523”。

3.3. 共享功能

BitBake 允许通过包含文件 (.inc) 和类文件 (.bbclass) 共享元数据。例如,假设您有一项通用功能,例如要在多个配方之间共享的任务定义。在这种情况下,创建一个包含通用功能的 .bbclass 文件,然后在您的配方中使用 inherit 指令来继承类将是共享任务的常用方法。

本节介绍 BitBake 提供的机制,允许您在配方之间共享功能。具体来说,这些机制包括 include、inherit、INHERIT 和 require 指令。

3.3.1. 定位包含和类文件

BitBake 使用 BBPATH 变量来定位所需的包含和类文件。此外,BitBake 在当前目录中搜索 include 和 require 指令。

说明
BBPATH 变量类似于环境变量 PATH。
为了让 BitBake 找到包含文件和类文件,它们需要位于 BBPATH 中的“classes”子目录中。

3.3.2. 继承(inherit)指令

在编写配方或类文件时,您可以使用 inherit 指令来继承类 (.bbclass) 的功能。BitBake 仅在配方和类文件(即 .bb 和 .bbclass)中使用时才支持此指令。

继承指令是指定您的配方需要哪些功能类的基本方法。例如,您可以轻松地抽象出构建使用 Autoconf 和 A​​utomake 的包所涉及的任务,并将这些任务放入您的配方可以使用的类文件中。

例如,您的配方可以使用以下指令来继承 autotools.bbclass 文件。类文件将包含使用 Autotools 的通用功能,这些功能可以跨配方共享:

 inherit autotools

在这种情况下,BitBake 将在 BBPATH 中搜索目录 classes/autotools.bbclass。

说明
通过在“inherit”语句之后执行此操作,您可以覆盖配方中继承类的任何值和函数。

如有必要,可以通过在inherit 语句后使用变量表达式有条件地继承类。下面是一个例子:

 inherit ${VARNAME}

如果要设置VARNAME,则需要在解析inherit 语句之前设置它。在这种情况下实现条件继承的一种方法是使用覆盖:

 VARIABLE = ""
 VARIABLE_someoverride = "myclass"

另一种方法是使用匿名 Python。下面是一个例子:

 python () {
     if condition == value:
         d.setVar('VARIABLE', 'myclass')
     else:
         d.setVar('VARIABLE', '')
 }

或者,您可以使用以下形式的内联 Python 表达式:

 inherit ${@'classname' if condition else ''}
 inherit ${@functionname(params)}

在所有情况下,如果表达式的计算结果为空字符串,则该语句不会触发语法错误,因为它变为无操作。

3.3.3. 包含(include)指令

BitBake 理解 include 指令。该指令使 BitBake 解析您指定的任何文件,并在该位置插入该文件。该指令与 Make 中的等效指令非常相似,不同之处在于如果包含行中指定的路径是相对路径,BitBake 将定位它在 BBPATH 中可以找到的第一个文件。

例如,假设您需要一个配方来包含一些自测定义:

 include test_defs.inc

说明
当找不到文件时,include 指令不会产生错误。因此,建议如果您希望包含的文件存在,您应该使用 require 而不是 include。这样做可确保在找不到文件时产生错误。

3.3.4. 依赖(require)指令

BitBake 理解 require 指令。该指令的行为与 include 指令类似,但如果找不到要包含的文件,BitBake 会引发解析错误。因此,您需要的任何文件都被插入到指令所在位置正在解析的文件中。

类似于 BitBake 处理 include 的方式,如果在 require 行指定的路径是相对路径,BitBake 会在 BBPATH 中定位它可以找到的第一个文件。

例如,假设您有两个版本的配方(例如 foo_1.2.2.bb 和 foo_2.0.0.bb),其中每个版本都包含一些可以共享的相同功能。您可以创建一个名为 foo.inc 的包含文件,其中包含构建“foo”所需的通用定义。您需要确保 foo.inc 也与您的两个配方文件位于同一目录中。设置这些条件后,您可以使用每个配方中的 require 指令共享功能:

 require foo.inc

3.3.5. 继承(INHERIT)配置指令

创建配置文件 (.conf) 时,可以使用 INHERIT 指令来继承类。BitBake 仅在配置文件中使用时才支持此指令。

例如,假设您需要从配置文件继承一个名为 abc.bbclass 的类文件,如下所示:

 INHERIT += "abc"

此配置指令导致在解析期间在指令点继承命名类。与inherit 指令一样,.bbclass 文件必须位于BBPATH 中指定的目录之一的“classes”子目录中。

说明
因为.conf在 BitBake 的执行过程中首先解析文件,使用 INHERIT继承一个类有效地全局继承该类(即对于所有配方)。

如果要使用该指令继承多个类,可以在 local.conf 文件的同一行中提供它们。使用空格分隔类。以下示例显示了如何继承 autotools 和 pkgconfig 类:

 inherit autotools pkgconfig

3.4. 函数

与大多数语言一样,函数是用于将操作构建为任务的构建块。BitBake 支持以下类型的函数:

  • Shell 函数:用 shell 脚本编写并直接作为函数、任务或两者执行的函数。它们也可以被其他 shell 函数调用。

  • BitBake 风格的 Python 函数:用 Python 编写并由 BitBake 或其他 Python 函数使用 bb.build.exec_func() 执行的函数。

  • Python 函数:用 Python 编写并由 Python 执行的函数。

  • 匿名 Python 函数:在解析过程中自动执行的 Python 函数。

无论函数类型如何,您只能在类 (.bbclass) 和配方 (.bb 或 .inc) 文件中定义它们。

3.4.1. Shell 函数

用 shell 脚本编写并直接作为函数、任务或两者执行的函数。它们也可以被其他 shell 函数调用。下面是一个示例 shell 函数定义:

 some_function () {
     echo "Hello World"
 }

当您在配方或类文件中创建这些类型的函数时,您需要遵循 shell 编程规则。脚本由 /bin/sh 执行,它可能不是 bash shell,但可能是诸如 dash 之类的东西。您不应该使用 Bash 特定的脚本 (bashisms)。

3.4.2. BitBake 风格的 Python 函数

这些函数是用 Python 编写的,由 BitBake 或其他 Python 函数使用 bb.build.exec_func() 执行。

一个示例 BitBake 函数是:

 python some_python_function () {
     d.setVar("TEXT", "Hello World")
     print d.getVar("TEXT", True)
 }

因为 Python “bb” 和 “os” 模块已经导入,所以您不需要导入这些模块。同样在这些类型的函数中,数据存储 (“d”) 是一个全局变量,并且始终自动可用。

说明
变量表达式(例如 ${X})不再在 Python 函数中展开。这种行为是有意的,目的是让您可以自由地将变量值设置为可扩展表达式,而不会过早地扩展它们。如果您确实希望在 Python 函数中扩展变量,请使用 d.getVar(“X”, True)。或者,对于更复杂的表达式,使用 d.expand()。

3.4.3. Python 函数

这些函数是用 Python 编写的,并由其他 Python 代码执行。Python 函数的示例是您打算从内嵌 Python 或其他 Python 函数中调用的实用程序函数。下面是一个例子:

 def get_depends(d):
     if d.getVar('SOMECONDITION', True):
         return "dependencywithcond"
     else:
         return "dependency"
 SOMECONDITION = "1"
 DEPENDS = "${@get_depends(d)}"

这将导致 DEPENDS 包含 dependencywithcond。

以下是有关 Python 函数的一些注意事项:

  • Python 函数可以带参数。

  • BitBake 数据存储不会自动可用。因此,您必须将其作为参数传递给函数。

  • “bb” 和 “os” Python 模块自动可用。您不需要导入它们。

3.4.4. 匿名 Python 函数

有时在解析期间运行一些代码以设置变量或以编程方式执行其他操作很有用。为此,您可以定义一个匿名 Python 函数。这是一个基于另一个变量的值有条件地设置变量的示例:

 python __anonymous () {
     if d.getVar('SOMEVAR', True) == 'value':
         d.setVar('ANOTHERVAR', 'value2')
 }

“__anonymous”函数名是可选的,所以下面的例子在功能上等同于上面的:

 python () {
     if d.getVar('SOMEVAR', True) == 'value':
         d.setVar('ANOTHERVAR', 'value2')
 }

因为与其他 Python 函数不同,匿名 Python 函数是在解析过程中执行的,所以匿名 Python 函数中的“d”变量代表整个配方的数据存储。因此,您可以在此处设置变量值,这些值可以由其他函数获取。

3.4.5. 类函数的灵活继承

通过编码技术和 EXPORT_FUNCTIONS 的使用,BitBake 支持从类中导出函数,使得类函数作为函数的默认实现出现,但如果继承类的配方需要定义自己的版本功能。

要了解此功能的好处,请考虑一个类定义任务函数并且您的配方继承该类的基本场景。在这个基本场景中,您的配方继承了类中定义的任务函数。如果需要,您的配方可以分别使用“_prepend”或“_append”操作添加到函数的开头和结尾,或者可以完全重新定义函数。但是,如果它重新定义了该函数,则它无法调用该函数的类版本。EXPORT_FUNCTIONS 提供了一种机制,使函数的配方版本能够调用函数的原始版本。

要使用此技术,您需要准备好以下内容:

  • 该类需要定义函数如下:

    classname_functionname

例如,如果您有一个类文件 bar.bbclass 和一个名为 do_foo 的函数,则该类必须按如下方式定义该函数:

 bar_do_foo
  • 该类需要包含 EXPORT_FUNCTIONS 语句,如下所示:

    EXPORT_FUNCTIONS functionname

例如,继续同一个例子,bar.bbclass 中的语句如下:

 EXPORT_FUNCTIONS do_foo
  • 您需要从您的配方中适当地调用该函数。继续同一个例子,如果你的配方需要调用函数的类版本,它应该调用 bar_do_foo。假设 do_foo 是一个 shell 函数并且 EXPORT_FUNCTIONS 被使用,那么配方的函数可以有条件地调用函数的类版本,如下所示:

    do_foo() {
    if [ somecondition ] ; then
    bar_do_foo
    else
    # Do something else
    fi
    }

要调用配方中定义的函数的修改版本,请将其命名为 do_foo。

满足这些条件后,您的单个配方可以在类文件中定义的原始函数和配方中修改后的函数之间自由选择。如果不设置这些条件,则只能使用一种功能或另一种功能。

3.5. 任务

任务是作为函数发起的 BitBake 执行单元,并构成 BitBake 需要为给定配方运行的步骤。任务仅在配方(.bb 或 .inc)和类(.bbclass)文件中受支持。按照惯例,任务名称以字符串“do_”开头。

以下是打印日期的任务示例:

 python do_printdate () {
     import time
     print time.strftime('%Y%m%d', time.gmtime())
 }
 addtask printdate after do_fetch before do_build

3.5.1. 将函数提升为任务

任何函数都可以通过应用 addtask 命令提升为任务。addtask 命令还描述了任务间的依赖关系。这是上一节中的函数,但使用 addtask 命令将其提升为任务并定义了一些依赖项:

 python do_printdate () {
     import time
     print time.strftime('%Y%m%d', time.gmtime())
 }
 addtask printdate after do_fetch before do_build

在示例中,函数被定义,然后被提升为任务。do_printdate 任务成为 do_build 任务的依赖项,它是默认任务。并且,do_printdate 任务依赖于 do_fetch 任务。do_build 任务的执行导致首先运行 do_printdate 任务。

3.5.2. 删除任务

除了能够添加任务,您还可以删除它们。只需使用 deltask 命令即可删除任务。例如,要删除前面部分中使用的示例任务,您可以使用:

 deltask printdate

如果使用 deltask 命令删除任务并且该任务具有依赖关系,则不会重新连接依赖关系。例如,假设您有三个名为 do_a、do_b 和 do_c 的任务。此外,do_c 依赖于 do_b,而 do_b 又依赖于 do_a。鉴于这种情况,如果使用deltask删除do_b,那么do_c和do_a通过do_b的隐式依赖关系不再存在,do_c依赖也不会更新为包含do_a。因此,do_c 可以在 do_a 之前自由运行。

如果您希望这些依赖项保持完整,请使用 noexec varflag 禁用任务,而不是使用 deltask 命令删除它:

 do_b[noexec] = "1"

3.5.3. 将信息传递到构建任务环境中

运行任务时,BitBake严格控制构建任务的shell执行环境,以确保来自构建机器的不希望的污染不会影响构建。

说明
默认情况下,BitBake 会清理环境以仅包含导出或列出在其白名单中的内容,以确保构建环境可重现且一致。您可以通过设置 BB_PRESERVE_ENV 变量来防止这种“清理”。

因此,如果您确实希望将某些内容传递到构建任务环境中,则必须执行以下两个步骤:

  • 告诉 BitBake 将您想要从环境中加载到数据存储中。您可以通过 BB_ENV_WHITELIST 和 BB_ENV_EXTRAWHITE 变量来实现。例如,假设您想阻止构建系统访问您的 $HOME/.ccache 目录。以下命令将环境变量 CCACHE_DIR 列入白名单,导致 BitBack 允许该变量进入数据存储:

    export BB_ENV_EXTRAWHITE=“$BB_ENV_EXTRAWHITE CCACHE_DIR”

  • 告诉 BitBake 将您加载到数据存储中的内容导出到每个正在运行的任务的任务环境中。将环境中的某些内容加载到数据存储中(上一步)只会使其在数据存储中可用。要将其导出到每个正在运行的任务的任务环境,请在本地配置文件 local.conf 或分发配置文件中使用类似于以下内容的命令:

    export CCACHE_DIR

说明
前面步骤的副作用是 BitBake 将变量记录为构建过程的依赖项,例如 setscene 校验和。如果这样做会导致不必要的任务重建,您可以将变量列入白名单,以便 setscene 代码在创建校验和时忽略依赖项。

有时,能够从原始执行环境中获取信息很有用。Bitbake 将原始环境的副本保存到名为 BB_ORIGENV 的特殊变量中。

BB_ORIGENV 变量返回一个数据存储对象,可以使用标准数据存储操作符(例如 getVar(, False))查询该对象。例如,数据存储对象可用于查找原始 DISPLAY 变量。下面是一个例子:

 origenv = d.getVar("BB_ORIGENV", False)
 bar = origenv.getVar("BAR", False)

前面的示例从原始执行环境返回 BAR。

3.6. 变量标志

变量标志 (varflags) 有助于控制任务的功能和依赖关系。BitBake 使用以下命令形式将 varflags 读取和写入数据存储:

 variable= d.getVarFlags(" variable")
 self.d.setVarFlags("FOO", {"func": True})

使用 varflags 时,应用相同的语法,但覆盖除外。换句话说,您可以像变量一样设置、附加和前置 varflags。有关详细信息,请参阅“变量标志语法”部分。

BitBake 有一组已定义的 varflags 可用于配方和类。任务支持许多控制任务的各种功能的标志:

  • cleandirs:应在任务运行之前创建的空目录。

  • depends:控制任务间的依赖关系。有关详细信息,请参阅 DEPENDS 变量和“任务间依赖关系”部分。

  • deptask:控制任务构建时的依赖关系。有关详细信息,请参阅 DEPENDS 变量和“构建依赖项”部分。

  • dirs:在任务运行之前应该创建的目录。列出的最后一个目录将用作任务的工作目录。

  • lockfiles:指定在任务执行时要锁定的一个或多个锁文件。只有一个任务可以持有一个锁定文件,任何试图锁定一个已经锁定的文件的任务都会阻塞,直到锁定被释放。您可以使用此变量标志来实现互斥。

  • noexec:将任务标记为空且不需要执行。noexec 标志可用于将任务设置为依赖项占位符,或禁用在其他地方定义的在特定配方中不需要的任务。

  • nostamp:告诉 BitBake 不为任务生成戳文件,这意味着该任务应该始终被执行。

  • postfuncs:任务完成后调用的函数列表。

  • prefuncs:任务执行前要调用的函数列表。

  • rdepends:控制任务间运行时依赖关系。有关详细信息,请参阅 RDEPENDS 变量、RRECOMMENDS 变量和“任务间依赖关系”部分。

  • rdeptask:控制任务运行时依赖。有关详细信息,请参阅 RDEPENDS 变量、RRECOMMENDS 变量和“运行时依赖项”部分。

  • recideptask:与 recrdeptask 一起设置时,指定应检查附加依赖项的任务。

  • recrdeptask:控制任务递归运行时依赖项。有关详细信息,请参阅 RDEPENDS 变量、RRECOMMENDS 变量和“递归依赖项”部分。

  • stamp-extra-info:附加到任务标记的额外标记信息。例如,OpenEmbedded 使用此标志来允许特定于机器的任务。

  • umask:在其下运行任务的 umask。

几个 varflags 可用于控制如何为变量计算签名。有关此过程的更多信息,请参阅“校验和(签名)”部分。

  • vardeps:指定以空格分隔的附加变量列表,以添加到变量的依赖项以计算其签名。向此列表添加变量很有用,例如,当函数以不允许 BitBake 自动确定引用变量的方式引用变量时。

  • vardepsexclude:指定一个以空格分隔的变量列表,为了计算其签名,这些变量应该从变量的依赖项中排除。

  • vardepvalue:如果设置,则指示 BitBake 在计算变量签名时忽略变量的实际值而使用指定的值。

  • vardepvalueexclude:指定在计算变量签名时要从变量值中排除的以管道分隔的字符串列表。

3.7. 事件

BitBake 允许在配方和类文件中安装事件处理程序。事件在操作期间的某些点触发,例如针对给定配方(*.bb 文件)的操作开始、给定任务的开始、任务失败、任务成功等。其目的是使诸如构建失败时的电子邮件通知之类的事情变得容易。

以下是打印事件名称和 FILE 变量内容的示例事件处理程序:

 addhandler myclass_eventhandler
 python myclass_eventhandler() {
     from bb.event import getName
     from bb import data
     print("The name of the Event is %s" % getName(e))
     print("The file we run for is %s" % data.getVar('FILE', e.data, True))
 }

每次触发事件时都会调用此事件处理程序。定义了一个全局变量“e”,“e.data”包含一个“bb.data”的实例。使用 getName(e) 方法,可以获得触发事件的名称。

因为您可能只对事件的一个子集感兴趣,所以您可能会对事件处理程序使用 [eventmask] 标志,以确保只有某些事件触发处理程序。鉴于前面的示例,假设您只希望 bb.build.TaskFailed 事件触发该事件处理程序。使用标志如下:

 addhandler myclass_eventhandler
 myclass_eventhandler[eventmask] = "bb.build.TaskFailed"
 python myclass_eventhandler() {
     from bb.event import getName
     from bb import data
     print("The name of the Event is %s" % getName(e))
     print("The file we run for is %s" % data.getVar('FILE', e.data, True))
 }

在标准构建期间,可能会发生以下常见事件:

  • bb.event.ConfigParsed()

  • bb.event.ParseStarted()

  • bb.event.ParseProgress()

  • bb.event.ParseCompleted()

  • bb.event.BuildStarted()

  • bb.build.TaskStarted()

  • bb.build.TaskInvalid()

  • bb.build.TaskFailedSilent()

  • bb.build.TaskFailed()

  • bb.build.TaskSucceeded()

  • bb.event.BuildCompleted()

  • bb.cooker.CookerExit()

以下是根据对服务器的特定请求发生的其他事件的列表:

  • bb.event.TreeDataPreparationStarted()

  • bb.event.TreeDataPreparationProgress

  • bb.event.TreeDataPreparationCompleted

  • bb.event.DepTreeGenerated

  • bb.event.CoreBaseFilesFound

  • bb.event.ConfigFilePathFound

  • bb.event.FilesMatchingFound

  • bb.event.ConfigFilesFound

  • bb.event.TargetsTreeGenerated

3.8. 变体 - 类扩展机制

BitBake 支持两个功能,这些功能有助于从单个配方文件创建该配方文件的多个化身,其中所有化身都是可构建的。这些功能是通过 BBCLASSEXTEND 和 BBVERSIONS 变量启用的。

说明
此类扩展的机制非常特定于实现。通常,配方的 PROVIDES、PN 和 DEPENDS 变量需要由扩展类修改。有关特定示例,请参阅 OE-Core native、nativesdk 和 multilib 类。

BBCLASSEXTEND:这个变量是一个空格分隔的类列表,用于“扩展”每个变体的配方。这是一个导致当前配方的第二个化身可用的示例。第二个化身将继承“native”类。

 BBCLASSEXTEND = "native"

BBVERSIONS:此变量允许单个配方从单个配方文件构建项目的多个版本。您还可以为单个版本或可选命名的版本范围指定条件元数据(使用 OVERRIDES 机制)。下面是一个例子:

 BBVERSIONS = "1.0 2.0 git"
 SRC_URI_git = "git://someurl/somepath.git"

 BBVERSIONS = "1.0.[0-6]:1.0.0+ \ 1.0.[7-9]:1.0.7+"
 SRC_URI_append_1.0.7+ = "file://some_patch_which_the_new_versions_need.patch;patch=1"

范围的名称默认为配方的原始版本。例如,在 OpenEmbedded 中,配方文件 foo_1.0.0+.bb 创建的默认名称范围为 1.0.0+。这很有用,因为范围名称不仅被放置在覆盖中,而且它也可用于元数据以在定义用于 file:// 搜索路径 (FILESPATH) 的基本配方版本的变量中使用。

3.9. 依赖项

为了在多个进程并行执行的情况下进行高效操作,BitBake 在任务级别处理依赖项。BitBake 支持一种强大的方法来处理这些依赖项。

本节描述了几种类型的依赖机制。

3.9.1. .bb文件内部的依赖项

BitBake 使用 addtask 指令来管理给定配方文件内部的依赖项。您可以使用 addtask 指令来指示任务何时依赖于其他任务或其他任务何时依赖于该配方。下面是一个例子:

 addtask printdate after do_fetch before do_build

在这个例子中,printdate 任务依赖于 do_fetch 任务的完成。并且,do_build 依赖于 printdate 任务的完成。

3.9.2. 构建时依赖项

BitBake 使用 DEPENDS 变量来管理构建时依赖项。任务的“deptask”varflag 表示 DEPENDS 中列出的每个项目的任务,必须在该任务执行之前完成。下面是一个例子:

 do_configure[deptask] = "do_populate_sysroot"

在这个例子中,DEPENDS 中每一项的 do_populate_sysroot 任务必须在 do_configure 执行之前完成。

3.9.3. 运行时依赖

BitBake 使用 PACKAGES、RDEPENDS 和 RRECOMMENDS 变量来管理运行时依赖项。

PACKAGES 变量列出运行时包。这些包中的每一个都可以具有 RDEPENDS 和 RRECOMMENDS 运行时依赖项。任务的“rdeptask”标志用于表示每个项目运行时依赖项的任务,该任务必须在该任务执行之前完成。

 do_package_qa[rdeptask] = "do_packagedata"

在前面的示例中,RDEPENDS 中每个项目的 do_packagedata 任务必须已完成,才能执行 do_package_qa。

3.9.4. 递归依赖

BitBake 使用“recrdeptask”标志来管理递归任务依赖项。BitBake 查看当前配方的构建时和运行时依赖项,查看任务的任务间依赖项,然后为列出的任务添加依赖项。一旦 BitBake 完成了这一点,它就会递归地处理这些任务的依赖关系。迭代过程继续,直到发现并添加所有依赖项。

您可能不仅希望 BitBake 查找这些任务的依赖项,还希望 BitBake 查找相关任务的构建时和运行时依赖项。如果是这种情况,您需要在任务列表中引用任务名称本身:

 do_a[recrdeptask] = "do_a do_b"

3.9.5. 任务间依赖

BitBake 以更通用的形式使用“depends”标志来管理任务间的依赖关系。这种更通用的形式允许对特定任务进行相互依赖检查,而不是检查 DEPENDS 中的数据。下面是一个例子:

 do_patch[depends] = "quilt-native:do_populate_sysroot"

在这个例子中,目标 quilt-native 的 do_populate_sysroot 任务必须在 do_patch 任务可以执行之前完成。

“rdepends”标志以类似的方式工作,但在运行时命名空间而不是构建时依赖命名空间中采用目标。

3.10. 使用 Python 访问数据存储变量

通常需要使用 Python 函数访问 BitBake 数据存储中的变量。Bitbake 数据存储有一个允许您进行此访问的 API。以下是可用操作的列表:

操作说明
d.getVar(“X”, expand=False)返回变量“X”的值。使用“expand=True”扩展值。
d.setVar(“X”, “value”)将变量“X”设置为“value”。
d.appendVar(“X”, “value”)将“value”添加到变量“X”的末尾。
d.prependVar(“X”, “value”)将“value”添加到变量“X”的开头。
d.delVar(“X”)从数据存储中删除变量“X”。
d.renameVar(“X”, “Y”)将变量“X”重命名为“Y”。
d.getVarFlag(“X”, flag, expand=False)从变量“X”中获取命名标志。使用“expand=True”扩展命名标志。
d.setVarFlag(“X”, flag, “value”)将变量“X”的命名标志设置为“value”。
d.appendVarFlag(“X”, flag, “value”)将“value”附加到变量“X”上的命名标志。
d.prependVarFlag(“X”, flag, “value”)在变量“X”的命名标志前添加“value”。
d.delVarFlag(“X”, flag)从数据存储中删除变量“X”上的命名标志。
d.setVarFlags(“X”, flagsdict)设置 flagsdict() 参数中指定的标志。setVarFlags 不会清除以前的标志。将此操作视为 addVarFlags。
d.getVarFlags(“X”)返回变量“X”的标志的flagsdict。
d.delVarFlags(“X”)删除变量“X”的所有标志。
d.expand(expression)扩展指定字符串表达式中的变量引用。

3.11. 任务校验和与设置场景

BitBake 使用校验和(或签名)和 setscene 来确定是否需要运行任务。本节介绍该过程。为了帮助理解 BitBake 如何做到这一点,本节假设一个基于 OpenEmbedded 元数据的示例。

此列表是本手册以前工作中存在的内容的占位符。它的部分或全部可能需要集成到组成本节的小节中。现在,我只是为每个变量提供了一个类似于词汇表的简短描述。最终,这个列表消失了。

  • STAMP:创建stamp文件的基本路径。

  • STAMPCLEAN 同样,创建stamp文件的基本路径,但可以使用通配符来匹配一系列文件以进行清理操作。

  • BB_STAMP_WHITELIST 列出当stamp策略为“白名单”时查看的stamp文件。

  • BB_STAMP_POLICY 定义比较stamp文件时间戳的方式。

  • BB_HASHCHECK_FUNCTION 指定在任务执行的“setscene”部分调用的函数名称,以验证任务哈希列表。

  • BB_SETSCENE_VERIFY_FUNCTION 指定要调用的函数,该函数在主任务执行发生之前验证计划的任务执行列表。

  • BB_SETSCENE_DEPVALID 指定 BitBake 调用的函数,该函数确定 BitBake 是否需要满足 setscene 依赖项。

  • BB_TASKHASH 在一个正在执行的任务中,该变量保存当前启用的签名生成器返回的任务的哈希值。

4. 文件下载支持

BitBake 的 fetch 模块是一段独立的库代码,用于处理从远程系统下载源代码和文件的复杂性。获取源代码是构建软件的基石之一。因此,该模块构成了 BitBake 的重要组成部分。

当前的 fetch 模块称为“fetch2”,指的是它是 API 的第二个主要版本。原始版本已过时并已从代码库中删除。因此,在所有情况下,“fetch”在本手册中都是指“fetch2”。

4.1. 下载 (Fetch)

BitBake 在获取源代码或文件时需要执行几个步骤。fetcher 代码库按顺序处理两个不同的过程:从某处(缓存或其他方式)获取文件,然后将这些文件解包到特定位置,也许会以特定方式。获取和解压文件后通常可选地进行打补丁。但是,此模块不包括打补丁。

执行这个过程的第一部分的代码,一个 fetch,看起来像下面这样:

 src_uri = (d.getVar('SRC_URI', True) or "").split()
 fetcher = bb.fetch2.Fetch(src_uri, d)
 fetcher.download()

此代码设置 fetch 类的实例。该实例使用来自 SRC_URI 变量的以空格分隔的 URL 列表,然后调用下载方法来下载文件。

fetch 类的实例化后通常是:

 rootdir = l.getVar('WORKDIR', True)
 fetcher.unpack(rootdir)

此代码将下载的文件解压到 WORKDIR 指定的位置。

说明
为方便起见,这些示例中的命名与 OpenEmbedded 使用的变量相匹配。如果您想查看上述代码的实际效果,请检查 OpenEmbedded 类文件 base.bbclass。

SRC_URI 和 WORKDIR 变量没有硬编码到获取器中,因为可以(并且)使用不同的变量名称调用这些获取器方法。例如,在 OpenEmbedded 中,共享状态 (sstate) 代码使用 fetch 模块来获取 sstate 文件。

当调用 download() 方法时,BitBake 尝试通过按特定搜索顺序查找源文件来解析 URL:

  • 预镜像站点: BitBake 首先使用预镜像来尝试查找源文件。这些位置是使用PREMIRRORS 变量定义的 。

  • 源 URI: 如果预镜像失败,BitBake 使用原始 URL(例如 from SRC_URI)。

  • 镜像站点: 如果发生获取失败,BitBake 接下来使用MIRRORS 变量定义的镜像位置 。

对于传递给 fetcher 的每个 URL,fetcher 调用处理该特定 URL 类型的子模块。当您为 SRC_URI 变量提供 URL 时,这种行为可能会导致一些混乱。考虑以下两个 URL:

 http://git.yoctoproject.org/git/poky;protocol=git
 git://git.yoctoproject.org/git/poky;protocol=http

在前一种情况下,URL 被传递给 wget fetcher,它不理解“git”。因此,后一种情况是正确的形式,因为 Git fetcher 确实知道如何使用 HTTP 作为传输。

以下是一些显示常用镜像定义的示例:

 PREMIRRORS ?= "\
     bzr://.*/.*   http://somemirror.org/sources/ \n \
     cvs://.*/.*   http://somemirror.org/sources/ \n \
     git://.*/.*   http://somemirror.org/sources/ \n \
     hg://.*/.*    http://somemirror.org/sources/ \n \
     osc://.*/.*   http://somemirror.org/sources/ \n \
     p4://.*/.*    http://somemirror.org/sources/ \n \
     svn://.*/.*   http://somemirror.org/sources/ \n"

 MIRRORS =+ "\
     ftp://.*/.*      http://somemirror.org/sources/ \n \
     http://.*/.*     http://somemirror.org/sources/ \n \
     https://.*/.*    http://somemirror.org/sources/ \n"

值得注意的是,BitBake 支持跨 URL。可以将 HTTP 服务器上的 Git 存储库镜像为 tarball。这就是前面示例中的 git:// 映射所做的。

由于网络访问速度较慢,Bitbake 维护了从网络下载的文件的缓存。任何非本地源文件(即从 Internet 下载)都放置在下载目录中,该目录由 DL_DIR 变量指定。

文件完整性对于复制构建至关重要。对于非本地存档下载,fetcher 代码可以验证 SHA-256 和 MD5 校验和,以确保存档已正确下载。您可以通过使用带有适当 varflags 的 SRC_URI 变量来指定这些校验和,如下所示:

 SRC_URI[md5sum] = "value"
 SRC_URI[sha256sum] = "value"

您还可以将校验和指定为 SRC_URI 上的参数,如下所示:

 SRC_URI = "http://example.com/foobar.tar.bz2;md5sum=4a8e0f237e961fd7785d19d07fdb994d"

如果存在多个 URI,您可以像前面的示例一样直接指定校验和,也可以命名 URL。以下语法显示了如何命名 URI:

 SRC_URI = "http://example.com/foobar.tar.bz2;name=foo"
 SRC_URI[foo.md5sum] = 4a8e0f237e961fd7785d19d07fdb994d

下载文件并检查其校验和后,DL_DIR 中会放置一个“.done”戳记。BitBake 在后续构建期间使用此戳记,以避免再次下载或比较文件的校验和。

说明
假设本地存储不会损坏数据。如果不是这种情况,就会有更大的问题需要担心。

如果设置了 BB_STRICT_CHECKSUM,则任何没有校验和的下载都会触发错误

4.2. 解包

解包过程通常会在下载后立即进行。对于除 Git URL 之外的所有 URL,BitBake 使用通用解包方法。

您可以在 URL 中指定许多参数来控制解包阶段的行为:

  • unpack:控制是否对 URL 组件进行解包。如果设置为“1”(这是默认值),则组件将被解包。如果设置为“0”,解包阶段将单独保留文件。当您希望将存档复制到其中而不是解压缩时,此参数很有用。

  • dos:适用于.zip 和.jar 文件,指定是否对文本文件使用DOS 行尾转换。

  • basepath:指示解包阶段在解包时从源路径中剥离指定的目录。

  • subdir:将特定 URL 解压到根目录中的指定子目录。

  • unpack 调用会自动解压和提取带有“.Z”、“.z”、“.gz”、“.xz”、“.zip”、“.jar”、“.ipk”、“.rpm”的文件。“.srpm”、“.deb”和“.bz2”扩展名以及tarball扩展名的各种组合。

如前所述,Git fetcher 有自己的解包方法,该方法经过优化以与 Git 树一起使用。基本上,此方法的工作原理是将树克隆到最终目录中。该过程使用引用完成,因此只需要一个 Git 元数据的中央副本。

4.3. 获取器

如前所述,URL 前缀决定了 BitBake 使用哪个 fetcher 子模块。每个子模块可以支持不同的 URL 参数,这些参数将在以下部分进行描述。

4.3.1. 本地文件获取器 ( file://)

该子模块处理以 file:// 开头的 URL。您在 URL 中指定的文件名可以是文件的绝对路径或相对路径。如果文件名是相对的,则 FILESPATH 变量的内容的使用方式与 PATH 用于查找可执行文件的方式相同。如果失败,则 FILESDIR 用于查找适当的相关文件。

说明
FILESDIR 已弃用,可以替换为 FILESPATH。由于 FILESDIR 可能会被删除,因此您不应在任何新代码中使用此变量。
如果找不到该文件,则假定在调用 download() 方法时该文件在 DL_DIR 中可用。

如果指定目录,则整个目录都将被解压。

下面是几个示例 URL,第一个是相对的,第二个是绝对的:

 SRC_URI = "file://relativefile.patch"
 SRC_URI = "file:///Users/ich/very_important_software"

4.3.2. HTTP/FTP wget fetcher ( http://, ftp://, https://)

此获取器从 Web 和 FTP 服务器获取文件。在内部,fetcher 使用 wget 实用程序。

使用的可执行文件和参数由 FETCHCMD_wget 变量指定,该变量默认为合理值。fetcher 支持参数“downloadfilename”,允许指定下载文件的名称。在处理多个具有相同名称的文件时,指定下载文件的名称对于避免 DL_DIR 中的冲突很有用。

一些示例 URL 如下所示:

 SRC_URI = "http://oe.handhelds.org/not_there.aac"
 SRC_URI = "ftp://oe.handhelds.org/not_there_as_well.aac"
 SRC_URI = "ftp://you@oe.handhelds.org/home/you/secret.plan"

说明
由于 URL 参数由分号分隔,因此在解析还包含分号的 URL 时,这可能会导致歧义,例如:
SRC_URI = “http://abc123.org/git/?p=gcc/gcc.git;a=snapshot;h=a5dd47”

应通过将分号替换为“&”字符来修改此类 URL:
SRC_URI = “http://abc123.org/git/?p=gcc/gcc.git&a=snapshot&h=a5dd47”

在大多数情况下,这应该有效。万维网联盟 (W3C) 建议对查询中的分号和“&”进行相同的处理。请注意,由于 URL 的性质,您可能还必须指定下载文件的名称:
SRC_URI = “http://abc123.org/git/?p=gcc/gcc.git&a=snapshot&h=a5dd47;down​​loadfilename=myfile.bz2”

4.3.3. CVS 获取器 ( (cvs://)

这个子模块处理从 CVS 版本控制系统检出文件。您可以使用许多不同的变量对其进行配置:

  • FETCHCMD_cvs:运行 cvs 命令时要使用的可执行文件的名称。这个名字通常是“cvs”。

  • SRCDATE:获取 CVS 源代码时使用的日期。“now”的特殊值会导致每次构建时更新检出。

  • CVSDIR:指定临时结帐的保存位置。位置通常是 DL_DIR/cvs。

  • CVS_PROXY_HOST:用作 cvs 命令的“proxy=”参数的名称。

  • CVS_PROXY_PORT:用作 cvs 命令的“proxyport=”参数的端口号。

除了标准的用户名和密码 URL 语法,您还可以使用各种 URL 参数配置 fetcher:

支持的参数如下:

  • “method”:与 CVS 服务器通信的协议。默认情况下,此协议为“pserver”。如果“method”设置为“ext”,BitBake 会检查“rsh”参数并设置 CVS_RSH。您可以将“dir”用于本地目录。

  • “module”:指定要检出的模块。您必须提供此参数。

  • “tag”:描述应该使用哪个 CVS TAG 进行结帐。默认情况下,TAG 为空。

  • “date”:指定日期。如果未指定“date”,则使用配置的 SRCDATE 签出特定日期。“now”的特殊值会导致每次构建时更新检出。

  • “localdir”:用于重命名模块。实际上,您正在重命名模块解压缩到的输出目录。您正在强制模块进入一个相对于 CVSDIR 的特殊目录。

  • “rsh” 与 “method” 参数结合使用。

  • “scmdata”:当设置为“keep”时,使 CVS 元数据保存在 fetcher 创建的 tarball 中。tarball 被扩展到工作目录中。默认情况下,会删除 CVS 元数据。

  • “fullpath”:控制结果检出是在模块级别(这是默认值)还是在更深的路径中。

  • “norecurse”:使获取器仅检出指定目录,而不会递归到任何子目录。

  • “port”:CVS 服务器连接的端口。

一些示例 URL 如下所示:

 SRC_URI = "cvs://CVSROOT;module=mymodule;tag=some-version;method=ext"
 SRC_URI = "cvs://CVSROOT;module=mymodule;date=20060126;localdir=usethat"

4.3.4. Subversion (SVN) 获取器 ( svn://)

这个 fetcher 子模块从 Subversion 源代码控制系统中获取代码。使用的可执行文件由 FETCHCMD_svn 指定,默认为“svn”。fetcher 的临时工作目录由 SVNDIR 设置,通常是 DL_DIR/svn。

支持的参数如下:

  • “module”:要签出的 svn 模块的名称。您必须提供此参数。您可以将此参数视为您想要的存储库数据的顶级目录。

  • “protocol”:要使用的协议,默认为“svn”。其他选项是“svn+ssh”和“rsh”。对于“rsh”,还使用“rsh”参数。

  • “rev”:要签出的源代码的修订版。

  • “date”:要签出的源代码的日期。特定修订通常比按日期更安全,因为它们不涉及时区(例如,它们更具确定性)。

  • “scmdata”:当设置为“keep”时,使“.svn”目录在编译时可用。默认情况下,这些目录被删除。

  • “transportuser”:需要时,设置传输的用户名。默认情况下,该参数为空。传输用户名与传递给 subversion 命令的主 URL 中使用的用户名不同。

以下是使用 svn 的两个示例:

 SRC_URI = "svn://svn.oe.handhelds.org/svn;module=vip;proto=http;rev=667"
 SRC_URI = "svn://svn.oe.handhelds.org/svn/;module=opie;proto=svn+ssh;date=20060126"

4.3.5. Git 获取器 ( git://)

这个 fetcher 子模块从 Git 源代码控制系统中获取代码。fetcher 通过在 GITDIR(通常是 DL_DIR/git2)中创建远程的裸克隆来工作。当特定树被检出时,这个裸克隆然后在解包阶段被克隆到工作目录中。这是通过使用替代和引用来完成的,以最大限度地减少磁盘上的重复数据量并加快解包过程。可以使用 FETCHCMD_git 设置所使用的可执行文件。

此获取器支持以下参数:

  • “protocol”:用于获取文件的协议。设置主机名时,默认值为“git”。如果未设置主机名,则 Git 协议为“文件”。您还可以使用“http”、“https”、“ssh”和“rsync”。

  • “nocheckout”:当设置为“1”时,告诉获取器在解包时不检出源代码。为存在检出代码的自定义例程的 URL 设置此选项。默认值为“0”。

  • “rebaseable”: 表示上游 Git 仓库可以 rebase。如果修订可以与分支分离,您应该将此参数设置为“1”。在这种情况下,源镜像 tarball 是每次修订完成的,这会降低效率。重新调整上游 Git 存储库可能会导致当前修订版从上游存储库中消失。此选项提醒 fetcher 小心地保留本地缓存以备将来使用。此参数的默认值为“0”。

  • “nobranch”:告诉获取器在设置为“1”时不检查分支的 SHA 验证。默认值为“0”。为引用对标记而不是分支有效的提交的配方设置此选项。

  • “bareclone”:告诉 fetcher 将一个裸克隆克隆到目标目录中,而不检查工作树。仅提供原始 Git 元数据。此参数也暗示“nocheckout”参数。

  • “branch”:要克隆的 Git 树的分支。如果未设置,则假定为“主”。分支参数的数量与名称参数的数量非常匹配。

  • “rev”:用于结帐的修订。默认为“主”。

  • “tag”:指定用于结帐的标签。为了正确解析标签,BitBake 必须访问网络。因此,通常不使用标签。就 Git 而言,“tag”参数的行为与“rev”参数相同。

  • “subpath”:将结帐限制为树的特定子路径。默认情况下,整个树被检出。

  • “destsuffix”:放置结帐的路径的名称。默认情况下,路径是 git/。

以下是一些示例 URL:

 SRC_URI = "git://git.oe.handhelds.org/git/vip.git;tag=version-1"
 SRC_URI = "git://git.oe.handhelds.org/git/vip.git;protocol=http"

4.3.6. Git 子模块获取器 ( gitsm://)

此 fetcher 子模块继承自 Git fetcher,并通过获取存储库的子模块来扩展该 fetcher 的行为。SRC_URI 被传递给 Git fetcher,如“Git Fetcher (git://)”部分所述。

注意事项和警告
在“git://”和“gitsm://” URL 之间切换时,您必须清理配方。

Git Submodules fetcher 不是一个完整的 fetcher 实现。fetcher 存在一些已知问题,即它没有正确使用正常的源镜像基础设施。

4.3.7. ClearCase 获取器 ( ccrc://)

这个 fetcher 子模块从 ClearCase 存储库中获取代码。

要使用此获取器,请确保您的配方具有正确的 SRC_URI、SRCREV 和 PV 设置。下面是一个例子:

 SRC_URI = "ccrc://cc.example.org/ccrc;vob=/example_vob;module=/example_module"
 SRCREV = "EXAMPLE_CLEARCASE_TAG"
 PV = "${@d.getVar("SRCREV", False).replace("/", "+")}"

fetcher 使用 rcleartool 或 cleartool 远程客户端,具体取决于哪一个可用。

以下是 SRC_URI 语句的选项:

vob:ClearCase VOB 的名称,必须包含前面的“/”字符。此选项是必需的。

module:模块,必须在选定的 VOB 中包含前面的“/”字符。

说明
module 和 vob 选项结合起来在视图配置规范中创建加载规则。例如,请考虑本节开头的 SRC_URI 语句中的 vob 和 module 值。组合这些值会产生以下结果:
load /example_vob/example_module

proto:协议,可以是http或https。

默认情况下,fetcher 创建一个配置规范。如果您希望将此规范写入默认值以外的区域,请在您的配方中使用 CCASE_CUSTOM_CONFIG_SPEC 变量来定义写入规范的位置。

说明
如果您指定此变量,SRCREV 将失去其功能。但是,SRCREV 仍然用于在提取后标记存档,即使它没有定义提取的内容。

以下是一些值得一提的其他行为:

使用cleartool时,cleartool的登录由系统处理。登录不需要特殊步骤。

为了对经过身份验证的用户使用 rcleartool,在使用 fetcher 之前需要“rcleartool 登录”。

4.3.8. 其他获取器

获取子模块也存在于以下内容中:

  • Bazaar (bzr://)

  • Perforce (p4://)

  • Trees using Git Annex (gitannex://)

  • Secure FTP (sftp://)

  • Secure Shell (ssh://)

  • Repo (repo://)

  • OSC (osc://)

  • Mercurial (hg://)

目前没有这些较少使用的 fetcher 子模块的文档。但是,您可能会发现该代码很有用且可读。

4.4. 自动修订

我们需要在此处记录 AUTOREV 和 SRCREV_FORMAT。

5. 变量词汇表

本章列出了 BitBake 使用的常用变量,并概述了它们的功能和内容。

说明
以下是有关本词汇表中列出的变量的一些要点:

  • 本词汇表中列出的变量特定于 BitBake。因此,描述仅限于该上下文。
  • 此外,其他使用 BitBake 的系统(例如 Yocto Project 和 OpenEmbedded)中也存在变量,其名称与本词汇表中的名称相同。对于这种情况,这些系统中的变量扩展了变量的功能,如本词汇表中所述。
  • 最后,本词汇表中提到的变量没有出现在 BitBake 词汇表中。这些其他变量是在使用 BitBake 的系统中使用的变量。

词汇表
A B C D E F G H L M O P R S T

A

  • ASSUME_PROVIDED

    列出配方名称(PN 值) BitBake 不会尝试构建。相反,BitBake 假设这些配方已经构建。

    在 OpenEmbedded Core 中,ASSUME_PROVIDED 主要指定不应构建的原生工具。一个例子是 git-native,它在指定时允许使用来自主机的 Git 二进制文件,而不是构建 git-native。

B

  • B

    BitBake 在配方的构建过程中执行函数的目录。

  • BB_ALLOWED_NETWORKS

    指定一个以空格分隔的主机列表,允许提取程序使用这些主机来获取所需的源代码。以下是围绕此变量的注意事项:

    • 此主机列表仅在 BB_NO_NETWORK 未设置或设置为“0”时使用。

    • 存在对主机名开头的通配符匹配的有限支持。例如,以下设置匹配 git.gnu.org、ftp.gnu.org 和 foo.git.gnu.org。

          BB_ALLOWED_NETWORKS = "*.gnu.org"
      
    • 不在主机列表中的镜像将被跳过并登录到调试中。

    • 尝试访问不在主机列表中的网络会导致失败。

    将 BB_ALLOWED_NETWORKS 与 PREMIRRORS 结合使用非常有用。将要使用的主机添加到 PREMIRRORS 会导致从允许的位置获取源代码,并避免在 SRC_URI 语句中出现不允许的主机时引发错误。这是因为在从 PREMIRRORS 成功获取后,获取器不会尝试使用 SRC_URI 中列出的主机。

  • BB_CONSOLELOG

    指定日志文件的路径,BitBake 的用户界面在构建期间将输出写入该日志文件。

  • BB_CURRENTTASK

    包含当前正在运行的任务的名称。名称不包括 do_前缀。

  • BB_DANGLINGAPPENDS_WARNONLY

    定义 BitBake 如何处理附加文件 (.bbappend) 没有相应配方文件 (.bb) 的情况。这种情况通常发生在层不同步时(例如,oe-core 碰撞配方版本,旧配方不再存在,另一层尚未更新到新版本的配方)。

    默认的致命行为是最安全的,因为它是在不同步的情况下的理智反应。重要的是要意识到何时不再应用您的更改。

  • BB_DEFAULT_TASK

    未指定时使用的默认任务(例如,使用 -c 命令行选项)。指定的任务名称不应包含 do_prefix。

  • BB_DISKMON_DIRS

    在构建期间监控磁盘空间和可用 inode,并允许您根据这些参数控制构建。

    默认情况下禁用磁盘空间监控。设置此变量时,请使用以下形式:

        BB_DISKMON_DIRS = "\<action\>,\<dir\>,\<threshold\> [...]"
    
        where:
    
        <action> is:
             ABORT:     当阈值被打破(broken)时立即中止构建。
             STOPTASKS: 当阈值被打破时,在当前正在执行的任务完成后停止构建。
             WARN:      发出警告,但在阈值被打破时继续构建。后续警告将按照
                       BB_DISKMON_WARNINTERVAL 变量的定义发出,该变量必须进行定义。
    
        <dir> is:
             您选择的任何目录。您可以通过用空格分隔分组来指定一个或多个要监视的目录。
             如果两个目录在同一台设备上,则只监控第一个目录。
    
        <threshold> is:
             最小可用磁盘空间、最小空闲 inode 数或两者。您必须至少指定一个。
             要省略其中一个,只需省略该值。分别为 Gbytes、Mbytes 和 Kbytes 使用 G、M、K 指定阈值。
             如果不指定 G、M 或 K,则默认假定为千字节。不要使用 GB、MB 或 KB。
    

    这里有些例子:

        BB_DISKMON_DIRS = "ABORT,${TMPDIR},1G,100K WARN,${SSTATE_DIR},1G,100K"
        BB_DISKMON_DIRS = "STOPTASKS,${TMPDIR},1G"
        BB_DISKMON_DIRS = "ABORT,${TMPDIR},,100K"
    

    只有当您还设置了 BB_DISKMON_WARNINTERVAL 变量时,第一个示例才有效。此示例导致构建系统在 ${TMPDIR} 中的磁盘空间低于 1 GB 或可用空闲 inode 低于 100 KB 时立即中止。因为变量提供了两个目录,所以当 ${SSTATE_DIR} 目录中的磁盘空间低于 1 GB 或空闲 inode 数低于 100 KB 时,构建系统也会发出警告。在 BB_DISKMON_WARNINTERVAL 变量定义的间隔期间发出后续警告。

    当 ${TMPDIR} 目录中的最小磁盘空间低于 1 GB 时,第二个示例在所有当前正在执行的任务完成后停止构建。在这种情况下,不会对空闲 inode 进行磁盘监控。

    当 ${TMPDIR} 目录中的空闲 inode 数量低于 100 KB 时,最后一个示例立即中止构建。在这种情况下,不会对目录本身进行磁盘空间监视。

  • BB_DISKMON_WARNINTERVAL

    定义磁盘空间和空闲 inode 警告间隔。

    如果要使用 BB_DISKMON_WARNINTERVAL 变量,则还必须使用 BB_DISKMON_DIRS 变量并将其操作定义为“WARN”。在构建期间,每次磁盘空间或空闲 inode 数量进一步减少相应的时间间隔时,都会发出后续警告。

    如果您不提供 BB_DISKMON_WARNINTERVAL 变量,并且确实将 BB_DISKMON_DIRS 与“WARN”操作一起使用,则磁盘监视间隔默认如下:

        BB_DISKMON_WARNINTERVAL = "50M,5K"
    

    在配置文件中指定变量时,请使用以下形式:

        BB_DISKMON_WARNINTERVAL = "<disk_space_interval>,<disk_inode_interval>"
    
        where:
    
        <disk_space_interval> is:
             以 G、M 或 K 表示的内存间隔,分别表示 Gbytes、Mbytes 或 Kbytes。不能使用 GB、MB 或 KB。
    
        <disk_inode_interval> is:
             空闲 inode 的间隔以 G、M 或 K 表示,分别表示 Gbytes、Mbytes 或 Kbytes。不能使用 GB、MB 或 KB。
    

    下面是一个例子:

        BB_DISKMON_DIRS = "WARN,${SSTATE_DIR},1G,100K"
        BB_DISKMON_WARNINTERVAL = "50M,5K"
    

    每当 ${SSTATE_DIR} 目录中的可用磁盘空间进一步减少 50 MB 或空闲 inode 的数量进一步减少 5 KB 时,这些变量会导致 BitBake 发出后续警告。每次达到超出初始警告(即 1 GB 和 100 KB)的相应间隔时,都会根据间隔发出后续警告。

  • BB_ENV_WHITELIST

    指定允许从外部环境进入 BitBake 数据存储的内部变量白名单。如果未指定此变量的值(这是默认值),则使用以下列表:BBPATH、BB_PRESERVE_ENV、BB_ENV_WHITELIST 和 BB_ENV_EXTRAWHITE。

    说明
    您必须在外部环境中设置此变量才能使其工作。

  • BB_ENV_EXTRAWHITE

    指定一组额外的变量以允许通过(白名单)从外部环境进入 BitBake 的数据存储。此变量列表位于 BB_ENV_WHITELIST 中设置的内部列表之上。

    说明
    您必须在外部环境中设置此变量才能使其工作。

  • BB_FETCH_PREMIRRORONLY

    当设置为“1”时,会导致 BitBake 的 fetcher 模块只在 PREMIRRORS 中搜索文件。BitBake 不会搜索主 SRC_URI 或 MIRRORS。

  • BB_FILENAME

    包含拥有当前正在运行的任务的配方的文件名。例如,如果驻留在 my-recipe.bb 中的 do_fetch 任务正在执行,则 BB_FILENAME 变量包含“/foo/path/my-recipe.bb”。

  • BB_GENERATE_MIRROR_TARBALLS

    将 Git 存储库的 tarball(包括 Git 元数据)放置在 DL_DIR 目录中。任何希望创建源镜像的人都希望启用此变量。

    出于性能原因,创建和放置 Git 存储库的 tarball 不是 BitBake 的默认操作。

        BB_GENERATE_MIRROR_TARBALLS = "1"
    
  • BB_HASHCONFIG_WHITELIST

    列出从基本配置校验和中排除的变量,用于确定是否可以重用缓存。

    BitBake 确定是否重新解析主要元数据的方法之一是通过基本配置数据的数据存储中变量的校验和。在检查是否重新解析并因此重建缓存时,您通常希望排除一些变量。例如,您通常会排除 TIME 和 DATE,因为这些变量总是在变化。如果您不排除它们,BitBake 将永远不会重用缓存。

  • BB_HASHBASE_WHITELIST

    列出从校验和和相关性数据中排除的变量。因此,被排除的变量可以在不影响校验和机制的情况下更改。一个常见的例子是构建路径的变量。BitBake 的输出不应该(通常不)依赖于它的构建目录。

  • BB_HASHCHECK_FUNCTION

    指定在任务执行的“setscene”部分调用的函数名称,以验证任务哈希列表。该函数返回应执行的 setscene 任务列表。

    在代码执行的这一点上,目标是快速验证给定的 setscene 函数是否可能工作。一次检查 setscene 函数列表比调用许多单个任务更容易。返回的列表不需要完全准确。给定的场景任务稍后仍可能失败。但是,返回的数据越准确,构建的效率就越高。

  • BB_INVALIDCONF

    与 ConfigParsed 事件结合使用以触发重新解析基本元数据(即所有配方)。ConfigParsed 事件可以设置变量来触发重新解析。您必须小心避免使用此功能的递归循环。

  • BB_LOGFMT

    指定保存在 ${T} 中的日志文件的名称。默认情况下,BB_LOGFMT 变量未定义,日志文件名使用以下形式创建:

        log.{task}.{pid}
    

    如果要强制日志文件采用特定名称,可以在配置文件中设置此变量。

  • BB_NICE_LEVEL

    允许 BitBake 以特定优先级(即良好级别)运行。系统权限通常意味着 BitBake 可以降低其优先级,但不会再次提高它。有关其他信息,请参阅 BB_TASK_NICE_LEVEL。

  • BB_NO_NETWORK

    在 BitBake fetcher 模块中禁用网络访问。禁用此访问后,任何尝试访问网络的命令都会出错。

    禁用网络访问对于测试源镜像、在未连接到 Internet 时运行构建以及在某些类型的防火墙环境中运行时非常有用。

  • BB_NUMBER_THREADS

    BitBake 应在任一时间并行运行的最大任务数。如果您的主机开发系统支持多核,一个好的经验法则是将此变量设置为核数的两倍。

  • BB_NUMBER_PARSE_THREADS

    设置解析时 BitBake 使用的线程数。默认情况下,线程数等于系统上的内核数。

  • BB_ORIGENV

    包含运行 BitBake 的原始外部环境的副本。在将任何列入白名单的变量值过滤到 BitBake 的数据存储区之前,会进行复制。

    说明
    该变量的内容是一个数据存储对象,可以使用正常的数据存储操作进行查询。

  • BB_PRESERVE_ENV

    禁用白名单,而是允许所有变量从外部环境进入 BitBake 的数据存储。

    说明
    您必须在外部环境中设置此变量才能使其工作。

  • BB_RUNFMT

    指定保存到 ${T} 中的可执行脚本文件(即运行文件)的名称。默认情况下,BB_RUNFMT 变量未定义,运行文件名使用以下形式创建:

        run.{task}.{pid}
    

    如果要强制运行文件采用特定名称,可以在配置文件中设置此变量。

  • BB_RUNTASK

    包含当前正在执行的任务的名称。该值不包括“do_”前缀。例如,如果当前正在执行的任务是 do_config,则值为“config”。

  • BB_SCHEDULER

    选择用于调度 BitBake 任务的调度程序的名称。存在三种选择:

    basic - 一切都源自的基本框架。使用此选项会导致任务在解析时按数字排序。

    speed - 首先执行有更多任务依赖的任务。“速度”选项是默认选项。

    completion - 使调度程序在构建开始后尝试完成给定的配方。

  • BB_SCHEDULERS

    定义要导入的自定义调度程序。自定义调度程序需要从 RunQueueScheduler 类派生。

    有关如何选择调度程序的信息,请参阅 BB_SCHEDULER 变量。

  • BB_SETSCENE_DEPVALID

    指定 BitBake 调用的函数,该函数确定 BitBake 是否需要满足 setscene 依赖项。

    在运行 setscene 任务时,BitBake 需要知道该 setscene 任务的哪些依赖项也需要运行。是否还需要运行依赖项高度依赖于元数据。此变量指定的函数根据是否需要满足依赖关系返回“True”或“False”。

  • BB_SETSCENE_VERIFY_FUNCTION

    指定要调用的函数,该函数在主任务执行发生之前验证计划的任务执行列表。一旦 BitBake 拥有已运行且成功或失败的 setscene 任务列表,就会调用该函数。

    该功能允许检查任务列表以查看它们是否有意义。即使 BitBake 计划跳过任务,函数的返回值也可以强制 BitBake 运行任务,这在某些元数据定义的情况下是必要的。

  • BB_SIGNATURE_EXCLUDE_FLAGS

    列出可以安全地从数据存储中键的校验和和依赖项数据中排除的变量标志 (varflags)。为数据存储中的键生成校验和或依赖项数据时,针对该键设置的标志通常包含在校验和中。

    有关 varflags 的更多信息,请参阅“变量标志”部分。

  • BB_SIGNATURE_HANDLER

    定义 BitBake 使用的签名处理程序的名称。签名处理程序定义了stamp文件的创建和处理方式,签名是否以及如何合并到stamp中,以及签名本身是如何生成的。

    可以通过将从 SignatureGenerator 类派生的类注入全局命名空间来添加新的签名处理程序。

  • BB_SRCREV_POLICY

    定义 fetcher 在与源控制系统和动态源修订交互时的行为。BB_SRCREV_POLICY 变量在没有网络的情况下工作时很有用。

    可以使用以下两种策略之一设置变量:

    • chache - 保留系统先前获得的值,而不是每次都查询源控制系统。

    • clear - 每次都查询源代码控制系统。使用此策略,没有缓存。“清除”策略是默认设置。

  • BB_STAMP_POLICY

    定义用于如何比较戳文件的时间戳的模式。您可以将变量设置为以下模式之一:

    • perfile - 时间戳比较仅在特定配方的时间戳之间进行。这是默认模式。

    • full - 对所有依赖项进行时间戳比较。

    • whitelist - 与“完整”模式相同,但对 BB_STAMP_WHITELIST 变量中列出的配方进行时间戳比较。

    说明
    随着场景任务的引入,邮票政策在很大程度上已经过时了

  • BB_STAMP_WHITELIST

    列出当戳策略模式设置为“白名单”时比较戳文件时间戳的文件。有关戳记策略的信息,请参阅 BB_STAMP_POLICY 变量。

  • BB_STRICT_CHECKSUM

    为非本地 URL 设置更严格的校验和机制。将此变量设置为一个值会导致 BitBake 在遇到未指定至少一个校验和的非本地 URL 时报告错误。

  • BB_TASK_IONICE_LEVEL

    允许调整任务的输入/输出优先级。在 Autobuilder 测试期间,由于 I/O 不足,任务可能会发生随机故障。这些故障发生在各种 QEMU 运行时超时期间。您可以使用 BB_TASK_IONICE_LEVEL 变量来调整这些任务的 I/O 优先级。

    说明
    除了任务的 I/O 优先级之外,此变量的工作方式与 BB_TASK_NICE_LEVEL 变量类似。

    设置变量如下:

        BB_TASK_IONICE_LEVEL = " class. prio"
    

    对于class,默认值为“2”,这是尽力而为。您可以将“1”用于实时,“3”用于空闲。如果要使用实时,则必须具有超级用户权限。

    对于prio,您可以使用从最高优先级“0”到最低优先级“7”的任何值。默认值为“4”。您不需要任何特殊权限即可使用此优先级值范围。

    说明
    为了使您的 I/O 优先级设置生效,您需要为后备块设备选择完全公平队列 (CFQ) 调度程序。要选择调度程序,请使用以下命令格式,其中 device 是设备(例如 sda、sdb 等):
    $ sudo sh -c “echo cfq > /sys/block/device/queu/scheduler

  • BB_TASK_NICE_LEVEL

    允许特定任务更改其优先级(即良好级别)。

    您可以将此变量与任务覆盖结合使用来提高或降低特定任务的优先级。例如,在 Yocto 项目自动构建器上,与构建任务相比,图像中的 QEMU 仿真具有更高的优先级,以确保图像在加载的系统上不会超时。

  • BB_TASKHASH

    在正在执行的任务中,此变量保存当前启用的签名生成器返回的任务的哈希值。

  • BB_VERBOSE_LOGS

    控制构建过程中 BitBake 的详细程度。如果设置,shell 脚本回显命令和 shell 脚本输出出现在标准输出 (stdout) 上。

  • BB_WORKERCONTEXT

    指定当前上下文是否正在执行任务。在执行任务时,BitBake 将此变量设置为“1”。当任务在解析或事件处理期间处于服务器上下文中时,不会设置该值。

  • BBCCLASSEND

    允许您扩展配方,以便它构建软件的变体。这些来自 OpenEmbedded Core 元数据的配方变体的一些示例是“本机”,例如 quilt-native,它是为在构建系统上运行而构建的 Quilt 副本; “crosses”,例如 gcc-cross,它是一个编译器,用于在构建机器上运行,但生成在目标机器上运行的二进制文件; “nativesdk”,它针对的是 SDK 机器而不是 MACHINE;和“multilib:multilib_name”形式的“multilibs”。

    要使用最少的代码构建配方的不同变体,通常就像将变量添加到配方中一样简单。这里有两个例子。“原生”变体来自 OpenEmbedded Core 元数据:

        BBCLASSEXTEND =+ "native nativesdk"
        BBCLASSEXTEND =+ "multilib:multilib_name"
    
  • BBDEBUG

    将 BitBake 调试输出级别设置为由 -d 命令行选项递增的特定值。

    说明
    您必须在外部环境中设置此变量才能使其工作。

  • BBFILE_COLLECTIONS

    列出已配置层的名称。这些名称用于查找其他 BBFILE_* 变量。通常,每个层在其 conf/layer.conf 文件中将其名称附加到此变量。

  • BBFILE_PATTERN

    扩展以匹配特定层中来自 BBFILES 的文件的变量。该变量在 conf/layer.conf 文件中使用,并且必须以特定层的名称作为后缀(例如 BBFILE_PATTERN_emenlow)。

  • BBFILE_PRIORITY

    为每一层中的配方文件分配优先级。

    此变量在同一配方出现在多个层中的情况下很有用。设置此变量允许您将一个层与包含相同配方的其他层进行优先级排序 - 有效地让您控制多个层的优先级。无论配方的版本(PV 变量)如何,通过此变量建立的优先级都有效。例如,具有较高 PV 值的配方但其 BBFILE_PRIORITY 设置为具有较低优先级的层仍然具有较低的优先级。

    BBFILE_PRIORITY 变量的值越大,优先级越高。例如,值 6 的优先级高于值 5。如果未指定,则 BBFILE_PRIORITY 变量基于层依赖项设置(有关更多信息,请参阅 LAYERDEPENDS 变量。默认优先级,如果未指定对于没有依赖项的层,是定义的最低优先级 + 1(如果未定义优先级,则为 1)。

    提示
    您可以使用该命令bitbake-layers show-layers列出所有已配置的层及其优先级。

  • BBFILES

    BitBake 用于构建软件的配方文件列表。

  • BBINCLUDED

    包含以空格分隔的所有文件的列表,其中包含 BitBake 的解析器在解析当前文件期间包含的所有文件。

  • BBINCLUDELOGS

    如果设置为一个值,则在报告失败的任务时启用打印任务日志。

  • BBINCLUDELOGS_LINES

    如果设置了 BBINCLUDELOGS,则指定在报告失败任务时要打印的任务日志文件中的最大行数。如果不设置 BBINCLUDELOGS_LINES,则打印整个日志。

  • BBLAYERS

    列出要在构建期间启用的层。这个变量是在build目录下的bblayers.conf配置文件中定义的。下面是一个例子:

        BBLAYERS = " \
        /home/scottrif/poky/meta \
        /home/scottrif/poky/meta-yocto \
        /home/scottrif/poky/meta-yocto-bsp \
        /home/scottrif/poky/meta-mykernel \
        ”
    

    此示例启用四个层,其中一个是名为 meta-mykernel 的自定义用户定义层。

  • BBLAYERS_FETCH_DIR

    设置存储图层的基本位置。默认情况下,此位置设置为 ${COREBASE}。此设置与 bitbake-layers layerindex-fetch 结合使用,并告诉 bitbake-layers 放置获取的层的位置。

  • BBMASK

    防止 BitBake 处理配方和配方附加文件。

    您可以使用 BBMASK 变量来“隐藏”这些 .bb 和 .bbappend 文件。BitBake 忽略与任何表达式匹配的任何配方或配方附加文件。就好像 BitBake 根本没有看到它们。因此,BitBake 不会解析或以其他方式使用匹配文件。

    您提供的值将传递给 Python 的正则表达式编译器。将表达式与文件的完整路径进行比较。有关完整的语法信息,请参阅 http://docs.python.org/release/2.3/lib/re-syntax.html 上的 Python 文档。

    以下示例使用完整的正则表达式告诉 BitBake 忽略 meta-ti/recipes-misc/ 目录中的所有配方和配方附加文件:

        BBMASK = "meta-ti/recipes-misc/"
    

    如果要屏蔽多个目录或配方,可以指定多个正则表达式片段。下一个示例屏蔽了多个目录和单个配方:

        BBMASK += "/meta-ti/recipes-misc/meta-ti/recipes-ti/packagegroup/"
        BBMASK += "/meta-oe/recipes-support/"
        BBMASK += "/meta-foo/.*/openldap"
        BBMASK += "opencv.*\.bbappend"
        BBMASK += "lzma"
    

    说明
    指定目录名称时,请使用尾部斜杠字符以确保仅匹配该目录名称。

  • BBPATH

    BitBake 使用它来定位类 (.bbclass) 和配置 (.conf) 文件。此变量类似于 PATH 变量。

    如果从构建目录之外的目录运行 BitBake,则必须确保将 BBPATH 设置为指向构建目录。像设置任何环境变量一样设置变量,然后运行 ​​BitBake:

        $ BBPATH="build_directory"
        $ export BBPATH
        $ bitbake target
    
  • BBSERVER

    指向运行内存驻留 BitBake 的服务器。该变量仅在您使用内存驻留 BitBake 时使用。

  • BBTARGETS

    允许您使用配置文件添加到要构建的命令行目标配方列表。

  • BBVERSIONS

    允许单个配方从单个配方文件构建项目的多个版本。您还可以使用 OVERRIDES 机制为单个版本或可选命名的版本范围指定条件元数据。

    有关 BBVERSIONS 的更多信息,请参阅“变体 - 类扩展机制”部分。

  • BITBAKE_UI

    用于指定运行 BitBake 时使用的 UI 模块。使用此变量等效于使用 -u 命令行选项。

    说明
    您必须在外部环境中设置此变量才能使其工作。

  • BUILDNAME

    分配给构建的名称。该名称默认为构建开始时的日期时间戳,但可以由元数据定义。

  • BZRDIR

    存储从 Bazaar 系统检出的文件的目录。

C

  • CACHE

    指定 BitBake 用于存储元数据缓存的目录,因此无需在每次启动 BitBake 时对其进行解析。

  • CVSDIR

    CVS系统下检出的文件存放的目录。

D

  • DEFAULT_PREFERENCE

    指定配方选择优先级的弱偏差。

    这个变量的最常见用法是在一个软件的开发版本的配方中将其设置为“-1”。在没有使用 PREFERRED_VERSION 来构建开发版本的情况下,以这种方式使用变量会导致默认情况下构建稳定版本的配方。

    说明
    DEFAULT_PREFERENCE 提供的偏差很弱,如果该变量在包含同一配方的不同版本的两个层之间不同,则 BBFILE_PRIORITY 会覆盖该偏差。

  • DEPENDS

    列出配方的构建时依赖项(即其他配方文件)。

    考虑这个名为“a”和“b”的配方的简单示例,它们生成名称相似的包。在本例中,DEPENDS 语句出现在“a”配方中:

        DEPENDS = "b"
    

    在这里,依赖关系使得配方“a”的 do_configure 任务依赖于配方“b”的 do_populate_sysroot 任务。这意味着当配方“a”配置自身时,配方“b”放入 sysroot 的任何内容都可用。

    有关运行时依赖项的信息,请参阅 RDEPENDS 变量。

    说明
    配方的详细说明。

  • DL_DIR

    构建过程用于存储下载的中央下载目录。默认情况下,DL_DIR 获取适合镜像除 Git 存储库之外的所有内容的文件。如果您想要 Git 存储库的 tarball,请使用 BB_GENERATE_MIRROR_TARBALLS 变量。

E

  • EXCLUDE_FROM_WORLD

    指示 BitBake 从世界构建(即 bitbake 世界)中排除配方。在世界构建期间,BitBake 定位、解析和构建在 bblayers.conf 配置文件中公开的每一层中找到的所有配方。

    要使用此变量从世界构建中排除配方,请在配方中将该变量设置为“1”。

    说明
    添加到 EXCLUDE_FROM_WORLD 的配方可能仍会在世界构建期间构建,以满足其他配方的依赖关系。将配方添加到 EXCLUDE_FROM_WORLD 只能确保配方不会显式添加到世界构建中的构建目标列表中。

F

  • FAKEROOT

    包含在 fakeroot 环境中运行 shell 脚本时使用的命令。FAKEROOT 变量已过时,已被其他 FAKEROOT* 变量替换。有关更多信息,请参阅词汇表中的这些条目。

  • FAKEROOTBASEENV

    列出在执行 FAKEROOTCMD 定义的命令时要设置的环境变量,该命令在 fakeroot 环境中启动 bitbake-worker 进程。

  • FAKEROOTCMD

    包含在 fakeroot 环境中启动 bitbake-worker 进程的命令。

  • FAKEROOTDIRS

    列出在 fakeroot 环境中运行任务之前要创建的目录。

  • FAKEROOTENV

    列出在 fakeroot 环境中运行任务时要设置的环境变量。有关环境变量和 fakeroot 环境的其他信息,请参阅 FAKEROOTBASEENV 变量。

  • FAKEROOTNOENV

    列出运行不在 fakeroot 环境中的任务时要设置的环境变量。有关环境变量和 fakeroot 环境的其他信息,请参阅 FAKEROOTENV 变量。

  • FETCHCMD

    定义 BitBake fetcher 模块在运行 fetch 操作时执行的命令。使用变量时需要使用覆盖后缀(例如 FETCHCMD_git 或 FETCHCMD_svn)。

  • FILE

    指向当前文件。BitBake 在解析过程中设置此变量以识别正在解析的文件。BitBake 还会在执行配方时设置此变量以识别配方文件。

  • FILESDIR

    指定 BitBake 在搜索补丁和文件时使用的目录。如果使用 FILESPATH 找不到文件,则“本地”提取器模块在处理 file:// URL 时使用这些目录。

    说明
    不推荐使用 FILESDIR 变量,您应该在所有新代码中使用 FILESPATH。

  • FILESPATH

    指定 BitBake 在搜索补丁和文件时使用的目录。“本地”提取器模块在处理 file:// URL 时使用这些目录。该变量的行为类似于 shell PATH 环境变量。该值是按从左到右的顺序搜索的以冒号分隔的目录列表。

G

  • GITDIR

    克隆时存储 Git 存储库的本地副本的目录。

H

  • HGDIR

    从 Mercurial 系统检出的文件的存储目录。

  • HOMEPAGE

    可以找到有关配方正在构建的软件的更多信息的网站。

I

  • INHERIT

    导致在解析过程中此时继承命名类。该变量仅在配置文件中有效。

L

  • LAYERDEPENDS

    列出此配方所依赖的层,以空格分隔。或者,您可以通过将其添加到带有冒号的层名称末尾来为依赖项指定特定层版本(例如,在这种情况下,将“anotherlayer:3”与 LAYERVERSION_anotherlayer 进行比较)。如果缺少任何依赖项或版本号不完全匹配(如果指定),BitBake 会产生错误。

    您可以在 conf/layer.conf 文件中使用此变量。您还必须使用特定图层名称作为变量的后缀(例如 LAYERDEPENDS_mylayer)。

  • LAYERDIR

    在 layer.conf 配置文件中使用时,此变量提供当前层的路径。此变量在 layer.conf 之外不可用,并且在文件解析完成后会立即扩展引用。

  • LAYERVERSION

    (可选)将图层的版本指定为单个数字。您可以在 LAYERDEPENDS 中将此变量用于另一层,以依赖于该层的特定版本。

    您可以在 conf/layer.conf 文件中使用此变量。您还必须使用特定图层名称作为变量的后缀(例如 LAYERDEPENDS_mylayer)。

  • LICENSE

    配方的源许可证列表。

M

  • MIRRORS

    指定 BitBake 从中获取源代码的其他路径。当构建系统搜索源代码时,它首先尝试本地下载目录。如果该位置失败,则构建系统会依次尝试由 PREMIRRORS 定义的位置、上游源,然后是由 MIRRORS 指定的位置。

  • MULTI_PROVIDER_WHITELIST

    允许您抑制在构建提供相同输出的两个单独配方时引起的 BitBake 警告。

    当构建两个不同的配方时,Bitbake 通常会发出警告,每个配方都提供相同的输出。这种情况通常是用户不想要的。但是,确实存在有意义的情况,特别是在 virtual/* 命名空间中。您可以使用此变量来抑制 BitBake 的警告。

    要使用该变量,请列出提供者名称(例如配方名称、虚拟/内核等)。

O

  • OVERRIDES

    BitBake 使用 OVERRIDES 来控制 BitBake 解析配方和配置文件后覆盖哪些变量。

    以下是使用基于机器架构的覆盖列表的简单示例:

        OVERRIDES = "arm:x86:mips:powerpc"
    

    您可以在“条件语法(覆盖)”部分中找到有关如何使用 OVERRIDES 的信息。

P

  • PACKAGES

    配方创建的包列表。

  • PACKAGES_DYNAMIC

    承诺您的配方满足在其他配方中找到的可选模块的运行时依赖项。PACKAGES_DYNAMIC 实际上并不满足依赖关系,它只是说明它们应该被满足。例如,如果在构建期间通过 PACKAGES_DYNAMIC 变量满足另一个包的硬运行时依赖(RDEPENDS),但从未实际生成具有模块名称的包,那么另一个包将被破坏。

  • PE

    配方的时代(epoch)。默认情况下,此变量未设置。当版本控制方案以某种向后不兼容的方式发生变化时,该变量用于使升级成为可能。

  • PERSISTENT_DIR

    指定 BitBake 用于存储应在构建之间保留的数据的目录。特别是存储的数据是使用BitBake的持久化数据API的数据和PR Server和PR Service使用的数据。

  • PF

    指定配方或包名称并包括所有版本和修订号(即 eglibc-2.13-r20+svnr15508/ 和 bash-4.2-r1/)。

  • PN

    配方名称。

  • PR

    配方的修订。

  • PREFERRED_PROVIDER

    确定当多个配方提供相同项目时应优先考虑哪个配方。您应该始终使用所提供项目的名称为变量添加后缀,并且您应该将其设置为您想要优先考虑的配方的 PN。一些例子:

        PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
        PREFERRED_PROVIDER_virtual/xserver = "xserver-xf86"
        PREFERRED_PROVIDER_virtual/libgl ?= "mesa"
    
  • PREFERRED_PROVIDERS

    确定在多个配方提供相同项目的情况下应优先考虑哪个配方。在功能上,PREFERRED_PROVIDERS 与 PREFERRED_PROVIDER 相同。但是, PREFERRED_PROVIDERS 变量允许您使用以下形式为多种情况定义首选项:

        PREFERRED_PROVIDERS = "xxx:yyy aaa:bbb ..."
    

    此表格可方便地替换以下内容:

        PREFERRED_PROVIDER_xxx = "yyy"
        PREFERRED_PROVIDER_aaa = "bbb"
    
  • PREFERRED_VERSION

    如果有多个可用的配方版本,则此变量确定应优先考虑哪个配方。您必须始终为变量添加要选择的 PN 后缀,并且您应该相应地设置 PV 以获得优先级。您可以使用“%”字符作为通配符来匹配任意数量的字符,这在指定包含可能会更改的长修订号的版本时非常有用。这里有两个例子:

        PREFERRED_VERSION_python = "2.7.3"
        PREFERRED_VERSION_linux-yocto = "3.10%"
    
  • PREMIRRORS

    指定 BitBake 从中获取源代码的其他路径。当构建系统搜索源代码时,它首先尝试本地下载目录。如果该位置失败,则构建系统会依次尝试由 PREMIRRORS 定义的位置、上游源,然后是由 MIRRORS 指定的位置。

    通常,您会为构建系统添加一个特定的服务器,通过在您的配置中添加如下内容,在其他任何服务器之前尝试:

        PREMIRRORS_prepend = "\
        git://.*/.* http://www.yoctoproject.org/sources/ \n \
        ftp://.*/.* http://www.yoctoproject.org/sources/ \n \
        http://.*/.* http://www.yoctoproject.org/sources/ \n \
        https://.*/.* http://www.yoctoproject.org/sources/ \n"
    

    这些更改导致构建系统拦截 Git、FTP、HTTP 和 HTTPS 请求并将它们定向到 http:// 源镜像。您也可以使用 file:// URL 指向本地目录或网络共享。

  • PROVIDES

    可以知道特定配方的别名列表。默认情况下,配方自己的 PN 已经隐含在其 PROVIDES 列表中。如果配方使用 PROVIDES,则附加别名是该配方的同义词,并且可以在构建期间满足 DEPENDS 指定的其他配方的依赖关系。

    考虑来自配方文件 libav_0.8.11.bb 的以下示例 PROVIDES 语句:

        PROVIDES += "libpostproc"
    

    PROVIDES 语句导致“libav”配方也称为“libpostproc”。

  • PRSERV_HOST

    基于网络的 PR 服务主机和端口。

    以下是如何设置 PRSERV_HOST 变量的示例:

        PRSERV_HOST = "localhost:0"
    

    如果要自动启动本地 PR 服务,则必须设置该变量。您可以将 PRSERV_HOST 设置为其他值以使用远程 PR 服务。

  • PV

    配方的版本。

R

  • RDEPENDS

    列出必须安装的包的运行时依赖项(即其他包),以便构建的包正确运行。如果在构建过程中找不到此列表中的包,您将收到构建错误。

    因为 RDEPENDS 变量适用于正在构建的包,所以您应该始终以带有附加包名称的形式使用该变量。例如,假设您正在构建一个依赖于 perl 包的开发包。在这种情况下,您将使用以下 RDEPENDS 语句:

        RDEPENDS_${PN}-dev += "perl"
    

    在示例中,开发包依赖于 perl 包。因此,RDEPENDS 变量将 ${PN}-dev 包名称作为变量的一部分。

    BitBake 支持指定版本依赖。尽管语法因打包格式而异,但 BitBake 对您隐藏了这些差异。以下是使用 RDEPENDS 变量指定版本的一般语法:

        RDEPENDS_${PN} = "package (operator version)"
    

    对于操作符(operator),您可以指定以下内容:

        =
        <
        >
        <=
        >=
    

    例如,以下设置对 foo 包的 1.2 或更高版本的依赖:

        RDEPENDS_${PN} = "foo (>= 1.2)"
    

    有关构建时依赖项的信息,请参阅 DEPENDS 变量

  • RPROVIDES

    包还提供的包名称别名列表。这些别名对于在构建期间和目标上(由 RDEPENDS 指定)满足其他包的运行时依赖性很有用。

    与所有包控制变量一样,您必须始终将变量与包名称覆盖结合使用。下面是一个例子:

        RPROVIDES_${PN} = "widget-abi-2"
    
  • RRECOMMENDS

    扩展正在构建的包的可用性的包列表。正在构建的包不依赖于这个包列表来成功构建,但需要它们来扩展可用性。要为包指定运行时依赖项,请参阅 RDEPENDS 变量。

    BitBake 支持指定版本推荐。尽管语法因打包格式而异,但 BitBake 对您隐藏了这些差异。以下是使用 RRECOMMENDS 变量指定版本的一般语法:

        RRECOMMENDS_${PN} = "package (operator version)"
    

    对于操作符(operator),您可以指定以下内容:

        =
        <
        >
        <=
        >=
    

    例如,以下设置对 1.2 或更高版本的 foo 包的推荐:

        RRCOMMENDS_${PN} = "foo (>= 1.2)"
    

S

  • SECTION

    应在其中对包进行分类的部分。

  • src_URI

    源文件列表 - 本地或远程。这个变量告诉 BitBake 为构建提取哪些位以及如何提取它们。例如,如果配方或附加文件需要从 Internet 获取单个 tarball,则配方或附加文件使用指定该 tarball 的 SRC_URI 条目。另一方面,如果配方或附加文件需要获取 tarball 并包含自定义文件,则配方或附加文件需要一个 SRC_URI 变量来指定所有这些源。

    以下列表解释了可用的 URI 协议:

    • file:// - 从本地机器获取文件,通常是元数据附带的文件。该路径是相对于 FILESPATH 变量的。

    • bzr:// - 从 Bazaar 版本控制存储库中获取文件。

    • git:// - 从 Git 版本控制存储库中获取文件。

    • osc:// - 从 OSC(OpenSUSE 构建服务)版本控制存储库中获取文件。

    • repo:// - 从 repo (Git) 存储库中获取文件。

    • http:// - 使用 HTTP 从 Internet 获取文件。

    • https:// - 使用 HTTPS 从 Internet 获取文件。

    • ftp:// - 使用 FTP 从 Internet 获取文件。

    • cvs:// - 从 CVS 版本控制存储库中获取文件。

    • hg:// - 从 Mercurial (hg) 版本控制存储库中获取文件。

    • p4:// - 从 Perforce (p4) 版本控制存储库中获取文件。

    • ssh:// - 从安全外壳中获取文件。

    • svn:// - 从 Subversion (svn) 版本控制存储库获取文件。

    以下是一些值得一提的附加选项:

    • unpack - 如果文件是存档,则控制是否解压文件。默认操作是解压缩文件。

    • subdir - 将文件(或提取其内容)放入指定的子目录中。此选项对于不寻常的 tarball 或其他档案非常有用,这些档案在档案的子目录中没有其文件。

    • name - 当您在 SRC_URI 中指定了多个文件时,指定用于与 SRC_URI 校验和关联的名称。

    • downloadfilename - 指定存储下载文件时使用的文件名。

  • SRCDATE

    用于构建包的源代码的日期。此变量仅适用于从源代码管理器 (SCM) 获取源的情况。

  • SRCREV

    用于构建包的源代码的修订版。此变量仅在使用 Subversion、Git、Mercurial 和 Bazaar 时适用。如果你想构建一个固定的修订版本,并且你想避免每次 BitBake 解析你的配方时在远程存储库上执行查询,你应该指定一个 SRCREV,它是一个完整的修订标识符,而不仅仅是一个标签。

  • SRCREV_FORMAT

    当在 SRC_URI 中使用多个源控制的 URL 时,帮助构建有效的 SRCREV 值。

    在这些情况下,系统需要帮助构建这些值。SRC_URI 中的每个组件都分配了一个名称,这些名称在 SRCREV_FORMAT 变量中引用。考虑一个带有名为“machine”和“meta”的 URL 的示例。在这种情况下,SRCREV_FORMAT 可能看起来像“machine_meta”,并且这些名称会将 SCM 版本替换到每个位置。如果需要,仅添加一个 AUTOINC 占位符。并且,这个占位符被放置在返回字符串的开头。

  • STAMP

    指定用于创建配方标记文件的基本路径。实际stamp文件的路径是通过评估此字符串然后附加其他信息来构建的。

  • STAMPCLEAN

    指定用于创建配方标记文件的基本路径。与 STAMP 变量不同,STAMPCLEAN 可以包含通配符以匹配清理操作应删除的文件范围。BitBake 使用清理操作来删除在创建新stamp时应该删除的任何其他stamp。

  • SUMMARY

    配方的简短摘要,不超过 72 个字符。

  • SVNDIR

    存储从 Subversion 系统检出的文件的目录。

T

  • T

    指向目录是 BitBake 在构建特定配方时放置临时文件,这些文件主要由任务日志和脚本组成

  • TOPDIR

    指向构建目录。BitBake 会自动设置这个变量。

A. Hello World 示例

A.1. BitBake Hello World

通常用于演示任何新编程语言或工具的最简单示例是“Hello World”示例。本附录以教程形式演示了 BitBake 上下文中的 Hello World。本教程描述了如何创建一个新项目以及允许 BitBake 构建它所需的适用元数据文件。

A.2. 获取BitBake

有关如何获取 BitBake 的信息,请参阅“获取 BitBake”部分。一旦你的机器上有了源代码,BitBake 目录就会显示如下:

 $ ls -al
 total 100
 drwxrwxr-x. 9 wmat wmat  4096 Jan 31 13:44 .
 drwxrwxr-x. 3 wmat wmat  4096 Feb  4 10:45 ..
 -rw-rw-r--. 1 wmat wmat   365 Nov 26 04:55 AUTHORS
 drwxrwxr-x. 2 wmat wmat  4096 Nov 26 04:55 bin
 drwxrwxr-x. 4 wmat wmat  4096 Jan 31 13:44 build
 -rw-rw-r--. 1 wmat wmat 16501 Nov 26 04:55 ChangeLog
 drwxrwxr-x. 2 wmat wmat  4096 Nov 26 04:55 classes
 drwxrwxr-x. 2 wmat wmat  4096 Nov 26 04:55 conf
 drwxrwxr-x. 3 wmat wmat  4096 Nov 26 04:55 contrib
 -rw-rw-r--. 1 wmat wmat 17987 Nov 26 04:55 COPYING
 drwxrwxr-x. 3 wmat wmat  4096 Nov 26 04:55 doc
 -rw-rw-r--. 1 wmat wmat    69 Nov 26 04:55 .gitignore
 -rw-rw-r--. 1 wmat wmat   849 Nov 26 04:55 HEADER
 drwxrwxr-x. 5 wmat wmat  4096 Jan 31 13:44 lib
 -rw-rw-r--. 1 wmat wmat   195 Nov 26 04:55 MANIFEST.in
 -rw-rw-r--. 1 wmat wmat  2887 Nov 26 04:55 TODO

此时,您应该将 BitBake 克隆到与之前列表匹配的目录,但日期和用户名除外。

A.3. 设置 BitBake 环境

首先,您需要确保可以运行 BitBake。将您的工作目录设置为本地 BitBake 文件所在的位置并运行以下命令:

 $ ./bin/bitbake --version
 BitBake Build Tool Core version 1.23.0, bitbake version 1.23.0

控制台输出会告诉您正在运行的版本。

运行 BitBake 的推荐方法来自您选择的目录。为了能够从任何目录运行 BitBake,您需要将可执行二进制文件添加到您的二进制文件到您的 shell 的环境 PATH 变量中。首先,通过输入以下内容查看当前的 PATH 变量:

 $ echo $PATH

接下来,将 BitBake 二进制文件的目录位置添加到 PATH。这是一个将 /home/scott-lenovo/bitbake/bin 目录添加到 PATH 变量前面的示例:

  $ export PATH=/home/scott-lenovo/bitbake/bin:$PATH

您现在应该能够在任何目录下工作时从命令行输入 bitbake 命令。

A.4. Hello World 示例

本练习的总体目标是利用任务和层概念构建一个完整的“Hello World”示例。因为这是 OpenEmbedded 和 Yocto Project 等现代项目利用 BitBake 的方式,所以该示例为理解 BitBake 提供了一个很好的起点。

为了帮助您了解如何使用 BitBake 构建目标,该示例仅从 bitbake 命令开始,该命令会导致 BitBake 失败并报告问题。该示例通过向构建添加部分来推进,最终以一个有效的、最小的“Hello World”示例结束。

尽管已尽一切努力解释示例中发生的情况,但这些描述无法涵盖所有​​内容。您可以在本手册中找到更多信息。此外,您可以积极参与有关 BitBake 构建工具的 http://lists.openembedded.org/mailman/listinfo/bitbake-devel 讨论邮件列表。

说明
这个例子受到以下来源的启发并大量借鉴:

  • 邮件列表帖子 - BitBake 相当于“Hello, World!”
  • Hambedded Linux 博客文章 - 从 Bitbake Hello World 到图像

如前所述,此示例的目标是最终编译“Hello World”。但是,尚不清楚 BitBake 需要什么以及您必须提供什么才能实现该目标。回想一下,BitBake 使用三种类型的元数据文件:配置文件、类和食谱。但是他们去哪里呢? BitBake 如何找到它们? BitBake 的错误消息可帮助您回答这些类型的问题,并帮助您更好地准确了解正在发生的事情。

以下是完整的“Hello World”示例。

1)创建项目目录:首先,为“Hello World”项目建立一个目录。以下是在主目录中执行此操作的方法:

 $ mkdir ~/hello
 $ cd ~/hello

这是 BitBake 将用来完成其所有工作的目录。您可以使用此目录来保存 BitBake 所需的所有元文件。拥有项目目录是隔离项目的好方法。

2)运行 Bitbake:此时,您只有一个项目目录。运行 bitbake 命令,看看它做了什么:

 $ bitbake
 The BBPATH variable is not set and bitbake did not
 find a conf/bblayers.conf file in the expected location.
 Maybe you accidentally invoked bitbake from the wrong directory?
 DEBUG: Removed the following variables from the environment:
 GNOME_DESKTOP_SESSION_ID, XDG_CURRENT_DESKTOP,
 GNOME_KEYRING_CONTROL, DISPLAY, SSH_AGENT_PID, LANG, no_proxy,
 XDG_SESSION_PATH, XAUTHORITY, SESSION_MANAGER, SHLVL,
 MANDATORY_PATH, COMPIZ_CONFIG_PROFILE, WINDOWID, EDITOR,
 GPG_AGENT_INFO, SSH_AUTH_SOCK, GDMSESSION, GNOME_KEYRING_PID,
 XDG_SEAT_PATH, XDG_CONFIG_DIRS, LESSOPEN, DBUS_SESSION_BUS_ADDRESS,
 _, XDG_SESSION_COOKIE, DESKTOP_SESSION, LESSCLOSE, DEFAULTS_PATH,
 UBUNTU_MENUPROXY, OLDPWD, XDG_DATA_DIRS, COLORTERM, LS_COLORS

此输出的大部分特定于与 BitBake 不直接相关的环境变量。但是,关于 BBPATH 变量和 conf/bblayers.conf 文件的第一条消息是相关的。

当您运行 BitBake 时,它​​开始寻找元数据文件。BBPATH 变量告诉 BitBake 在哪里查找这些文件。BBPATH 未设置,您需要设置它。如果没有 BBPATH,Bitbake 根本找不到任何配置文件 (.conf) 或配方文件 (.bb)。BitBake 也找不到 bitbake.conf 文件。

3)设置 BBPATH:对于本示例,您可以按照与前面在附录中设置 PATH 相同的方式来设置 BBPATH。但是,您应该意识到,在每个项目的配置文件中设置 BBPATH 变量要灵活得多。

在您的 shell 中,输入以下命令来设置和导出 BBPATH 变量:

 $ BBPATH="projectdirectory"
 $ export BBPATH

在命令中使用您的实际项目目录。BitBake 使用该目录来查找项目所需的元数据。

说明
指定项目目录时,请勿使用波浪号(“~”)字符,因为 BitBake 不会像 shell 那样扩展该字符。

4)运行 Bitbake:现在你已经定义了 BBPATH,再次运行 bitbake 命令:

 $ bitbake
 ERROR: Traceback (most recent call last):
   File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped
     return func(fn, *args)
   File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 173, in parse_config_file
     return bb.parse.handle(fn, data, include)
   File "/home/scott-lenovo/bitbake/lib/bb/parse/__init__.py", line 99, in handle
     return h['handle'](fn, data, include)
   File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 120, in handle
     abs_fn = resolve_file(fn, data)
   File "/home/scott-lenovo/bitbake/lib/bb/parse/__init__.py", line 117, in resolve_file
     raise IOError("file %s not found in %s" % (fn, bbpath))
 IOError: file conf/bitbake.conf not found in /home/scott-lenovo/hello

 ERROR: Unable to parse conf/bitbake.conf: file conf/bitbake.conf not found in /home/scott-lenovo/hello

此示例输出显示 BitBake 在项目目录中找不到 conf/bitbake.conf 文件。这个文件是 BitBake 为了构建目标必须找到的第一件事。而且,由于此示例的项目目录为空,因此您需要提供一个 conf/bitbake.conf 文件。

5)创建 conf/bitbake.conf:conf/bitbake.conf 包含许多 BitBake 用于元数据和配方文件的配置变量。对于此示例,您需要在项目目录中创建文件并定义一些关键的 BitBake 变量。有关 bitbake.conf 的更多信息,请参阅 https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to- an-image/#an-overview-of-bitbakeconf

使用以下命令在项目目录下创建conf目录:

 $ mkdir conf

从 conf 目录中,使用一些编辑器创建 bitbake.conf,使其包含以下内容:

 TMPDIR = "${ TOPDIR }/tmp"
  CACHE    = "${TMPDIR}/cache"
  STAMP    = "${TMPDIR}/stamps"
  T        = "${TMPDIR}/work"
  B        = "${TMPDIR}"

TMPDIR 变量建立了 BitBake 用于构建输出和中间文件的目录(除了 Setscene 进程使用的缓存信息。这里,TMPDIR 目录设置为 hello/tmp。

提示
您始终可以安全地删除 tmp 目录以重建 BitBake 目标。当您运行 BitBake 时,构建过程会为您创建目录。

有关此示例中定义的每个其他变量的信息,请单击链接以转到词汇表中的定义。

6)运行Bitbake:确认conf/bitbake.conf文件存在后,可以再次运行bitbake命令:

 $ bitbake
 ERROR: Traceback (most recent call last):
 File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped
 return func(fn, *args)
 File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 177, in _inherit
 bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data)
 File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 92, in inherit
 include(fn, file, lineno, d, "inherit")
 File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 100, in include
 raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
 ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass

 ERROR: Unable to parse base: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass

在示例输出中,BitBake 找不到 classes/base.bbclass 文件。接下来您需要创建该文件。

7)创建 classes/base.bbclass:BitBake 使用类文件来提供通用代码和功能。BitBake 最少需要的类是 classes/base.bbclass 文件。每个配方都隐式继承了基类。BitBake 在项目的 classes 目录中查找类(即本例中的 hello/classes)。

创建类目录如下:

 $ cd $HOME/hello
 $ mkdir classes

移动到 classes 目录,然后通过插入以下一行来创建 base.bbclass 文件:

 addtask build

BitBake 运行的最小任务是 do_build 任务。这是构建项目所需的全部示例。当然,根据 BitBake 支持的构建环境,base.bbclass 可以有更多。有关 base.bbclass 文件的更多信息,您可以查看 https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to-an-image/#tasks.

8)运行Bitbake:确认classes/base.bbclass文件存在后,可以再次运行bitbake命令:

 $ bitbake
 Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.

BitBake 终于没有报告任何错误。但是,您可以看到它确实没有任何关系。您需要创建一个配方,让 BitBake 有事可做。

9)创建一个层:虽然对于这样一个小例子来说并不是真正必要的,但是创建一个层来使您的代码与 BitBake 使用的通用元数据分开是一个很好的做法。因此,此示例创建并使用了一个名为“mylayer”的层。

说明
您可以在以下位置找到有关添加图层的其他信息 https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to-an-image/#adding-an-example-layer。

至少,您的层中需要一个配方文件和一个层配置文件。配置文件需要在层内的conf目录下。使用这些命令来设置层和 conf 目录:

 $ cd $HOME
 $ mkdir mylayer
 $ cd mylayer
 $ mkdir conf

移动到 conf 目录并创建一个具有以下内容的 layer.conf 文件:

 BBPATH .= ":${LAYERDIR}"

 BBFILES += "${LAYERDIR}/*.bb"

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

有关这些变量的信息,请单击链接以转到词汇表中的定义。

接下来您需要创建配方文件。在顶层的图层中,使用编辑器创建一个名为 printhello.bb 的配方文件,该文件具有以下内容:

 DESCRIPTION = "Prints Hello World"
 PN = 'printhello'
 PV = '1'

 python do_build() {
    bb.plain("********************");
    bb.plain("*                  *");
    bb.plain("*  Hello, World!   *");
    bb.plain("*                  *");
    bb.plain("********************");
 }

配方文件仅提供配方的描述、名称、版本和 do_build 任务,该任务将“Hello World”打印到控制台。有关这些变量的更多信息,请访问词汇表的链接。

10)使用目标运行 Bitbake:现在 BitBake 目标存在,运行命令并提供该目标:

 $ cd $HOME/hello
 $ bitbake printhello
 ERROR: no recipe files to build, check your BBPATH and BBFILES?

 Summary: There was 1 ERROR message shown, returning a non-zero exit code.

我们已经使用配方和层配置文件创建了层,但似乎 BitBake 仍然找不到配方。BitBake 需要一个 conf/bblayers.conf 来列出项目的层。没有这个文件,BitBake 无法找到配方。

11)创建 conf/bblayers.conf:BitBake 使用 conf/bblayers.conf 文件来定位项目所需的层。该文件必须位于项目的 conf 目录中(即本例中的 hello/conf)。

将您的工作目录设置为 hello/conf 目录,然后创建 bblayers.conf 文件,使其包含以下内容:

 BBLAYERS ?= " \
   /home/<you>/mylayer \
   "

您需要在文件中为您提供您自己的信息。

12)使用目标运行 Bitbake:现在您已经提供了 bblayers.conf 文件,运行 bitbake 命令并提供目标:

 $ bitbake printhello
 Parsing recipes: 100% |##################################################################################|
 Time: 00:00:00
 Parsing of 1 .bb files complete (0 cached, 1 parsed). 1 targets, 0 skipped, 0 masked, 0 errors.
 NOTE: Resolving any missing task queue dependencies
 NOTE: Preparing RunQueue
 NOTE: Executing RunQueue Tasks
 ********************
 *                  *
 *  Hello, World!   *
 *                  *
 ********************
 NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.

BitBake 找到了 printhello 配方并成功运行了任务。

说明
第一次执行后,再次重新运行 bitbake printhello 不会导致 BitBake 运行打印相同的控制台输出。这样做的原因是printhello.bb recipe的do_build任务第一次执行成功时,BitBake会为该任务写入一个stamp文件。因此,下次您尝试使用相同的 bitbake 命令运行任务时,BitBake 会注意到戳记,因此确定不需要重新运行任务。如果删除 tmp 目录或运行 bitbake -c clean printhello 然后重新运行构建,“Hello, World!”消息将再次打印。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值