常见定义

报告问题 查看来源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

本部分定义了许多函数或 build 规则通用的各种术语和概念。

目录

Bourne shell 词元化

某些规则的特定字符串属性会根据 Bourne shell 的分词规则拆分为多个字词:未加引号的空格用于分隔不同的字词,而单引号、双引号和反斜杠字符用于防止分词。

本文档中明确指出哪些属性需要进行这种标记化处理。

受“Make”变量扩展和 Bourne shell 令牌化影响的属性通常用于将任意选项传递给编译器和其他工具。此类属性的示例包括 cc_library.coptsjava_library.javacopts。 通过这些替换,单个字符串变量可以扩展为特定于配置的选项字词列表。

标签扩展

极少数规则的某些字符串属性会进行标签扩展:如果这些字符串包含有效的标签作为子字符串(例如 //mypkg:target),并且该标签是当前规则的已声明前提条件,则会扩展为 目标 //mypkg:target 所表示文件的路径名。

属性示例包括 genrule.cmdcc_binary.linkopts。在每种情况下,详细信息可能会有很大差异,例如:是否展开相对标签;如何处理展开为多个文件的标签等。有关具体信息,请参阅规则属性文档。

大多数 build 规则定义的典型属性

本部分介绍了许多构建规则(但并非所有规则)定义的属性。

属性 说明
data

标签列表;默认值为 []

此规则在运行时所需的文件。可能会列出文件或规则目标。通常允许任何目标。

data 属性中目标的默认输出和 runfile 应显示在由相应目标输出或对相应目标具有运行时依赖关系的任何可执行文件的 *.runfiles 区域中。这可能包括执行相应目标平台的 srcs 时使用的数据文件或二进制文件。如需详细了解如何依赖和使用数据文件,请参阅数据依赖项部分。

如果新规则处理的输入可能会在运行时使用其他输入,则应定义 data 属性。规则的实现函数还必须根据任何 data 属性的输出和 runfiles 以及提供源代码或运行时依赖项的任何依赖项属性的 runfiles,填充目标的 runfiles

deps

标签列表;默认值为 []

相应目标的依赖项。通常应仅列出规则目标。(不过,有些规则允许直接在 deps 中列出文件,但应尽可能避免这样做。)

特定于语言的规则通常会将列出的目标限制为具有特定提供商的目标。

目标依赖于使用 deps 的另一个目标的具体语义因规则类型而异,规则特定的文档会对此进行更详细的说明。对于处理源代码的规则,deps 通常指定 srcs 中代码使用的代码依赖项。

通常,deps 依赖项用于允许一个模块使用以相同编程语言编写并单独编译的另一模块中定义的符号。在许多情况下,也允许使用跨语言依赖项:例如,java_library 目标可以通过在 deps 属性中列出 cc_library 目标来依赖于 cc_library 目标中的 C++ 代码。如需了解详情,请参阅依赖项的定义。

licenses

字符串列表;不可配置;默认值为 ["none"]

要用于此特定目标的许可类型字符串列表。 这是 Bazel 不再使用的已弃用的许可 API 的一部分。请勿使用此功能。

srcs

标签列表;默认值为 []

此规则处理或包含的文件。通常直接列出文件,但也可以列出规则目标(例如 filegroupgenrule)以包含其默认输出。

特定于语言的规则通常要求所列文件具有特定的文件扩展名。

所有 build 规则通用的属性

本部分介绍隐式添加到所有 build 规则的属性。

属性 说明
aspect_hints

标签列表;默认值为 []

一个任意标签列表,该列表会公开给 aspect(尤其是由此规则的反向依赖项调用的 aspect),但不会公开给此规则自身的实现。如需详细了解特定方面提示会产生什么效果,请参阅特定于语言的规则集的相关文档。

您可以将方面提示视为比标记更丰富的替代方案:标记仅传达布尔值状态(标记在 tags 列表中存在或不存在),而方面提示可以在其 providers 中传达任意结构化信息。

在实践中,宽高比提示用于实现不同语言特定规则集之间的互操作性。例如,假设您有一个 mylang_binary 目标,该目标需要依赖于 otherlang_library 目标。MyLang 特有的逻辑需要有关 OtherLang 目标的一些额外信息才能使用,但 otherlang_library 不提供此信息,因为它对 MyLang 一无所知。一种解决方案可能是让 MyLang 规则集定义一个 mylang_hint 规则,该规则可用于对该附加信息进行编码;用户可以将提示添加到其 otherlang_libraryaspect_hints 中,而 mylang_binary 可以使用方面从 mylang_hint 中特定于 MyLang 的提供程序收集附加信息。

如需查看具体示例,请参阅 rules_swift 中的 swift_interop_hintswift_overlay

最佳做法:

  • aspect_hints 中列出的目标应是轻量级且最小化的。
  • 特定于语言的逻辑应仅考虑具有与该语言相关的提供程序的方面提示,并应忽略任何其他方面提示。
compatible_with

标签列表;不可配置;默认值为 []

此目标可构建的环境列表,除了默认支持的环境之外。

这是 Bazel 约束系统的一部分,可让用户声明哪些目标可以相互依赖,哪些目标不能相互依赖。例如,外部可部署的二进制文件不应依赖于包含公司机密代码的库。如需了解详情,请参阅 ConstraintSemantics

deprecation

字符串;不可配置;默认值为 None

与此目标相关联的说明性警告消息。 通常,此属性用于通知用户目标已过时、已被其他规则取代、是软件包私有的,或者可能因某种原因而被视为有害。最好添加一些参考信息(例如网页、bug 编号或迁移 CL 示例),以便用户轻松了解需要进行哪些更改才能避免显示该消息。如果有一个新的目标可以作为替代目标,那么最好将旧目标的所有用户都迁移到新目标。

此属性对构建方式没有影响,但可能会影响构建工具的诊断输出。当其他软件包中的目标依赖于具有 deprecation 属性的规则时,构建工具会发出警告。

软件包内部依赖项不受此警告的限制,因此,例如,构建已弃用规则的测试不会遇到警告。

如果某个已弃用的目标依赖于另一个已弃用的目标,则不会发出警告消息。

当用户不再使用该目标时,可以将其移除。

exec_compatible_with

标签列表;不可配置;默认值为 []

此目标的默认执行组的执行平台中必须存在的 constraint_values 列表。这是对规则类型已设置的任何限制的补充。 限制条件用于限制可用的执行平台列表。 如需了解详情,请参阅工具链解析的说明。 以及执行组

exec_group_compatible_with

字符串到标签列表的字典;不可配置;默认值为 {}

一个字典,其中包含执行组名称到必须在给定执行组的执行平台中存在的 constraint_values 列表的映射。这是对执行组定义中已设置的任何限制的补充。 限制条件用于限制可用的执行平台列表。 如需了解详情,请参阅工具链解析的说明。 以及执行组

exec_properties

字符串字典;默认值为 {}

一个字符串字典,将添加到为此目标选择的平台的 exec_properties 中。请参阅平台规则的 exec_properties

如果某个键同时出现在平台级和目标级属性中,则系统会从目标级属性中获取相应的值。

键可以添加执行组名称作为前缀,后跟 .,以仅将这些键应用于该特定执行组。

features

功能字符串列表;默认值为 []

功能是可在目标上启用或停用的字符串标记。功能的含义取决于规则本身。

features 属性与 软件包features 属性相结合。例如,如果已在软件包级别启用 ["a", "b"] 这两项功能,并且目标的 features 属性包含 ["-a", "c"],则为相应规则启用的功能将为“b”和“c”。 查看示例

package_metadata

标签列表;不可配置;默认值为软件包的 default_package_metadata

与此目标相关联的标签列表,其中包含相关元数据。 通常,标签是返回常量值提供程序的简单规则。规则和方面可以使用这些标签对 build 图执行一些额外的分析。

规范用例是 rules_license。对于该用例,package_metadatadefault_package_metadata 用于将有关软件包许可或版本的信息附加到目标。应用于顶级二进制文件的方面可用于收集这些信息并生成合规性报告。

restricted_to

标签列表;不可配置;默认值为 []

相应目标可构建的环境列表,而非默认支持的环境。

这是 Bazel 限制系统的一部分。如需了解详情,请参阅 compatible_with

tags

字符串列表;不可配置;默认值为 []

标记可用于任何规则。测试和 test_suite 规则上的标记有助于对测试进行分类。 非测试目标上的 tags 用于控制 genruleStarlark 操作的沙盒执行,以及供人工和/或外部工具进行解析。

如果 Bazel 在任何测试或 genrule 目标的 tags 属性中,或者在任何 Starlark 操作的 execution_requirements 的键中找到以下关键字,就会修改其沙盒代码的行为。

  • no-sandbox 关键字会导致操作或测试永远不会被沙盒化;它仍然可以被缓存或远程运行 - 使用 no-cacheno-remote 来防止其中一种或两种情况。
  • no-cache 关键字会导致操作或测试永远不会被缓存(本地或远程)。注意:对于此标记而言,磁盘缓存被视为本地缓存,而 HTTP 和 gRPC 缓存被视为远程缓存。其他缓存(例如 Skyframe 或持久操作缓存)不受影响。
  • no-remote-cache 关键字会导致操作或测试永远不会被远程缓存(但可能会被本地缓存;也可能会被远程执行)。 注意:对于此标记而言,磁盘缓存被视为本地缓存,而 HTTP 和 gRPC 缓存被视为远程缓存。其他缓存(例如 Skyframe 或持久操作缓存)不受影响。 如果同时使用本地磁盘缓存和远程缓存(组合缓存),则该缓存会被视为远程缓存并完全停用,除非设置了 --incompatible_remote_results_ignore_disk,在这种情况下会使用本地组件。
  • no-remote-exec 关键字会导致操作或测试永远不会远程执行(但可能会远程缓存)。
  • no-remote 关键字可防止远程执行操作或测试,或远程缓存操作或测试。这相当于同时使用 no-remote-cacheno-remote-exec
  • no-remote-cache-upload 关键字会停用生成操作的远程缓存的上传部分。 它不会停用远程执行。
  • local 关键字可防止操作或测试被远程缓存、远程执行或在沙盒中运行。对于 genrule 和测试,使用 local = True 属性标记规则具有相同的效果。
  • requires-network 关键字允许从沙盒内部访问外部网络。只有在启用沙盒模式的情况下,此标记才会生效。
  • block-network 关键字会阻止从沙盒内部访问外部网络。在这种情况下,仅允许与 localhost 进行通信。只有在启用沙盒的情况下,此标记才会生效。
  • requires-fakeroot 以 uid 和 gid 0(即根用户)身份运行测试或操作。仅 Linux 支持此功能。此标记的优先级高于 --sandbox_fake_username 命令行选项。

测试中的标记通常用于注释测试在调试和发布过程中的角色。通常,标记最适合用于缺少任何运行时注释功能的 C++ 和 Python 测试。通过使用标记和大小元素,可以根据代码库提交政策灵活地组装测试套件。

如果 Bazel 在测试规则的 tags 属性中找到以下关键字,则会修改测试运行行为:

  • exclusive 将强制测试以“独占”模式运行,确保没有其他测试同时运行。此类测试将在所有 build 活动和非独占测试完成后按顺序执行。由于 Bazel 无法控制远程机器上运行的内容,因此此类测试会停用远程执行。
  • 如果测试在本地执行,exclusive-if-local 会强制测试以“独占”模式运行;如果测试在远程执行,则会并行运行测试。
  • manual 关键字会从目标模式通配符(...:*:all 等)和 test_suite 规则的扩展中排除目标,这些规则在计算要为 buildtestcoverage 命令构建/运行的顶级目标集时,不会明确列出测试。它不会影响其他上下文中的目标通配符或测试套件扩展,包括 query 命令。请注意,manual 并不意味着持续构建/测试系统不应自动构建/运行目标。例如,可能需要从 bazel test ... 中排除某个目标,因为它需要特定的 Bazel 标志,但仍希望将其包含在配置正确的预提交或持续测试运行中。
  • external 关键字会强制执行测试(无论 --cache_test_results 值如何)。
如需详细了解附加到测试目标的标记的更多惯例,请参阅测试百科全书中的标记惯例
target_compatible_with

标签列表;默认值为 []

必须存在于目标平台中的 constraint_value 列表,才能将相应目标视为兼容。这是对规则类型已设置的任何限制的补充。如果目标平台不满足所有列出的限制条件,则该目标平台会被视为不兼容。当目标模式展开时(例如 //...:all),不兼容的目标会被跳过,不进行构建和测试。如果在命令行中明确指定了不兼容的目标,则 Bazel 会打印错误,并导致构建或测试失败。

以传递方式依赖于不兼容目标的目标本身也被视为不兼容。在构建和测试时,这些文件也会被跳过。

空列表(默认值)表示目标与所有平台兼容。

Workspace 规则之外的所有规则都支持此属性。 对于某些规则,此属性不会产生任何影响。例如,为 cc_toolchain 指定 target_compatible_with 没有什么用处。

如需详细了解如何跳过不兼容的目标平台,请参阅平台页面。

testonly

布尔值;不可配置;默认值为 False,但测试和测试套件目标除外

如果为 True,则只有 testonly 目标(例如测试)可以依赖于此目标。

同样,非 testonly 的规则不得依赖于任何 testonly 的规则。

测试(*_test 规则)和测试套件(test_suite 规则)默认情况下为 testonly

此属性旨在表示,目标不应包含在发布到生产环境的二进制文件中。

由于 testonly 是在 build 时(而非运行时)强制执行的,并且会通过依赖树以病毒式方式传播,因此应谨慎应用。例如,对单元测试有用的桩和伪对象可能对涉及将发布到生产环境的相同二进制文件的集成测试也有用,因此可能不应标记为 testonly。相反,即使链接到也危险的规则(可能是因为它们无条件地替换了正常行为)应明确标记为 testonly。

toolchains

标签列表;不可配置;默认值为 []

一组目标,允许此目标访问这些目标的 Make 变量。这些目标可以是提供 TemplateVariableInfo 的规则的实例,也可以是 Bazel 内置的工具链类型的特殊目标。其中包括:

  • @bazel_tools//tools/cpp:toolchain_type
  • @rules_java//toolchains:current_java_runtime

请注意,这与规则实现用于平台相关配置的工具链解析概念不同。您无法使用此属性来确定目标将使用哪个特定的 cc_toolchainjava_toolchain

visibility

标签列表; 不可配置; 默认值各不相同

visibility 属性用于控制其他位置的目标是否可以依赖相应目标。请参阅有关可见性的文档。

对于直接在 BUILD 文件中声明的目标或从 BUILD 文件调用的旧版宏,默认值为软件包的 default_visibility(如果已指定),否则为 ["//visibility:private"]。对于在一个或多个符号宏中声明的目标,默认值始终只是 ["//visibility:private"](这使得它只能在包含宏代码的软件包中使用)。

所有测试规则(*_test)通用的属性

本部分介绍了所有测试规则通用的属性。

属性 说明
args

字符串列表;受 $(location)“Make variable” 替换以及 Bourne shell 令牌化的影响;默认值为 []

当使用 bazel test 执行目标时,Bazel 传递给目标的命令行实参。

这些实参在 bazel test 命令行上指定的任何 --test_arg 值之前传递。

env

字符串字典;值受 $(location)“Make variable” 替换的影响;默认值为 {}

指定在 bazel test 执行测试时要设置的其他环境变量。

此属性仅适用于原生规则,例如 cc_testpy_testsh_test。它不适用于 Starlark 定义的测试规则。对于您自己的 Starlark 规则,您可以添加“env”属性,并使用该属性来填充 RunEnvironmentInfo 提供程序。

TestEnvironment 提供程序。

env_inherit

字符串列表;默认值为 []

指定在通过 bazel test 执行测试时要从外部环境继承的其他环境变量。

此属性仅适用于原生规则,例如 cc_testpy_testsh_test。它不适用于 Starlark 定义的测试规则。

size

字符串 "enormous""large""medium""small"不可配置;默认值为 "medium"

指定测试目标的“轻重程度”:运行测试需要多少时间/资源。

单元测试被视为“小型”测试,集成测试被视为“中型”测试,端到端测试被视为“大型”或“巨型”测试。Bazel 会使用该大小来确定默认超时时间,您可以使用 timeout 属性替换该超时时间。超时时间适用于 BUILD 目标中的所有测试,而不是每个单独的测试。在本地运行测试时,size 还用于调度目的:Bazel 会尽量遵循 --local_{ram,cpu}_resources,避免同时运行大量繁重的测试,以免使本地机器不堪重负。

测试规模对应于以下默认超时时间和假设的本地资源使用峰值:

大小 RAM(以 MB 为单位) CPU(以 CPU 核心数表示) 默认超时时间
20 1 短(1 分钟)
100 1 中等(5 分钟)
large 300 1 长(15 分钟)
特大 800 1 永久(60 分钟)

在生成测试时,环境变量 TEST_SIZE 将设置为此属性的值。

timeout

字符串 "short""moderate""long""eternal"不可配置;默认值派生自测试的 size 属性

测试预计运行多长时间后返回。

虽然测试的大小属性控制着资源估计,但测试的超时时间可以单独设置。如果未明确指定,则超时时间取决于测试的大小。可以使用 --test_timeout 标志替换测试超时时间,例如在已知速度较慢的特定条件下运行测试时。测试超时值对应于以下时间段:

超时值 时间段
短片 1 分钟
适中 5 分钟
long 15 分钟
eternal 60 分钟

对于上述时间以外的时间,可以使用 --test_timeout bazel 标志替换测试超时时间,例如在已知速度较慢的条件下手动运行。--test_timeout 值以秒为单位。例如,--test_timeout=120 会将测试超时时间设置为 2 分钟。

在生成测试时,环境变量 TEST_TIMEOUT 将设置为测试超时时间(以秒为单位)。

flaky

布尔值;不可配置;默认值为 False

将测试标记为 flaky。

如果设置了此标志,则执行测试最多三次,只有在每次都失败时才将其标记为失败。默认情况下,此属性设置为 False,并且测试仅执行一次。请注意,一般不建议使用此属性 - 当断言成立时,测试应可靠地通过。

shard_count

小于或等于 50 的非负整数;默认值为 -1

指定用于运行测试的并行分片数量。

如果设置,此值将替换用于确定运行测试的并行分片数量的所有启发式方法。请注意,对于某些测试规则,可能需要此参数才能启用分片。另请参阅 --test_sharding_strategy

如果启用了测试分片,则在生成测试时,环境变量 TEST_TOTAL_SHARDS 将设置为此值。

分片要求测试运行程序支持测试分片协议。如果未指定,则很可能会在每个分片中运行每个测试,而这并不是您想要的结果。

如需详细了解分片,请参阅测试百科全书中的测试分片

local

布尔值;不可配置;默认值为 False

强制在本地运行测试,而不进行沙盒处理。

将此属性设置为 True 等同于提供“local”作为标记 (tags=["local"])。

所有二元规则(*_binary)通用的属性

本部分介绍了所有二进制规则通用的属性。

属性 说明
args

字符串列表;受 $(location)“Make variable”替换以及 Bourne shell 令牌化的影响;不可配置;默认值为 []

当目标通过 run 命令或作为测试执行时,Bazel 将传递给目标的命令行实参。这些实参在 bazel runbazel test 命令行中指定的实参之前传递。

注意:在 Bazel 之外运行目标时(例如,通过在 bazel-bin/ 中手动执行二进制文件),不会传递参数。

env

字符串字典;值受 $(location) 和“创建变量”替换的影响;默认值为 {}

指定由 bazel run 执行目标时要设置的其他环境变量。

此属性仅适用于原生规则,例如 cc_binarypy_binarysh_binary。它不适用于 Starlark 定义的可执行规则。对于您自己的 Starlark 规则,您可以添加“env”属性,并使用该属性来填充 RunEnvironmentInfo 提供程序。

注意:在 Bazel 之外运行目标时(例如,通过手动执行 bazel-bin/ 中的二进制文件),不会设置环境变量。

output_licenses

字符串列表;默认值为 []

相应二进制文件生成的输出文件的许可。 这是 Bazel 不再使用的已弃用的许可 API 的一部分。请勿使用此功能。

可配置的属性

大多数属性都是“可配置”的,这意味着当以不同方式构建目标时,它们的值可能会发生变化。具体而言,可配置的属性可能会因传递给 Bazel 命令行标志的不同而异,也可能会因下游依赖项请求的目标不同而异。例如,这可用于自定义多个平台或编译模式的目标。

以下示例针对不同的目标架构声明了不同的来源。运行 bazel build :multiplatform_lib --cpu x86 将使用 x86_impl.cc 构建目标,而替换为 --cpu arm 将导致它改用 arm_impl.cc

cc_library(
    name = "multiplatform_lib",
    srcs = select({
        ":x86_mode": ["x86_impl.cc"],
        ":arm_mode": ["arm_impl.cc"]
    })
)
config_setting(
    name = "x86_mode",
    values = { "cpu": "x86" }
)
config_setting(
    name = "arm_mode",
    values = { "cpu": "arm" }
)

select() 函数会根据目标配置满足的 config_settingconstraint_value 条件,从可配置属性的不同替代值中进行选择。

Bazel 会在处理宏之后、处理规则之前(从技术上讲,是在 加载阶段和分析阶段之间)评估可配置的属性。在评估 select() 之前进行的任何处理都不知道 select() 会选择哪个分支。例如,宏无法根据所选分支更改其行为,而 bazel query 只能对目标的可配置依赖项做出保守的猜测。如需详细了解如何将 select() 与规则和宏搭配使用,请参阅 此常见问题解答

文档中标记为 nonconfigurable 的属性无法使用此功能。通常,属性是不可配置的,因为 Bazel 需要在内部知道其值,然后才能确定如何解析 select()

如需详细了解,请参阅 可配置的 build 属性

隐式输出目标

C++ 中的隐式输出已被弃用。请尽可能避免在其他语言中使用该功能。我们尚未确定弃用路径,但它们最终也会被弃用。

在 BUILD 文件中定义 build 规则时,您是在软件包中明确声明一个新的命名规则目标。许多 build 规则函数还隐式包含一个或多个输出文件目标,这些目标的具体内容和含义取决于规则。 例如,当您明确声明 java_binary(name='foo', ...) 规则时,您还隐式声明输出文件目标 foo_deploy.jar 是同一软件包的成员。 (此特定目标是适合部署的自包含 Java 归档。)

隐式输出目标是全局目标图的一级成员。与其他目标一样,它们也是按需构建的,要么是在顶级 build 命令中指定时构建,要么是在它们是其他 build 目标的必要前提条件时构建。它们可在 BUILD 文件中作为依赖项引用,并可在 bazel query 等分析工具的输出中观察到。

对于每种 build 规则,相应规则的文档都包含一个特殊部分,详细说明了声明该类规则所带来的任何隐式输出的名称和内容。

构建系统使用的两个命名空间之间存在一个重要但略微细微的区别:标签用于标识目标(可以是规则或文件),而文件目标可以分为源(或输入)文件目标和派生(或输出)文件目标。这些是您可以在 BUILD 文件中提及、从命令行构建或使用 bazel query 进行检查的内容;这是目标命名空间。每个文件目标都对应于磁盘上的一个实际文件(“文件系统命名空间”);每个规则目标可能对应于磁盘上的零个、一个或多个实际文件。 磁盘上可能存在没有相应目标的文件;例如,在 C++ 编译期间生成的 .o 对象文件无法从 BUILD 文件内或命令行中引用。这样一来,构建工具可能会隐藏其工作方式的某些实现细节。如需了解详情,请参阅 BUILD 概念参考