前面的部分抽象地介绍了软件包、目标和标签,以及 构建依赖关系图。本部分介绍了用于定义软件包的具体语法 。
根据定义,每个软件包都包含一个 BUILD 文件,这是一个简短
程序。
BUILD 文件使用命令式语言
Starlark 进行评估。
它们被解释为一系列语句。
一般来说,顺序很重要:例如,变量必须先定义后
使用。不过,大多数 BUILD 文件仅包含构建规则的声明,这些语句的相对顺序并不重要;重要的是在软件包评估完成时,声明了哪些规则以及使用了哪些值。
执行构建规则函数(例如 cc_library)时,它会在图中创建一
个新目标。稍后可以使用标签引用此目标。
在简单的 BUILD 文件中,可以随意重新排序规则声明,而不会
更改行为。
为了鼓励代码和数据之间的清晰分离,BUILD 文件不能
包含函数定义、for 语句或 if 语句(但允许使用列表
推导式和 if 表达式)。函数可以在
.bzl 文件中声明。此外,*args 和 **kwargs 实参在 BUILD 文件中不
允许使用;请改为明确列出所有实参。
至关重要的是,Starlark 中的程序无法执行任意 I/O。此不变量
使得 BUILD 文件的解释是密封的,仅依赖于一组已知的
输入,这对于确保构建可重现至关重要。
如需了解详情,请参阅Hermeticity。
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 的第一个实参是用于标识 label
.bzl 文件的标签。如果是相对标签,则相对于包含当前 bzl 文件的
软件包(而非目录)进行解析。`load` 语句中的相对标签应使用前导 :。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 文件。
构建规则的类型
大多数构建规则都属于某个系列,按
语言分组在一起。例如,cc_binary、cc_library
和 cc_test 分别是 C++ 二进制文件、
库和测试的构建规则。其他语言使用相同的
命名方案,但前缀不同,例如 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规则以给定的 编程语言指定单独编译的模块。库可以依赖于其他库, 二进制文件和测试可以依赖于库,并具有预期的 单独编译行为。
| 标签 | 依赖项 |