前面的部分抽象地介绍了软件包、目标和标签,以及 build 依赖关系图。本部分介绍了用于定义软件包的具体语法。
根据定义,每个软件包都包含一个 BUILD
文件,这是一个简短的程序。
BUILD
文件使用命令式语言 Starlark 进行评估。
它们会被解读为一系列按顺序排列的语句。
一般来说,顺序很重要:例如,必须先定义变量,然后才能使用变量。不过,大多数 BUILD
文件仅包含 build 规则的声明,这些语句的相对顺序无关紧要;重要的是在软件包评估完成时,声明了哪些规则以及这些规则的值。
当执行 build 规则函数(例如 cc_library
)时,会在图中创建一个新目标。稍后可以使用标签引用此目标。
在简单的 BUILD
文件中,规则声明可以随意重新排序,而不会改变行为。
为了鼓励代码和数据之间实现清晰分离,BUILD
文件不能包含函数定义、for
语句或 if
语句(但允许使用列表推导式和 if
表达式)。函数可以改为在 .bzl
文件中声明。此外,BUILD
文件中不允许使用 *args
和 **kwargs
实参;请改为明确列出所有实参。
至关重要的是,Starlark 中的程序无法执行任意 I/O。此不变量使 BUILD
文件的解释具有封闭性,即仅依赖于一组已知的输入,这对于确保构建可重现至关重要。如需了解详情,请参阅Hermeticity。
由于每当底层代码的依赖项发生更改时,都需要更新 BUILD
文件,因此这些文件通常由团队中的多人维护。BUILD
文件作者应添加大量注释,以记录每个 build 目标的角色(无论是否打算公开使用),并记录软件包本身的角色。
加载扩展程序
Bazel 扩展文件以 .bzl
结尾。使用 load
语句从扩展程序导入符号。
load("//foo/bar:file.bzl", "some_library")
此代码会加载文件 foo/bar/file.bzl
并向环境添加 some_library
符号。这可用于加载新规则、函数或常量(例如字符串或列表)。您可以通过在对 load
的调用中使用其他实参来导入多个符号。实参必须是字符串字面量(无变量),并且 load
语句必须出现在顶层,不能位于函数正文中。
load
的第一个实参是用于标识 .bzl
文件的标签。如果它是相对标签,则会相对于包含当前 bzl
文件的软件包(而非目录)进行解析。load
语句中的相对标签应使用前导 :
。
load
还支持别名,因此您可以为导入的符号分配不同的名称。
load("//foo/bar:file.bzl", library_alias = "some_library")
您可以在一个 load
语句中定义多个别名。此外,实参列表可以同时包含别名和常规符号名称。以下示例完全合法(请注意何时使用英文引号)。
load(":my_rules.bzl", "some_rule", nice_alias = "some_other_rule")
在 .bzl
文件中,以 _
开头的符号不会导出,也无法从其他文件加载。
您可以使用加载可见性来限制哪些人可以加载 .bzl
文件。
构建规则的类型
大多数 build 规则都属于某个系列,按语言分组。例如,cc_binary
、cc_library
和 cc_test
分别是 C++ 二进制文件、库和测试的 build 规则。其他语言使用相同的命名方案,但前缀不同,例如 Java 使用 java_*
。其中一些函数已记录在构建百科全书中,但任何人都可以创建新规则。
*_binary
规则用于构建指定语言的可执行程序。构建完成后,可执行文件将位于构建工具的二进制输出树中,并以相应规则标签的名称命名,因此//my:program
将显示在$(BINDIR)/my/program
(例如)中。在某些语言中,此类规则还会创建一个 runfiles 目录,其中包含属于相应规则的
data
属性或其传递依赖项闭包中任何规则中提及的所有文件;这组文件会集中在一个位置,以便轻松部署到生产环境。*_test
规则是*_binary
规则的一种特殊形式,用于自动化测试。测试只是在成功时返回零的程序。与二进制文件一样,测试也有 runfiles 树,并且只有该树下的文件才是测试在运行时可以合法打开的文件。例如,程序
cc_test(name='x', data=['//foo:bar'])
可能会在执行期间打开并读取$TEST_SRCDIR/workspace/foo/bar
。 (每种编程语言都有自己的实用函数来访问$TEST_SRCDIR
的值,但它们都相当于直接使用环境变量。) 如果不遵守此规则,测试在远程测试主机上执行时将会失败。*_library
规则用于指定以给定编程语言单独编译的模块。库可以依赖于其他库,二进制文件和测试可以依赖于库,并具有预期的单独编译行为。
标签 | 依赖项 |
文件编码
BUILD
和 .bzl
文件应采用 UTF-8 编码,其中 ASCII 是有效的子集。目前允许使用任意字节序列,但未来可能不再支持。