本页介绍了如何使用宏和规则扩展 BUILD 语言。
Bazel 扩展程序是以 .bzl
结尾的文件。使用 load 语句从扩展程序导入符号。
在学习更高级的概念之前,请先:
了解
BUILD
和.bzl
文件中使用的 Starlark 语言。了解如何在两个
BUILD
文件之间共享变量。
宏和规则
宏是用于对规则进行实例化的函数。当 BUILD
文件过于重复或过于复杂时,这会很有用,因为它允许您重复使用一些代码。系统会在读取 BUILD
文件后立即评估该函数。在对 BUILD
文件求值后,Bazel 几乎没有关于宏的信息:如果您的宏生成了 genrule
,Bazel 会像您编写了 genrule
一样。因此,bazel query
将仅列出生成的 genrule
。
规则比宏更强大。它可以访问 Bazel 内部,并完全掌控发生的情况。例如,它可以将信息传递给其他规则。
如果您想重复使用简单的逻辑,请从宏着手。如果宏变得复杂,通常最好将其设为规则。通常可以使用规则来实现对新语言的支持。规则适用于高级用户,大多数用户永远无需编写规则;他们只需加载并调用现有规则。
评估模型
build 包含三个阶段。
加载阶段。首先,加载并评估 build 所需的所有扩展程序和所有
BUILD
文件。执行BUILD
文件只是实例化规则(每次调用规则时,系统都会将其添加到图表中)。系统会对宏进行评估。分析阶段。执行规则的代码(其
implementation
函数),并实例化操作。操作描述了如何根据一组输入(例如,“在 hello.c 和 hello.o 上运行 gcc”)生成一组输出。在执行实际命令之前,您必须明确列出将生成哪些文件。换言之,分析阶段会采用加载阶段生成的图并生成操作图。执行阶段。当需要至少一项输出时,执行操作。如果文件缺失或某个命令未能生成一项输出,构建就会失败。在此阶段还会运行测试。
Bazel 使用并行处理来读取、解析和评估 .bzl
文件和 BUILD
文件。每个构建最多只能读取一个文件,并且会缓存和重复使用评估结果。文件只有在所有依赖项(load()
语句)都经过解析后才会进行求值。根据设计,加载 .bzl
文件不会产生明显的副作用,而是仅定义值和函数。
Bazel 非常聪明:它使用依赖项分析功能来确定必须加载哪些文件、必须分析哪些规则以及必须执行哪些操作。例如,如果规则生成当前构建不需要的操作,则不会执行这些规则。
创建扩展程序
创建您的第一个宏以便重复使用某些代码。然后详细了解宏,并使用宏创建“自定义动词”。
在编写自己的附加信息时,以下两个链接将非常有用。触手可及: