本页面介绍了如何使用宏 和规则扩展 BUILD 语言。
Bazel 扩展是扩展名为 .bzl 的文件。使用
load 语句从扩展中导入符号。
在学习更高级的概念之前,请先执行以下操作:
了解 Starlark 语言,用于
BUILD和.bzl文件。了解如何在两个
BUILD文件之间共享变量。
宏和规则
宏是实例化规则的函数。宏有两种类型:
符号宏(Bazel 8 中的新功能)和旧版
宏。这两种类型的宏的定义方式
不同,但从用户的角度来看,其行为几乎相同。当 BUILD 文件变得过于重复或过于复杂时,A
宏非常有用,as
它允许您重复使用一些代码。系统会在读取 BUILD
文件后立即评估该函数。在评估 BUILD 文件后,Bazel 几乎没有
关于宏的信息。如果您的宏生成 genrule,Bazel 将
表现得 几乎 就像您在 BUILD 文件中声明了该 genrule 一样。(一个
例外是,在符号宏中声明的目标具有特殊的可见性
语义:符号宏可以向软件包的其余部分隐藏其内部
目标。)
规则比宏更强大。它可以访问 Bazel 内部结构,并完全控制正在发生的事情。例如,它可以将 信息传递给其他规则。
如果您想重复使用简单的逻辑,请从宏开始;我们建议使用符号 宏,除非您需要支持旧版 Bazel。如果宏变得 复杂,最好将其设为规则。对新语言的支持 通常通过规则完成。规则适用于高级用户,大多数用户永远不必编写规则;他们只会加载和调用现有规则。
评估模型
构建包含三个阶段。
加载阶段。首先,加载并评估构建所需的所有扩展和所有
BUILD文件。BUILD文件的执行只是 实例化规则(每次调用规则时,都会将其添加到图中)。 宏在此阶段进行评估。分析阶段。规则的代码(其
implementation函数)会执行,并且操作会实例化。操作描述了如何生成 一组输出,例如“在 hello.c 上运行 gcc 并获取 hello.o”。您必须在 执行实际命令之前明确列出将生成哪些文件。换句话说,分析阶段会获取 加载阶段生成的图,并生成操作图。执行阶段。当至少需要一个操作的输出时,系统会执行这些操作。如果缺少文件或命令无法生成输出, 构建就会失败。测试也会在此阶段运行。
Bazel 使用并行处理来读取、解析和评估 .bzl 文件和 BUILD
文件。每个文件在每次构建中最多读取一次,并且评估结果会
被缓存并重复使用。只有在解析完文件的所有依赖项(load()
语句)后,才会评估该文件。按照设计,加载 .bzl 文件没有可见的
副作用,它只会定义值和函数。
Bazel 会尝试变得更智能:它使用依赖项分析来了解必须 加载哪些文件、必须分析哪些规则以及必须执行哪些操作。例如,如果某条规则生成了当前构建不需要的操作,则不会执行这些操作。
创建扩展
创建您的第一个宏,以便重复使用一些代码。 然后,详细了解宏以及如何使用宏创建 “自定义动词”。
在编写自己的扩展时,以下两个链接非常有用。请将 它们放在方便取用的位置:
深入了解
始终使用 Buildifier 来格式化代码并对其进行 lint。
遵循
.bzl样式指南。测试您的代码。
生成文档以帮助您的用户。