构建文件

报告问题 查看源代码

前面的几个部分抽象地说明了软件包、目标和标签,以及构建依赖项图。本部分介绍了定义软件包的具体语法。

根据定义,每个软件包都包含一个 BUILD 文件,这是一个短程序。

BUILD 文件通过命令式语言 Starlark 进行评估。

它们会被解读为语句的依序列表。

一般来说,顺序至关重要:例如,必须在使用变量之前对其进行定义。不过,大多数 BUILD 文件仅包含构建规则的声明,并且这些语句的相对顺序无关紧要;重要的是,在软件包评估完成时声明了哪些规则及其值。

执行构建规则函数(例如 cc_library)时,它会在图中创建新目标。之后可通过标签来引用该目标。

在简单的 BUILD 文件中,规则声明可以随意重新排序,而不改变行为。

为了鼓励代码和代码完全区分,BUILD 文件不能包含函数定义、for 语句或 if 语句(但允许使用列表理解和 if 表达式)。您可以改为在 .bzl 文件中声明函数。此外,BUILD 文件中不允许使用 *args**kwargs 参数;请明确列出所有参数。

最重要的是,Starlark 中的程序无法执行任意 I/O。这种不变的特性使得对 BUILD 文件的解释变得封闭,仅依赖于一组已知的输入,这对于确保构建可以重现至关重要。 如需了解详情,请参阅Hermetic

BUILD 文件应使用 ASCII 字符编写,但从技术上讲,这些文件是使用 Latin-1 字符集进行解释的。

由于每当底层代码的依赖项发生更改时,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 规则类型

大多数 build 规则都属于家庭,它们按语言组合在一起。例如,cc_binarycc_librarycc_test 分别是 C++ 二进制文件、库和测试的构建规则。其他语言会采用相同的命名方案,但采用不同的前缀,例如适用于 Java 的 java_*build 百科全书中记录了其中一些函数,但任何人都可以创建新规则。

  • *_binary 规则可用于构建给定语言的可执行程序。构建后,可执行文件将位于构建工具的二进制文件输出树中,位于规则标签的相应名称上,因此 //my:program(例如)将显示在 $(BINDIR)/my/program

    在一些编程语言中,此类规则还会创建一个 runfiles 目录,其中包含属于该规则的 data 属性中提及的所有文件,或者其传递依赖项关闭中的任何规则;这些文件集会集中在一起,以方便部署到生产环境。

  • *_test 规则是 *_binary 规则的专用规则,用于自动测试。测试只是在成功时返回零的程序。

    与二进制文件一样,测试也具有 runfile 树,并且文件在其下方是唯一可以在运行时合法打开的文件。例如,程序 cc_test(name='x', data=['//foo:bar']) 可以在执行期间打开和读取 $TEST_SRCDIR/workspace/foo/bar。 (每种编程语言都有自己的实用函数用于访问 $TEST_SRCDIR 的值,但它们等效于直接使用环境变量。) 未通过观察的规则将导致测试在远程测试主机上执行失败。

  • *_library 规则以指定给定的编程语言指定单独编译的模块。库可以依赖于其他库,二进制文件和测试可以依赖于库,并且具有预期的单独编译行为。

标签 依赖项