Bazel 术语表

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

操作

在构建期间运行的命令,例如调用编译器,该编译器将工件作为输入,并生成其他工件作为输出。包括命令行参数、操作键、环境变量和声明的输入/输出工件等元数据。

另请参阅规则文档

操作缓存

一种磁盘缓存,用于存储已执行操作与其创建的输出的映射。缓存键称为“操作键”。Bazel 增量模型的核心组件。缓存存储在输出基本目录中,因此会在 Bazel 服务器重启后保留。

操作图

操作及其读取和生成的工件的内存图。该图表可能包含以源文件形式存在的工件(例如在文件系统中),以及 BUILD 文件中未提及的生成的中间/最终工件。在分析阶段生成,并在执行阶段使用。

操作图查询 (aquery)

一种查询工具,可对 build 操作执行查询。这样,您就可以分析构建规则如何转化为实际工作构建。

快捷操作按键

操作的缓存键。根据操作元数据计算得出,其中可能包括要在操作中执行的命令、编译器标志、库位置或系统头文件,具体取决于操作。让 Bazel 能够确定性地缓存或使各项操作失效。

分析阶段

构建的第二阶段。处理 BUILD 文件中指定的目标图,以生成内存中的操作图,该图决定了在执行阶段期间要运行的操作的顺序。这是评估规则实现的阶段。

制品

源文件或生成的文件。也可以是文件目录,称为树工件

工件可以是多项操作的输入,但必须由最多一项操作生成。

您可以通过标签来引用与文件目标对应的工件。

方面

一种机制,用于让规则在其依赖项中创建其他操作。例如,如果目标 A 依赖于 B,则可以对 A 应用一个切面,该切面会沿依赖项边缘向上遍历到 B,并在 B 中运行其他操作以生成和收集其他输出文件。这些额外操作会缓存起来,并在需要相同视图的目标之间重复使用。使用 aspect() Starlark Build API 函数创建。例如,可用于为 IDE 生成元数据,以及创建 lint 操作。

另请参阅“Aspects”文档

切面上切面

一种组合机制,可将方面应用于其他方面的结果。例如,您可以将用于生成供 IDE 使用的相关信息的 aspect 应用于用于从 proto 生成 .java 文件的 aspect 之上。

若要将 A 方面应用于 B 方面,B 在其 provides 属性中宣传的提供程序必须与 A 在其 required_aspect_providers 属性中声明的所需提供程序一致。

属性

规则的参数,用于表示每个目标的 build 信息。示例包括 srcsdepscopts,它们分别声明目标的源文件、依赖项和自定义编译器选项。可用于给定目标的具体属性取决于其规则类型。

.bazelrc

Bazel 的配置文件用于更改启动标志命令标志的默认值,以及定义常见的选项组,以便在 Bazel 命令行中使用 --config 标志一起设置。Bazel 可以组合多个 bazelrc 文件(系统级、按工作区、按用户或来自自定义位置)中的设置,并且 bazelrc 文件还可以从其他 bazelrc 文件导入设置。

Blaze

Google 内部版本的 Bazel。Google 的单仓库的主要构建系统。

BUILD 文件

BUILD 文件是主要配置文件,用于告知 Bazel 要构建哪些软件输出、它们的依赖项以及如何构建它们。Bazel 会将 BUILD 文件作为输入,并使用该文件创建依赖项图,以及派生构建中间和最终软件输出时必须完成的操作。BUILD 文件会将目录以及不包含 BUILD 文件的任何子目录标记为软件包,并且可以包含由规则创建的目标。该文件也可以命名为 BUILD.bazel

BUILD.bazel 文件

请参阅 BUILD 文件。优先于同一目录中的 BUILD 文件。

.bzl 文件

用于定义规则、和常量的文件,这些内容均以 Starlark 编写。然后,您可以使用 load() 函数将这些数据导入 BUILD 文件

构建图

Bazel 构建并遍历的依赖关系图,以执行构建。包括目标已配置的目标操作工件等节点。当一组请求的目标所依赖的所有工件都被验证为是最新的时,构建即被视为已完成。

build 设置

Starlark 定义的配置部分。转换可以设置 build 设置,以更改子图的配置。如果以命令行标志(也称为 build 标志)的形式向用户公开。

清理 build

不使用之前 build 的结果的 build。这通常比增量 build 更慢,但通常被认为更正确。Bazel 可保证整洁 build 和增量 build 始终正确无误。

客户端-服务器模型

bazel 命令行客户端会自动在本地计算机上启动后台服务器,以执行 Bazel 命令。服务器会跨命令保留,但会在一段非活动时间后自动停止(或通过 bazel 关闭明确停止)。将 Bazel 拆分为服务器和客户端有助于摊销 JVM 启动时间,并支持更快的增量构建,因为操作图会在各个命令中保留在内存中。

命令

在命令行中用于调用不同的 Bazel 函数,例如 bazel buildbazel testbazel runbazel query

命令标志

一组特定于命令的标志。命令标志在命令 (bazel build <command flags>) 后面指定。标志可以应用于一个或多个命令。例如,--configure 是专门用于 bazel sync 命令的标志,但 --keep_going 适用于 syncbuildtest 等。标志通常用于配置目的,因此标志值的更改可能会导致 Bazel 使内存图无效并重启分析阶段

配置

规则定义之外的信息,会影响规则生成操作的方式。每个 build 至少有一个配置,用于指定目标平台、操作环境变量和命令行build 标志转换可能会创建其他配置,例如主机工具或交叉编译。

另请参阅配置

配置修剪

仅包含目标实际需要的配置部分的过程。例如,如果您使用 C++ 依赖项 //:c 构建 Java 二进制文件 //:j,则在 //:c 的配置中添加 --javacopt 的值会造成浪费,因为更改 --javacopt 会不必要地破坏 C++ 构建缓存功能。

配置的查询 (cquery)

一种查询工具,用于查询配置的目标(在分析阶段完成后)。这意味着 select()build 标志(例如 --platforms)会准确反映在结果中。

另请参阅cquery 文档

配置的目标

使用配置评估目标的结果。分析阶段会通过将 build 的选项与需要构建的目标组合来生成此信息。例如,如果 //:foo 在同一 build 中针对两个不同的架构进行构建,则它具有两个配置的目标:<//:foo, x86><//:foo, arm>

正确性

如果 build 的输出准确反映了其传递输入的状态,则 build 是正确的。为了实现正确的构建,Bazel 会努力实现封闭性、可重现性,并使构建分析操作执行具有确定性。

依赖项

两个目标之间的有向边。如果 //:foo 的属性值包含对 //:bar 的引用,则目标 //:foo 对目标 //:bar 具有目标依赖项。如果 //:foo 中的操作依赖于 //:bar 中的操作创建的输入工件,则 //:foo//:bar 具有操作依赖项

在某些上下文中,它还可以指代外部依赖项;请参阅模块

Depset

用于收集传递依赖项数据的数据结构。经过优化,可高效合并 depset,因为通常会出现非常大的 depset(数十万个文件)。出于空间效率考虑,实现了递归引用其他 depset 的功能。规则实现不应通过将依赖项集转换为列表来“扁平化”依赖项集,除非规则位于 build 图的顶级。展平大型 depset 会导致巨大的内存消耗。在 Bazel 的内部实现中,也称为嵌套集

另请参阅代码库文档

磁盘缓存

用于远程缓存功能的本地磁盘 blob 存储区。可与实际的远程 blob 存储区搭配使用。

Distdir

一个只读目录,其中包含 Bazel 原本会使用代码库规则从互联网提取的文件。支持完全离线运行 build。

动态执行

一种执行策略,可根据各种启发词语在本地执行和远程执行之间进行选择,并使用成功速度更快的方法的执行结果。某些操作在本地执行速度更快(例如链接),而另一些操作在远程执行速度更快(例如高度可并行的编译)。动态执行策略可以尽可能缩短增量构建时间并确保构建过程干净无误。

执行阶段

构建的第三个阶段。在分析阶段创建的操作图中执行操作。这些操作会调用可执行文件(编译器、脚本)来读取和写入工件生成策略用于控制这些操作的执行方式:本地、远程、动态、沙盒、Docker 等。

执行根

工作区输出基础目录中的目录,用于在非沙盒化 build 中执行本地操作。目录内容主要为工作区中输入工件的符号链接。执行根目录还包含指向其他输入的外部代码库的符号链接,以及用于存储输出的 bazel-out 目录。在加载阶段准备,方法是创建表示构建依赖的软件包的传递闭包的目录的符号链接森林。可在命令行中使用 bazel info execution_root 访问。

文件

请参阅工件

Hermeticity

如果构建和测试操作不受外部影响,则构建是密封的,这有助于确保结果是确定性的且正确无误。例如,密封型 build 通常不允许对操作进行网络访问,限制对已声明输入的访问,使用固定的时间戳和时区,限制对环境变量的访问,并为随机数生成器使用固定的种子

增量 build

增量 build 会重复使用之前 build 的结果,以缩短构建时间并减少资源用量。依赖项检查和缓存旨在为此类 build 生成正确的结果。增量 build 与完整 build 相反。

标签

目标的标识符。通常采用 @repo//path/to/package:target 的形式,其中 repo 是包含目标的代码库的(表面)名称,path/to/package 是包含声明目标的 BUILD 文件(此目录也称为软件包)所在目录的路径,target 是目标本身的名称。根据具体情况,此语法中的某些部分可能会被省略。

另见标签

加载阶段

构建的第一个阶段,其中 Bazel 会执行 BUILD 文件以创建软件包。此阶段会对glob() 等特定函数进行求值。与 build 的第二阶段(分析阶段)交错,以构建目标图

旧版宏

一种变体,声明为普通的 Starlark 函数,并会作为执行 BUILD 文件的副作用运行。

旧版宏可以执行函数可以执行的任何操作。这意味着它们很方便,但也可能更难读、写和使用。旧版宏可能会意外地更改其参数,或者在收到 select() 或类型错误的参数时失败。

符号宏相对。

另请参阅旧版宏文档

一种机制,用于在单个 Starlark 可调用项下组合多个规则目标声明。支持在 BUILD 文件中重复使用常见规则声明模式。在加载阶段扩展为底层规则目标声明。

有两种类型:符号宏(从 Bazel 8 开始)和旧版宏

助记符

规则作者选择的简短且直观易懂的字符串,用于快速了解规则中的操作的执行方式。助记符可用作生成策略选择的标识符。操作助记符的一些示例如下:Java 规则中的 Javac、C++ 规则中的 CppCompile 和 Android 规则中的 AndroidManifestMerger

模块

一个 Bazel 项目可以有多个版本,每个版本都可以依赖于其他模块。这类似于其他依赖项管理系统中常见的概念,例如 Maven 工件、npm 软件包、Go 模块或 Cargo crate。模块是 Bazel 外部依赖项管理系统的支柱。

每个模块都由一个 repo 提供支持,其根目录中包含 MODULE.bazel 文件。此文件包含有关模块本身的元数据(例如名称和版本)、其直接依赖项,以及各种其他数据,包括工具链注册和模块扩展输入。

模块元数据托管在 Bazel 注册库中。

另请参阅Bazel 模块

模块扩展

可通过读取整个模块依赖项图中的输入并调用代码库规则来生成代码库的一段逻辑。模块扩展程序具有与代码库规则类似的功能,可访问互联网、执行文件 I/O 等操作。

另请参阅模块扩展

原生规则

内置于 Bazel 中并以 Java 实现的规则。此类规则会以原生模块中的函数形式显示在 .bzl 文件中(例如 native.cc_librarynative.java_library)。用户定义的规则(非原生)是使用 Starlark 创建的。

输出基准

用于存储 Bazel 输出文件的工作区专用目录。用于将输出与工作区的源代码树(主代码库)分开。位于输出用户根目录中。

输出组

在 Bazel 完成构建目标后预计要构建的一组文件。规则会将其常规输出放入“默认输出组”(例如 java_library.jar 文件、.a.socc_library 目标)。默认输出组是指在命令行上请求目标时构建其工件的输出组。规则可以定义更多命名输出组,这些组可以在 BUILD 文件filegroup 规则)或命令行(--output_groups 标志)中明确指定。

输出用户 root

用于存储 Bazel 输出的用户专用目录。目录名称派生自用户的系统用户名。如果多个用户同时在系统上构建同一项目,则可防止输出文件发生冲突。包含与各个工作区的构建输出(也称为输出基础)对应的子目录。

软件包

BUILD 文件定义的一组目标。软件包的名称是 BUILD 文件相对于代码库根目录的路径。软件包可以包含子软件包,或包含 BUILD 文件的子目录,从而形成软件包层次结构。

文件包组

表示一组软件包的目标。通常用于 visibility 属性值。

平台

构建中涉及的“机器类型”。这包括 Bazel 运行的机器(“主机”平台)、构建工具执行的机器(“执行”平台),以及构建目标的机器(“目标平台”)。

提供商

用于描述要在依赖关系沿线规则目标之间传递的信息单元的架构。通常,这类文件包含编译器选项、传递的源文件或输出文件以及构建元数据等信息。通常与 depsets 搭配使用,以高效存储累积的传递数据。内置提供程序的一个示例是 DefaultInfo

另请参阅提供程序文档

查询(概念)

分析构建图以了解目标属性和依赖项结构的过程。Bazel 支持三种查询变体:querycqueryaquery

查询(命令)

一种查询工具,用于在 build 的加载后阶段目标图上运行。这种方法速度相对较快,但无法分析 select()构建标记工件或构建操作的影响。

另请参阅查询操作方法查询参考文档

代码库

一个目录树,其根目录包含边界标记文件,其中包含可在 Bazel build 中使用的源文件。通常简称为代码库

代码库边界标记文件可以是 MODULE.bazel(表示此代码库代表 Bazel 模块)、REPO.bazel,或者在旧版上下文中,可以是 WORKSPACEWORKSPACE.bazel。任何代码库边界标记文件都将表示代码库的边界;一个目录中可以同时存在多个此类文件。

主代码库是当前正在运行 Bazel 命令的代码库。

外部代码库是通过在 MODULE.bazel 文件中指定模块或在模块扩展中调用代码库规则来定义的。它们可以按需提取到磁盘上的预先指定的“神奇”位置。

每个代码库都有一个唯一的常量规范名称,从其他代码库查看时,可能还有不同的外观名称。

另请参阅外部依赖项概览

代码库缓存

由 Bazel 为构建下载的文件的共享内容寻址缓存,可跨工作区共享。在初始下载后启用离线 build。通常用于缓存通过 http_archive代码库规则repository_ctx.download 等代码库规则 API 下载的文件。只有在为下载文件指定 SHA-256 校验和后,系统才会将文件缓存起来。

代码库规则

代码库定义的架构,用于告知 Bazel 如何具体化(或“提取”)代码库。通常简称为代码库规则。 Bazel 会在内部调用代码库规则来定义由模块支持的代码库,也可以由模块扩展调用。代码库规则可以访问互联网或执行文件 I/O;最常见的代码库规则是 http_archive,用于从互联网下载包含源文件的归档文件。

另请参阅代码库规则文档

可再现性

构建或测试的属性,即无论时间、方法或环境如何,构建或测试的一组输入始终会生成一组相同的输出。请注意,这并不一定意味着输出正确无误或为所需输出。

规则

用于在 BUILD 文件(例如 cc_library)中定义规则目标的架构。从 BUILD 文件作者的角度来看,规则由一组属性和黑盒逻辑组成。该逻辑会告知规则目标如何生成输出工件并将信息传递给其他规则目标。从 .bzl 作者的角度来看,规则是扩展 Bazel 以支持新编程语言和环境的主要方式。

系统会在加载阶段实例化规则,以生成规则目标。在分析阶段,规则目标会以提供程序的形式将信息传达给其下游依赖项,并注册描述如何生成其输出工件的操作。这些操作在执行阶段运行。

另请参阅规则文档

规则目标

目标,即规则的实例。与文件目标和软件包组相对。请勿与规则混淆。

runfile

可执行目标的运行时依赖项。最常见的是,可执行文件是测试规则的可执行输出,而 runfile 是测试的运行时数据依赖项。在调用可执行文件之前(在 Bazel 测试期间),Bazel 会根据其源代码目录结构准备 runfile 树以及测试可执行文件。

另请参阅Runfile 文档

沙盒

一种在受限的临时执行根中隔离正在运行的操作的技术,有助于确保该操作不会读取未声明的输入或写入未声明的输出。沙盒化大大提高了密封性,但通常会降低性能,并且需要操作系统的支持。性能开销取决于平台。在 Linux 上,这不重要,但在 macOS 上,这可能会导致沙盒无法使用。

Skyframe

Skyframe 是 Bazel 的核心并行、功能和增量评估框架。

冲压

用于将其他信息嵌入到 Bazel 构建的工件中的功能。例如,这可以用于发布 build 的源代码控制、构建时间和其他工作区或环境相关信息。通过支持戳记属性的 --workspace_status_command 标志和规则启用。

Starlark

用于编写规则的扩展语言。一种受限的 Python 子集(在语法和语法方面),旨在用于配置和提升性能。使用 .bzl 文件扩展名。BUILD 文件使用 Starlark 的更受限版本(例如不允许使用 def 函数定义),以前称为 Skylark。

另请参阅Starlark 语言文档

启动标志

bazel命令(例如 bazel --host_jvm_debug build)之间指定的一组标志。这些标志会修改 Bazel 服务器的配置,因此对启动标志进行的任何修改都会导致服务器重启。启动标志并非特定于任何命令。

符号宏

一种变种,使用类似规则属性架构进行声明,允许隐藏从自己的软件包中声明的内部目标,并对宏声明的目标强制执行可预测的命名模式。旨在避免大型旧版宏代码库中出现的一些问题。

另请参阅符号宏文档

目标

BUILD 文件中定义且由标签标识的对象。目标代表从最终用户的角度来看,工作区的可构建单元。

通过实例化规则声明的目标称为规则目标。这些目标可能可运行(例如 cc_binary)或可测试(例如 cc_test),具体取决于规则。规则目标通常通过其属性(例如 deps)依赖于其他目标;这些依赖项构成了目标图的基础。

除了规则目标之外,还有文件目标和软件包组目标。文件目标对应于 BUILD 文件中引用的工件。作为一种特殊情况,任何软件包的 BUILD 文件始终被视为该软件包中的源文件目标。

系统会在加载阶段发现目标。在分析阶段,目标会与构建配置相关联,以形成已配置的目标

目标图表

目标及其依赖项的内存图。在加载阶段生成,并用作分析阶段的输入。

目标模式

一种在命令行中指定一组目标的方法。常用的模式包括 :all(所有规则目标)、:*(所有规则 + 文件目标)、...(当前软件包及其所有子软件包,以递归方式)。可以组合使用,例如,//...:* 表示从 workspace 的根目录递归地查找所有软件包中的所有规则和文件目标。

测试

规则目标是从测试规则实例化的,因此包含测试可执行文件。可执行文件完成后返回 0 表示测试成功。测试百科全书中指定了 Bazel 与测试之间的确切协定(例如测试环境变量、测试结果收集方法)。

工具链

一组用于为某种语言构建输出的工具。通常,工具链包括编译器、链接器、解释器和/或 lint 工具。工具链也可能因平台而异,也就是说,Unix 编译器工具链的组件可能因 Windows 变体而异,即使该工具链适用于同一语言也是如此。为平台选择合适的工具链称为工具链解析。

顶级目标

如果在 Bazel 命令行中请求构建目标,则该目标是顶级目标。例如,如果 //:foo 依赖于 //:bar,并且调用了 bazel build //:foo,那么对于此 build,//:foo 是顶级目标,而 //:bar 不是顶级目标,尽管这两个目标都需要构建。顶级目标和非顶级目标之间的一个重要区别是,在 Bazel 命令行(或通过 .bazelrc)上设置的命令标志将为顶级目标设置配置,但对于非顶级目标,可能会被转换修改。

转换

配置状态从一个值到另一个值的映射。允许构建图中的目标具有不同的配置,即使它们是从同一规则实例化而来也是如此。转换的常见用法是与分屏转换搭配使用,其中目标图的某些部分会分叉,每个分支都有不同的配置。例如,您可以使用单个 build 中的分屏转换构建一个包含针对 ARM 和 x86 编译的原生二进制文件的 Android APK。

另请参阅用户定义的转场效果

树工件

表示文件集的工件。由于这些文件本身不是工件,因此对这些文件执行操作的操作必须将树工件注册为其输入或输出。

公开范围

用于防止 build 系统中出现不必要依赖项的两种机制之一:目标可见性,用于控制其他目标是否可以依赖于某个目标加载可见性,用于控制 BUILD.bzl 文件是否可以加载给定的 .bzl 文件。如果没有上下文,通常“可见性”是指目标可见性。

另请参阅“公开范围”文档

工作区

所有从同一主仓库运行的 Bazel 命令共享的环境。

请注意,在历史上,“代码库”和“工作区”这两个概念一直被混淆;“工作区”一词通常用于指代主代码库,有时甚至用作“代码库”的同义词。为清楚起见,应避免这种用法。