2022 年 BazelCon 将于 11 月 16 日至 17 日在纽约和线上举办。
立即报名!

构建文件

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

前面的部分简要介绍了软件包、目标、标签和构建依赖项图。本部分介绍了用于定义软件包的具体语法。

根据定义,每个软件包都包含一个 BUILD 文件,这是一个简短的程序。BUILD 文件使用命令式语言 Starlark 进行评估。

它们会被解读为一系列连续的语句。

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

当执行构建规则函数(如 cc_library)时,它会在图中创建一个新的目标。此目标稍后可使用标签进行引用。

在简单的 BUILD 文件中,您可以随意对规则声明进行重新排序,而无需更改行为。

为了促进代码和数据之间的完全分离,BUILD 文件不能包含函数定义、for 语句或 if 语句(但允许使用列表理解和 if 表达式)中披露政府所要求信息的数量和类型。可以在 .bzl 文件中声明函数。此外,BUILD 文件中还不允许使用 *args**kwargs 参数;改为明确列出所有参数。

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

BUILD 文件应仅用 ASCII 字符编写,但从技术上讲,它们是使用 Latin-1 字符集解释的。

由于 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 文件中,以 _ 开头的符号不会被导出,无法从其他文件加载。可见性不会影响加载(您无需使用 exports_files 公开 .bzl 文件)。

构建规则的类型

大多数构建规则都来自系列,并按语言组合在一起。例如,cc_binarycc_librarycc_test 分别是 C++ 二进制文件、库和测试的构建规则。其他语言使用相同的命名方案,但采用不同的前缀,例如 java_* for Java。其中一些函数记录在 Build Encyclopedia 中,但任何人都可以创建新规则。

  • *_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 规则用于指定给定编程语言中单独编译的模块。库可以依赖于其他库,而二进制文件和测试可以依赖于具有预期单独编译行为的库。

标签 依赖项