常见定义

报告问题 查看源代码 每夜 build · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

本部分定义了许多函数或构建规则中常见的各种术语和概念。

目录

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 属性的输出和 runfile 以及提供源代码或运行时依赖项的任何依赖项属性的 runfile 填充目标的 runfile

deps

标签列表;默认值为 []

此目标的依赖项。通常应仅列出名单规则目标。(虽然某些规则允许在 deps 中直接列出文件,但应尽可能避免这样做。)

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

使用 deps 时,一个目标依赖于另一个目标的确切语义因规则类型而异,具体请参阅特定于规则的文档。对于处理源代码的规则,deps 通常会在 srcs 中指定代码使用的代码依赖项。

大多数情况下,deps 依赖项用于允许一个模块使用使用相同编程语言编写且单独编译的另一个模块中定义的符号。在许多情况下,还允许跨语言依赖项:例如,java_library 目标可以依赖于 cc_library 目标中的 C++ 代码,方法是将后者列在 deps 属性中。如需了解详情,请参阅依赖项的定义。

licenses

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

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

srcs

标签列表;默认值为 []

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

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

所有 build 规则通用的属性

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

属性 说明
compatible_with

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

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

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

deprecation

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

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

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

软件包内依赖项不受此警告的约束,因此,例如,构建已废弃规则的测试时不会遇到警告。

如果已废弃的目标依赖于另一个已废弃的目标,系统不会发出警告消息。

用户停止使用该目标后,您就可以将其移除。

distribs

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

要用于此特定目标的分发方法字符串的列表。 这是已废弃的许可 API 的一部分,Bazel 不再使用该 API。请勿使用此方法。

exec_compatible_with

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

此目标的执行平台中必须存在的 constraint_values 的列表。这还不包括规则类型已设置的任何约束条件。限制条件用于限制可用执行平台的列表。如需了解详情,请参阅工具链解析的说明。

exec_properties

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

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

如果平台级和目标级属性中都存在某个键,系统会从目标中获取值。

features

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

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

features 属性与 软件包features 属性结合使用。例如,如果在软件包级别启用了功能 [“a”“b”],并且目标的 features 属性包含 [“-a”“c”],则为规则启用的功能将是“b”和“c”。 请参阅示例

restricted_to

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

此目标可构建的环境列表(而非默认支持的环境)。

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

tags

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

标记可用于任何规则。测试和 test_suite 规则中的标记有助于对测试进行分类。非测试目标上的标记用于控制 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 关键字会停用 spawn 的远程缓存上传部分。 但不会停用远程执行。
  • local 关键字会阻止操作或测试远程缓存、远程执行或在沙盒中运行。 对于 genrule 和测试,使用 local = True 属性标记规则具有相同的效果。
  • requires-network 关键字允许从沙盒内访问外部网络。只有在启用沙盒化后,此代码才会生效。
  • block-network 关键字会阻止从沙盒内访问外部网络。在这种情况下,仅允许与 localhost 通信。只有在启用沙盒化后,此标记才会生效。
  • requires-fakeroot 会以 UID 和 GID 0(即 root 用户)的身份运行测试或操作。只有 Linux 支持此功能。此标记的优先级高于 --sandbox_fake_username 命令行选项。

测试的标记通常用于注释测试在调试和发布流程中的作用。通常,代码段最适用于缺少任何运行时注解功能的 C++ 和 Python 测试。使用标记和大小元素可根据代码库签入政策灵活组合测试套件。

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

  • exclusive 会强制测试在“独占”模式下运行,确保没有其他测试同时运行。在所有 build 活动和非独占测试完成后,系统会串行执行此类测试。系统会停用此类测试的远程执行,因为 Bazel 无法控制远程机器上运行的内容。
  • 如果测试在本地执行,exclusive-if-local 会强制测试在“独占”模式下运行,但如果测试在远程执行,则会并行运行测试。
  • manual 关键字会在计算要为 buildtestcoverage 命令构建/运行的一组顶级目标时,将目标从目标模式通配符(...:*:all 等)和 test_suite 规则的展开中排除,这些规则不会明确列出测试。这不会影响其他上下文(包括 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 是在构建时(而非运行时)强制执行的,并且会通过依赖项树进行病毒式传播,因此应谨慎应用。例如,对单元测试有用的桩和虚构对象可能也对涉及要发布到生产环境的相同二进制文件的集成测试有用,因此可能不应标记为仅用于测试。相反,如果规则连链接都很危险(可能是因为它们会无条件替换正常行为),则绝对应将其标记为仅用于测试。

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 变量”替换,以及 Bourne shell 令牌化;默认值为 []

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

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

env

字符串字典;值会替换为 $(location)“设备变量”;默认值为 {}

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

此属性仅适用于原生规则,例如 cc_testpy_testsh_test。不适用于 Starlark 定义的测试规则。对于您自己的 Starlark 规则,您可以添加“env”属性,并使用该属性填充 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 分钟)
300 1 长(15 分钟)
巨大 800 1 永久(60 分钟)

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

timeout

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

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

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

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

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

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

flaky

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

将测试标记为不稳定。

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

shard_count

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

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

如果设置,此值将替换用于确定用于运行测试的并行分片数量的任何启发词语。请注意,对于某些测试规则,可能需要先使用此参数启用分片。另请参阅 --test_sharding_strategy

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

分片需要测试运行程序支持测试分片协议。如果没有,则很可能会在每个分片中运行每项测试,这并不是您想要的。

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

local

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

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

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

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

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

属性 说明
args

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

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

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

env

字符串字典;值会替换为 $(location)“设备变量”;默认值为 {}

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

此属性仅适用于原生规则,例如 cc_binarypy_binarysh_binary。不适用于 Starlark 定义的可执行规则。

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

output_licenses

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

此二进制文件生成的输出文件的许可。 这是已废弃的许可 API 的一部分,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 文件中作为依赖项进行引用,并且可以在 bazel query 等分析工具的输出中观察到。

对于每种类型的构建规则,该规则的文档中都包含一个特殊部分,详细说明声明该类型规则所涉及的任何隐式输出的名称和内容。

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