扩展程序概览

本页面介绍如何使用宏和规则扩展 BUILD 语言。

Bazel 扩展程序是一些以 .bzl 结尾的文件。使用 load 语句从扩展导入符号。

在学习更高级的概念之前,请先执行以下操作:

  • 了解 BUILD.bzl 文件中使用的 Starlark 语言

  • 了解如何在两个 BUILD 文件之间共享变量

宏和规则

是实例化规则的函数。当 BUILD 文件过于重复或过于复杂时,它就非常有用,因为它允许您重复使用某些代码。系统会在读取 BUILD 文件后立即评估该函数。评估 BUILD 文件后,Bazel 很少掌握宏的相关信息:如果您的宏生成了 genrule,Bazel 的行为就像您编写 genrule 一样。因此,bazel query 将仅列出生成的 genrule

规则比宏更强大。它可以访问 Bazel 内部信息,并完全掌控将要处理的内容。例如,它可以将信息传递给其他规则。

如果您想重复使用简单的逻辑,请从宏开始。如果宏变得复杂,通常最好使其成为规则。对新语言的支持通常通过规则来实现。规则适用于高级用户,大多数用户永远都不需要编写规则;它们只会加载和调用现有规则。

评估模型

build 由三个阶段组成。

  • 加载阶段。首先,加载并评估构建所需的所有扩展程序和所有 BUILD 文件。执行 BUILD 文件只会实例化规则(每次调用规则时,系统都会将其添加到图表中)。这是评估宏的位置。

  • 分析阶段。系统将执行规则的代码(其 implementation 函数),并将操作实例化。一个操作描述了如何从一组输入生成一组输出,如“在 hello.c 上运行 gcc 和获取 hello.o”。在执行实际命令之前,必须明确列出将生成哪些文件。换句话说,分析阶段接受由加载阶段生成的图并生成操作图。

  • 执行阶段。需要至少一项输出时,系统才会执行操作。如果文件缺失,或者某个命令无法生成一条输出,则构建会失败。在此阶段还会运行测试。

Bazel 使用并行处理来读取、解析和评估 .bzl 文件和 BUILD 文件。每个 build 最多读取一次文件,并且评估结果会被缓存并重复使用。只有在所有文件依赖项(load() 语句)都得到解决后,系统才会对文件进行评估。按照设计,加载 .bzl 文件不会产生任何副作用,它只会定义值和函数。

Bazel 会很智能:它使用依赖项分析来了解必须加载哪些文件、必须分析哪些规则,以及必须执行哪些操作。例如,如果规则生成的操作对当前构建不需要,则系统不会执行这些操作。

创建扩展程序

在创建您自己的扩展程序时,以下两个链接非常有用。让它们始终触手可及:

更进一步

除了规则之外,您可能还需要编写方面代码库规则