规则
alias
查看规则源代码alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)
alias
规则会创建另一个名称,以便通过该名称引用规则。
别名仅适用于“常规”目标。具体而言,package_group
和 test_suite
不能使用别名。
在大型代码库中,重命名目标文件需要更改许多文件,因此使用别名可能会很有帮助。如果您想针对多个目标重复使用该逻辑,还可以使用别名规则来存储 select 函数调用。
别名规则有自己的可见性声明。在所有其他方面,它都像它引用的规则一样运作(例如,系统会忽略别名上的仅限测试;而是使用所引用规则的仅限测试属性),但存在一些小例外情况:
-
如果命令行中提到了测试的别名,则测试不会运行。如需定义用于运行引用的测试的别名,请使用
test_suite
规则,并在其tests
属性中添加一个目标。 -
定义环境组时,不支持
environment
规则的别名。--target_environment
命令行选项也不支持这些参数。
示例
filegroup( name = "data", srcs = ["data.txt"], ) alias( name = "other", actual = ":data", )
参数
config_setting
查看规则源代码config_setting(name, constraint_values, define_values, deprecation, distribs, features, flag_values, licenses, tags, testonly, values, visibility)
为触发可配置属性而匹配预期的配置状态(以 build 标志或平台限制条件的形式表示)。如需简要了解一般功能,请参阅 select 了解如何使用此规则和 可配置属性。
示例
以下规则会与设置 --compilation_mode=opt
或 -c opt
的任何 build 匹配(在命令行中显式设置,或通过 .bazelrc 文件隐式设置):
config_setting( name = "simple", values = {"compilation_mode": "opt"} )
以下表达式会匹配以 ARM 为目标平台并应用自定义定义 FOO=bar
(例如 bazel build --cpu=arm --define FOO=bar ...
)的任何 build:
config_setting( name = "two_conditions", values = { "cpu": "arm", "define": "FOO=bar" } )
以下表达式会匹配设置了用户定义的标志
--//custom_flags:foo=1
(在命令行上显式设置或在 .bazelrc 文件中隐式设置)的任何 build:
config_setting( name = "my_custom_flag_is_set", flag_values = { "//custom_flags:foo": "1" }, )
以下条件会匹配以 x86_64 架构和 glibc 版本 2.25 为目标平台的任何 build,前提是存在标签为 //example:glibc_2_25
的 constraint_value
。请注意,即使平台定义了除这两个值之外的其他限制条件值,也仍会匹配。
config_setting( name = "64bit_glibc_2_25", constraint_values = [ "@platforms//cpu:x86_64", "//example:glibc_2_25", ] )
config_setting
与顶级命令行标志不匹配,也可能仍与某些 build 目标匹配。
备注
- 如需了解当多个
config_setting
与当前配置状态匹配时会发生什么情况,请参阅 select。 - 对于支持简写形式的标志(例如
--compilation_mode
与-c
),values
定义必须使用完整形式。这些规则会自动匹配使用任一形式的调用。 -
如果某个标志接受多个值(例如
--copt=-Da --copt=-Db
或列表类型的 Starlark 标志),则只要"a"
出现在实际列表中的任意位置,values = { "flag": "a" }
就会匹配。values = { "myflag": "a,b" }
的运作方式相同:此操作会匹配--myflag=a --myflag=b
、--myflag=a --myflag=b --myflag=c
、--myflag=a,b
和--myflag=c,b,a
。确切的语义因标志而异。例如,--copt
不支持在同一实例中使用多个值:--copt=a,b
会生成["a,b"]
,而--copt=a --copt=b
会生成["a", "b"]
(因此values = { "copt": "a,b" }
与前者匹配,但与后者不匹配)。但--ios_multi_cpus
(适用于 Apple 规则)会:-ios_multi_cpus=a,b
和ios_multi_cpus=a --ios_multi_cpus=b
都会生成["a", "b"]
。仔细检查标志定义并测试您的条件,以验证是否符合预期。 - 如果您需要定义不由内置 build 标志建模的条件,请使用 Starlark 定义的标志。您也可以使用
--define
,但支持程度较低,不建议这样做。如需查看更多讨论,请点击此处。 - 避免在不同的软件包中重复相同的
config_setting
定义。 而是引用规范软件包中定义的常见config_setting
。 values
、define_values
和constraint_values
可以在同一config_setting
中以任何组合使用,但对于任何给定的config_setting
,必须设置至少一个。
参数
属性 | |
---|---|
name |
名称(必需) 此目标的唯一名称。 |
constraint_values
|
目标平台为了匹配此 config_setting 而必须指定的最小 constraint_values 集。(此处不考虑执行平台。)平台已忽略的所有其他限制条件值都会被忽略。如需了解详情,请参阅
可配置的 build 属性。
如果两个 如果两个 |
define_values
|
字典:字符串 -> 字符串;不可配置;默认为 values 相同,但专门针对 --define 标志。
这意味着: config_setting( name = "a_and_b", values = { "define": "a=1", "define": "b=2", }) 不起作用,因为字典中出现了相同的键 ( config_setting( name = "a_and_b", define_values = { "a": "1", "b": "2", }) 与
|
flag_values
|
字典:label -> 字符串;不可配置;默认值为 values 相同,但适用于用户定义的 build 标志。
这是个独特的属性,因为用户定义的标志是作为标签引用的,而内置标志是作为任意字符串引用的。 |
values
|
字典:String -> String;不可配置;默认值为 此规则会继承在 为方便起见,配置值以 build 标志的形式指定(不带前面的 如果未在命令行中明确设置标志,则系统会使用其默认值。
如果字典中某个键出现多次,则仅使用最后一个实例。
如果密钥引用可在命令行中多次设置的标志(例如
|
filegroup
查看规则源代码filegroup(name, srcs, data, compatible_with, deprecation, distribs, features, licenses, output_group, restricted_to, tags, target_compatible_with, testonly, visibility)
使用 filegroup
可收集一组目标在单个标签下的输出。
filegroup
不能替代在命令行或其他规则的属性中列出目标,因为目标除了输出之外,还有许多其他属性,这些属性的收集方式不同。但是,在很多情况下,它仍然很有用,例如,在 Genrule 的 srcs
属性中,或 *_binary 规则的 data
属性中。
建议使用 filegroup
,而不是直接引用目录。不建议直接引用目录,因为构建系统无法完全了解目录下的所有文件,因此当这些文件发生变化时,它可能不会重新构建。与 glob 结合使用时,filegroup
可确保编译系统明确知道所有文件。
示例
如需创建由两个源文件组成的 filegroup
,请执行以下操作:
filegroup( name = "mygroup", srcs = [ "a_file.txt", "//a/library:target", "//a/binary:target", ], )
或者,使用 glob
完全抓取 testdata 目录:
filegroup( name = "exported_testdata", srcs = glob([ "testdata/*.dat", "testdata/logs/**/*.log", ]), )
如需使用这些定义,请使用任意规则中的标签引用 filegroup
:
cc_library( name = "my_library", srcs = ["foo.cc"], data = [ "//my_package:exported_testdata", "//my_package:mygroup", ], )
参数
属性 | |
---|---|
name |
名称;必需 此目标的唯一名称。 |
srcs
|
标签列表;默认值为
通常使用 glob 表达式的结果作为 |
data
|
标签列表;默认值为
|
output_group
|
字符串;默认值为 “输出组”是目标的输出工件类别,在相应规则的实现中指定。 |
Genquery
查看规则来源genquery(name, deps, data, compatible_with, compressed_output, deprecation, distribs, exec_compatible_with, exec_properties, expression, features, licenses, opts, restricted_to, scope, strict, tags, target_compatible_with, testonly, visibility)
genquery()
会运行 Bazel 查询语言中指定的查询,并将结果转储到文件中。
为了保持 build 的一致性,查询只能访问 scope
属性中指定的目标的传递闭包。如果 strict
未指定或 true,则违反此规则的查询将在执行期间失败(如果 strict
为 false,系统会跳过超出范围的目标,并发出警告)。若要避免发生这种情况,最简单的方法是在范围中提及与查询表达式相同的标签。
此处允许的查询与命令行允许的查询之间的唯一区别在于,此处不允许使用包含通配目标规范(例如 //pkg:*
或 //pkg:all
)的查询。
原因有二:首先,genquery
必须指定一个作用域,以防止查询传递闭包之外的目标影响其输出;其次,BUILD
文件不支持通配符依赖项(例如,不允许使用 deps=["//a/..."]
)。
为了强制执行确定性输出,genquery 的输出会按字典顺序排序,但 --output=graph|minrank|maxrank
或 somepath
用作顶级函数的情况除外。
输出文件的名称是规则的名称。
示例
此示例会将指定目标的传递闭包中的标签列表写入文件。
genquery( name = "kiwi-deps", expression = "deps(//kiwi:kiwi_lib)", scope = ["//kiwi:kiwi_lib"], )
参数
属性 | |
---|---|
name |
名称(必需) 此目标的唯一名称。 |
compressed_output
|
布尔值;默认值为 True ,则查询输出以 GZIP 文件格式写入。当查询输出预计会很大时,此设置可用于避免 Bazel 的内存使用量激增。无论此设置的值如何,Bazel 都会在内部压缩大于 220 字节的查询输出,因此将其设置为 True 可能不会减少保留的堆。不过,这允许 Bazel 在写入输出文件时跳过解压缩,而解压缩操作可能会占用大量内存。
|
expression
|
字符串;必需 要执行的查询。与命令行和 BUILD 文件中的其他位置不同,此处的标签相对于工作区的根目录进行解析。例如,文件a/BUILD 中此属性中的标签 :b 将引用目标 //:b 。
|
opts
|
字符串列表;默认值为 bazel query 的命令行选项。此处不允许使用以下查询选项:--keep_going 、--query_file 、--universe_scope 、--order_results 和 --order_output 。与 bazel query 的命令行一样,此处未指定的选项将采用默认值。
|
scope
|
标签列表;必需 查询的范围。查询不得触及这些目标的传递闭包之外的目标。 |
strict
|
布尔值;默认值为 |
genrule
查看规则源代码genrule(name, srcs, outs, cmd, cmd_bash, cmd_bat, cmd_ps, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, executable, features, licenses, local, message, output_licenses, output_to_bindir, restricted_to, tags, target_compatible_with, testonly, toolchains, tools, visibility)
genrule
使用用户定义的 Bash 命令生成一个或多个文件。
Genrule 是通用 build 规则,如果没有针对任务的特定规则,您可以使用它。
例如,您可以运行 Bash 一行代码。不过,如果您需要编译 C++ 文件,请遵循现有的 cc_*
规则,因为系统已为您完成所有繁重工作。
请注意,genrule 需要 shell 来解析命令参数。 您还可以轻松引用 PATH 上可用的任意程序,但这会使命令不具封闭性,并且可能无法重现。 如果您只需运行单个工具,请考虑改用 run_binary。
与所有其他操作一样,genrules 创建的操作不应对其工作目录做出任何假设;Bazel 仅保证其声明的输入将在 $(location)
为其标签返回的路径中可用。例如,如果操作是在沙盒中或远程运行,则沙盒的实现或远程执行将决定工作目录。如果直接运行(使用 standalone
策略),工作目录将是执行根目录,即 bazel info execution_root
的结果。
请勿使用 genrule 运行测试。系统会对测试和测试结果(包括缓存政策和环境变量)提供特殊豁免。测试通常需要在构建完成后在目标架构上运行,而 genrule 是在构建期间以及在 exec 架构上执行的(两者可能不同)。如果您需要通用测试规则,请使用 sh_test
。
交叉编译注意事项
如需详细了解交叉编译,请参阅用户手册。
虽然 genrule 在构建期间运行,但其输出通常在构建后用于部署或测试。不妨考虑为微控制器编译 C 代码的示例:编译器接受 C 源文件,并生成在微控制器上运行的代码。生成的代码显然无法在用于构建它的 CPU 上运行,但 C 编译器(如果是从源代码编译的)本身必须在该 CPU 上运行。
构建系统使用 exec 配置来描述构建运行的机器,并使用目标配置来描述构建输出应运行的机器。它提供了配置每种类型的选项,并将相应的文件分隔到单独的目录中,以避免冲突。
对于 genrule,构建系统会确保正确构建依赖项:为 target 配置构建 srcs
(如果需要),为 exec 配置构建 tools
,并将输出视为适用于 target 配置。它还提供
“Make”变量,genrule 命令可以将其传递给相应的工具。
Genrule 有意不定义任何 deps
属性:其他内置规则使用规则之间传递的与语言相关的元信息自动确定如何处理从属规则,但这种级别的自动化不适用于 Genrule。Genrule 仅在文件和 runfile 级别运行。
特殊情况
Exec-exec 编译:在某些情况下,构建系统需要运行 genrule,以便在构建期间也能执行输出。例如,如果某个 genrule 构建了某个自定义编译器,而该编译器随后被另一个 genrule 使用,则第一个 genrule 必须为 exec 配置生成输出,因为编译器将在另一个 genrule 中运行。在这种情况下,构建系统会自动执行正确的操作:它会为执行配置(而非目标配置)构建第一个 genrule 的 srcs
和 outs
。如需了解详情,请参阅用户手册。
JDK 和 C++ 工具:如需使用 JDK 或 C++ 编译器套件中的工具,构建系统提供了一组可供使用的变量。如需了解详情,请参阅“品牌”变量。
Genrule 环境
genrule 命令由 Bash shell 执行,该 shell 配置为在命令或流水线失败时使用 set -e -o pipefail
失败。
构建工具会在仅定义核心变量(如 PATH
、PWD
、TMPDIR
等)的已清理进程环境中执行 Bash 命令。
为确保 build 可重现,用户 shell 环境中定义的大多数变量都不会传递给 genrule 的命令。但是,Bazel(而不是 Blaze)会传递用户的 PATH
环境变量的值。对 PATH
的值所做的任何更改都会导致 Bazel 在下次构建时重新执行该命令。
genrule 命令不得访问网络,但可以连接该命令本身的子进程,不过目前系统不会强制执行此限制。
构建系统会自动删除所有现有输出文件,但会在运行 genrule 之前创建所有必要的父目录。它还会在发生失败时移除所有输出文件。
一般建议
- 确保由 Genrule 运行的工具具有确定性和封闭性。它们不应将时间戳写入输出,应对集合和映射使用稳定的排序,并且仅将相对文件路径写入输出,而不要写入绝对路径。不遵循此规则将导致意外的构建行为(Bazel 不会重新构建您认为它会重新构建的 genrule),并降低缓存性能。
- 请广泛使用
$(location)
,用于输出、工具和来源。由于输出文件会按不同的配置进行分隔,因此 genrule 不能依赖于硬编码的绝对路径。 - 请编写通用的 Starlark 宏,以防在多个位置使用相同或非常相似的 genrule。如果 genrule 较为复杂,不妨考虑在脚本中或作为 Starlark 规则实现它。这有助于提高可读性和可测试性。
- 请务必确保退出代码正确指示 genrule 的成功或失败。
- 请勿将信息消息写入 stdout 或 stderr。虽然这对于调试很有用,但很容易变成噪音;成功的 Genrule 应该是静音的。另一方面,失败的 genrule 应发出良好的错误消息。
$$
evaluates to a$
, a literal dollar-sign, so in order to invoke a shell command containing dollar-signs such asls $(dirname $x)
, one must escape it thus:ls $$(dirname $$x)
。- 避免创建符号链接和目录。Bazel 不会复制 genrule 创建的目录/符号链接结构,并且其对目录的依赖项检查不健全。
- 在其他规则中引用 Genrule 时,您可以使用 genrule 的标签或各个输出文件的标签。有时,一种方法更易于阅读,有时另一种方法更易于阅读:在使用规则的
srcs
中按名称引用输出可避免无意中提取 genrule 的其他输出,但如果 genrule 生成多个输出,则可能会很繁琐。
示例
此示例会生成 foo.h
。没有来源,因为该命令不接受任何输入。该命令运行的“二进制文件”是 genrule 所在软件包中的 perl 脚本。
genrule( name = "foo", srcs = [], outs = ["foo.h"], cmd = "./$(location create_foo.pl) > \"$@\"", tools = ["create_foo.pl"], )
以下示例展示了如何使用 filegroup
以及另一个 genrule
的输出。请注意,使用 $(SRCS)
而非显式 $(location)
指令也可以;此示例出于演示目的使用了后者。
genrule( name = "concat_all_files", srcs = [ "//some:files", # a filegroup with multiple files in it ==> $(locations) "//other:gen", # a genrule with a single output ==> $(location) ], outs = ["concatenated.txt"], cmd = "cat $(locations //some:files) $(location //other:gen) > $@", )
参数
属性 | |
---|---|
name |
名称(必需) 此目标的唯一名称。 您可以在其他 BUILD 规则的 srcs 或 deps 部分中按名称引用此规则。如果规则生成源文件,您应使用 srcs 属性。
|
srcs
|
标签列表;默认值为
此属性不适用于列出由
构建系统可确保在运行 genrule 命令之前构建这些前提条件;它们使用与原始构建请求相同的配置构建。满足这些前提条件的文件的名称在 |
outs
|
此规则生成的文件列表。
输出文件不得跨越软件包边界。 输出文件名被解释为相对于文件包而言。
如果设置了
genrule 命令应在预先指定的位置创建每个输出文件。
您可以在 |
cmd
|
字符串;默认值为 $(location)
和 “Make”变量。
cmd_bash 、cmd_ps 和 cmd_bat 都不适用,则此值是它们的回退值。
如果命令行长度超出平台限制(在 Linux/macOS 上为 64K,在 Windows 上为 8K),则 genrule 会将命令写入脚本并执行该脚本以解决此问题。这适用于所有 cmd 属性( |
cmd_bash
|
字符串;默认值为 此属性的优先级高于 |
cmd_bat
|
字符串;默认值为 此属性的优先级高于
|
cmd_ps
|
字符串;默认值为 此属性的优先级高于
为了使 Powershell 更易于使用并且不容易出错,我们先运行以下命令来设置环境,然后再在 genrule 中执行 Powershell 命令。
|
executable
|
布尔值;不可配置;默认值为
将此标志设为 True 表示输出是可执行文件,可以使用 不支持为生成的可执行文件声明数据依赖项。 |
local
|
布尔值;默认值为
如果设为 True,此选项会强制此
这相当于将“local”作为标记 ( |
message
|
字符串;默认值为
在执行此构建步骤时,系统会输出进度消息。默认消息是“正在生成输出”(或其他同样平淡无奇的消息),但您可以提供更具体的消息。在 |
output_licenses
|
许可类型;默认值为 common attributes
|
output_to_bindir
|
布尔值;不可配置;默认值为
如果设置为 True,此选项会导致输出文件写入 |
toolchains
|
此 genrule 允许访问的 Make 变量的目标集,或此 genrule 将访问的
通过 |
tools
|
标签列表;默认值为
构建系统会确保在运行 genrule 命令之前构建这些前提条件;由于这些工具会作为构建过程的一部分执行,因此它们是使用 exec 配置构建的。您可以使用
要由 |
starlark_doc_extract
查看规则源代码starlark_doc_extract(name, deps, src, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, render_main_repo_name, restricted_to, symbol_names, tags, target_compatible_with, testonly, visibility)
starlark_doc_extract()
会提取在给定 .bzl
或 .scl
文件中定义或重新导出的规则、函数(包括宏)、方面和提供程序的文档。此规则的输出是 ModuleInfo
二进制 proto,如 Bazel 源代码树的 stardoc_output.proto 所定义。
隐式输出目标
name.binaryproto
(默认输出):ModuleInfo
二进制 proto。name.textproto
(仅在明确请求时构建):name.binaryproto
的文本 proto 版本。
警告:此规则的输出格式不能保证稳定。它主要供 Stardoc 在内部使用。
参数
属性 | |
---|---|
name |
名称;必需 此目标的唯一名称。 |
deps
|
标签列表;默认值为 src load() 的 Starlark 文件的目标列表。在正常使用情况下,这些目标应为 bzl_library 目标,但 starlark_doc_extract 规则不会强制执行此要求,而是接受在 DefaultInfo 中提供 Starlark 文件的任何目标。
请注意,封装的 Starlark 文件必须是源代码树中的文件;Bazel 无法 |
src
|
标签;必填 要从中提取文档的 Starlark 文件。请注意,此文件必须是源代码树中的文件;Bazel 无法 |
render_main_repo_name
|
布尔值;默认值为 //foo:bar.bzl 将作为 @main_repo_name//foo:bar.bzl 发出)。
主代码库使用的名称从主代码库的 为仅在同一代码库中使用的 Starlark 文件生成文档时,应将此属性设为 |
symbol_names
|
字符串列表;默认值为 当且仅当满足以下条件时,
|
test_suite
查看规则源代码test_suite(name, compatible_with, deprecation, distribs, features, licenses, restricted_to, tags, target_compatible_with, testonly, tests, visibility)
test_suite
定义了一组被认为对人类“有用”的测试。这样,项目就可以定义一组测试,例如“您必须在提交之前运行的测试”“我们项目的压力测试”或“所有小型测试”。bazel test
命令遵循了这种组织方式:对于像 bazel test //some/test:suite
这样的调用,Bazel 首先枚举 //some/test:suite
目标以传递方式包含的所有测试目标(我们称之为“test_suite 扩展”),然后 Bazel 会构建并测试这些目标。
示例
一个测试套件,用于运行当前软件包中的所有小测试。
test_suite( name = "small_tests", tags = ["small"], )
运行一组指定测试的测试套件:
test_suite( name = "smoke_tests", tests = [ "system_unittest", "public_api_unittest", ], )
用于运行当前软件包中所有稳定的测试的测试套件。
test_suite( name = "non_flaky_test", tags = ["-flaky"], )
参数
属性 | |
---|---|
name |
名称;必需 此目标的唯一名称。 |
tags
|
字符串列表;不可配置;默认值为 以“-”字符开头的标签会被视为否定关键字。前面的“-”字符不被视为标记的一部分,因此“-small”的套件标记与测试的“small”大小匹配。所有其他代码均被视为正例代码。 (可选)为使肯定标记更加明确,标记也可以以“+”字符开头,该字符不会作为标记文本的一部分进行评估。这只是为了让正负之分更易于读取。 只有与所有正例标记匹配且与所有负例标记都不匹配的测试规则才会包含在测试套件中。请注意,这并不意味着会跳过对被滤除的测试的依赖项的错误检查;被跳过的测试的依赖项仍需要合法(例如不会被可见性约束条件阻止)。
请注意,测试的
如果您需要的 |
tests
|
任何语言的测试套件和测试目标的列表。
此处接受任何
如果 |