操作
在构建期间运行的命令,例如,调用将工件作为输入并生成其他工件作为输出的编译器。包括命令行参数、操作键、环境变量和声明的输入/输出工件等元数据。
另请参阅:规则文档
操作缓存
磁盘缓存,用于存储已执行操作到操作所创建的输出的映射。缓存键称为操作键。Bazel 增量模型的核心组件。缓存存储在输出基本目录中,因此在 Bazel 服务器重启后仍然有效。
操作图表
包含操作以及这些操作读取和生成的工件的内存中图表。该图可能包含以源文件形式存在的工件(例如,在文件系统中)以及生成的中间/最终工件(在 BUILD
文件中未提及)。在分析阶段生成并在执行阶段使用。
操作图查询(查询)
一种查询工具,可用于对构建操作进行查询。 这样,您就可以分析构建规则如何转化为实际工作 build。
操作键
操作的缓存键。根据操作元数据计算得出,其中可能包括要在操作中执行的命令、编译器标志、库位置或系统头文件,具体取决于操作。允许 Bazel 确定性地缓存或使各项操作失效。
分析阶段
构建的第二阶段。处理 BUILD
文件中指定的目标图,以生成一个内存中操作图,该操作图用于确定在执行阶段运行的操作顺序。这是评估规则实现的阶段。
制品
源文件或生成的文件。该文件也可以是文件目录,称为“树工件”。
工件可以是多项操作的输入,但只能由一个操作生成。
宽高比
一种规则,用于在依赖项中创建其他操作。例如,如果目标 A 依赖于 B,可以在 A 上应用一个切面,该切面遍历依赖关系边缘到 B,并在 B 中运行其他操作,以生成和收集其他输出文件。系统会缓存这些额外的操作,并在需要相同宽高比的目标之间重复使用这些操作。使用 aspect()
Starlark Build API 函数创建。例如,可用于为 IDE 生成元数据,以及创建执行 lint 检查的操作。
另请参阅:Aspects 文档
宽高比
一种组合机制,可将切面应用于其他切面的结果。例如,生成供 IDE 使用的信息的切面可以应用于从 proto 生成 .java
文件的方面。
若要在切面 B
之上应用切面 A
,B
在其 provides
属性中通告的提供程序必须与 A
在其 required_aspect_providers
属性中声明的提供程序相匹配。
属性
规则的参数,用于表示每个目标的 build 信息。示例包括 srcs
、deps
和 copts
,它们分别声明目标的源文件、依赖项和自定义编译器选项。给定目标可用的特定属性取决于其规则类型。
.bazelrc
Bazel 的配置文件,用于更改启动标志和命令标志的默认值,以及定义随后可以使用 --config
标志在 Bazel 命令行中一起设置的常用选项组。Bazel 可以合并多个 bazelrc 文件(系统级、按工作区、按用户或来自自定义位置)的设置,bazelrc
文件也可以从其他 bazelrc
文件导入设置。
Blaze
Google 内部版本的 Bazel。Google 用于单代码库的主要构建系统。
编译文件
BUILD
文件是主配置文件,用于告知 Bazel 要构建哪些软件输出、它们的依赖项是什么,以及如何构建它们。Bazel 会将 BUILD
文件作为输入,并使用该文件创建依赖关系图,并推导构建中间和最终软件输出所必须完成的操作。BUILD
文件会将不包含 BUILD
文件的目录和任何子目录标记为软件包,并且可以包含由 rules 创建的目标。该文件也可以命名为 BUILD.bazel
。
BUILD.bazel 文件
请参阅 BUILD
文件。优先级高于同一目录中的 BUILD
文件。
.bzl 文件
一个文件,用于定义使用 Starlark 编写的规则、宏和常量。然后,可以使用 load()
函数将它们导入 BUILD
文件。
build 图
为了执行构建,Bazel 构造和遍历的依赖关系图。包括目标、已配置的目标、操作和工件等节点。当一组请求的目标所依赖的所有工件都通过验证为最新时,构建即被视为已完成。
构建设置
Starlark 定义的配置。转换可以设置构建设置来更改子图的配置。如果以命令行标志(也称为构建标志)的形式向用户显示。
干净 build
不使用早期构建结果的构建。这通常比增量构建慢,但通常被认为更正确。Bazel 可保证干净构建和增量构建始终正确。
客户端-服务器模型
bazel
命令行客户端会自动在本地机器上启动后台服务器,以执行 Bazel 命令。服务器在不同命令之间保持不变,但会在处于不活动状态一段时间(或通过 Bazel 关闭)后自动停止。将 Bazel 拆分为服务器和客户端有助于分摊 JVM 启动时间,并支持更快的增量构建,因为各个命令的操作图始终位于内存中。
命令
在命令行中用于调用不同的 Bazel 函数,如 bazel
build
、bazel test
、bazel run
和 bazel query
。
命令标志
特定于某个命令的一组标志。命令标志在命令 (bazel build <command flags>
) 之后指定。标志可应用于一个或多个命令。例如,--configure
是专门用于 bazel sync
命令的标志,但 --keep_going
适用于 sync
、build
、test
等。标志通常用于配置,因此标志值的变化可能会导致 Bazel 使内存中图失效,并重启分析阶段。
配置
规则定义之外、影响规则生成操作方式的信息。每个构建都至少有一个配置指定目标平台、操作环境变量和命令行构建标志。转换可能会创建其他配置,例如用于主机工具或交叉编译的配置。
另请参阅:配置
配置精简
仅包含目标实际需要的配置部分的过程。例如,如果您使用 C++ 依赖项 //:c
构建 Java 二进制文件 //:j
,在 //:c
的配置中添加 --javacopt
的值就会造成浪费,因为更改 --javacopt
会不必要地破坏 C++ 构建的可缓存性。
已配置的查询 (cquery)
查询工具,用于对配置的目标进行查询(在分析阶段完成后)。这意味着 select()
和构建标志(例如 --platforms
)会准确反映在结果中。
另请参阅:cquery 文档
配置的目标
使用配置评估目标的结果。分析阶段通过将 build 的选项与需要构建的目标相结合来生成此数据。例如,如果 //:foo
在同一 build 中针对两个不同的架构进行构建,它就会有两个已配置的目标:<//:foo, x86>
和 <//:foo, arm>
。
正确性
如果 build 的输出能够如实反映其传递输入的状态,那么 build 就是正确的。为了实现正确的构建,Bazel 会努力实现封闭、可重现的机制,并使构建分析和操作执行具有确定性。
依赖项
两个目标之间的定向边缘。如果 //:foo
的属性值包含对 //:bar
的引用,则目标 //:foo
具有目标 //:bar
的目标依赖项。如果 //:foo
中的操作依赖于 //:bar
中的操作创建的输入工件,则 //:foo
对 //:bar
有操作依赖项。
在某些上下文中,它还可以指外部依赖项;请参阅模块。
停用
用于收集传递依赖项数据的数据结构。该依赖项已经过优化,可以节省时间和空间,因为通常会有非常大的依赖项(数十万个文件)。实现为出于空间效率原因而以递归方式引用其他位置。规则实现不应通过将偏移量转换为列表来“扁平化”偏移量,除非该规则位于 build 图的顶层。展平较大的依赖项会消耗大量的内存。在 Bazel 的内部实现中,也称为嵌套集。
另请参阅:Depset 文档
磁盘缓存
用于远程缓存功能的本地磁盘 blob 存储区。可与实际的远程 blob 存储结合使用。
Distdir
一个只读目录,其中包含 Bazel 会使用代码库规则从互联网提取的文件。让构建能够完全离线运行。
动态执行
一种执行策略,根据各种启发法选择本地执行和远程执行,并使用更快成功方法的执行结果。某些操作在本地执行更快(例如链接),另一些操作则远程更快(例如,高度可并行的编译)。动态执行策略可以尽可能缩短增量构建时间。
执行阶段
构建的第三阶段。执行在分析阶段创建的操作图中的操作。这些操作会调用可执行文件(编译器、脚本)来读取和写入工件。生成策略控制这些操作的执行方式:本地、远程、动态、沙盒化、Docker 等。
执行根
工作区的输出基本目录中的目录,这是在非沙盒化 build 中执行本地操作的目录。目录内容主要是工作区中的输入工件的符号链接。执行根目录还包含指向作为其他输入的外部代码库的符号链接,以及用于存储输出的 bazel-out
目录。在加载阶段通过创建目录符号链接林做好准备,该目录表示 build 所依赖的软件包的传递闭包。可以在命令行中使用 bazel info
execution_root
访问。
文件
请参阅工件。
封闭性
如果 build 和测试操作没有外部影响,则 build 就是封闭的,这有助于确保结果具有确定性和正确。例如,封闭 build 通常不允许网络访问操作、限制对声明的输入的访问、使用固定的时间戳和时区、限制对环境变量的访问,以及对随机数生成器使用固定种子。
增量 build
增量构建会重复使用早期构建的结果,以减少构建时间和资源用量。依赖项检查和缓存旨在为此类构建生成正确的结果。增量 build 与干净 build 相反。
标签
目标的标识符。通常采用 @repo//path/to/package:target
格式,其中 repo
是包含目标的代码库的(明显)名称,path/to/package
是包含声明目标的 BUILD
文件的目录的路径(此目录也称为软件包),target
是目标本身的名称。根据具体情况,此语法的某些部分可能会被省略。
另请参阅:标签
加载阶段
在构建的第一阶段,Bazel 会执行 BUILD
文件以创建软件包。在此阶段会评估宏和某些功能(例如 glob()
)。与构建的第二阶段(分析阶段)交织在一起,以构建目标图。
宏
一种机制,可在单个 Starlark 函数下组合多个规则目标声明。支持在 BUILD
文件中重复使用通用规则声明模式。在加载阶段扩展到了底层规则目标声明。
另请参阅:宏文档
助记符
规则作者选择的简短易懂的字符串,用于快速了解规则中的操作将执行什么操作。助记符可以用作生成策略选择的标识符。一些操作助记符示例包括 Java 规则中的 Javac
、C++ 规则中的 CppCompile
和 Android 规则中的 AndroidManifestMerger
。
单元
可以有多个版本的 Bazel 项目,每个版本都可以依赖于其他模块。这类似于其他依赖项管理系统(如 Maven 工件、npm 软件包、Go 模块或 Cargo crate)中较为熟悉的概念。模块是 Bazel 外部依赖项管理系统的支柱。
每个模块都由一个代码库提供支持,其根目录下有一个 MODULE.bazel
文件。此文件包含有关模块本身的元数据(例如其名称和版本)、其直接依赖项,以及包括工具链注册和模块扩展输入在内的各种其他数据。
模块元数据托管在 Bazel 注册表中。
另请参阅:Bazel 模块
模块扩展
通过从模块依赖关系图中读取输入并调用 repo 规则,可以运行来生成 Repo 的一段逻辑。模块扩展具有与代码库规则类似的功能,允许它们访问互联网、执行文件 I/O 等。
另请参阅:模块扩展
原生规则
内置于 Bazel 中并在 Java 中实现的规则。此类规则在 .bzl
文件中显示为原生模块中的函数(例如 native.cc_library
或 native.java_library
)。用户定义的规则(非原生)使用 Starlark 创建。
输出基
用于存储 Bazel 输出文件的工作区专用目录。用于将输出与工作区的源代码树(主代码库)分隔开来。位于输出用户根目录中。
输出组
预计在 Bazel 完成目标构建后构建的一组文件。规则将其常规输出放在“默认输出组”中(例如 java_library
的 .jar
文件,cc_library
目标的 .a
和 .so
)。默认输出组是指在命令行中请求目标时构建其工件的输出组。规则可以定义更多命名的输出组,这些组可以在 BUILD
文件(filegroup
规则)或命令行(--output_groups
标志)中明确指定。
输出用户根目录
用于存储 Bazel 输出的用户专属目录。目录名称派生自用户的系统用户名。如果多个用户同时在系统上构建相同的项目,防止输出文件冲突。包含与各个工作区的构建输出(也称为“输出库”)相对应的子目录。
软件包
由 BUILD
文件定义的一组目标。软件包的名称是 BUILD
文件相对于 repo 根目录的路径。软件包可以包含子软件包(即包含 BUILD
文件的子目录),从而形成软件包层次结构。
软件包组
表示一组软件包的目标。通常用于 visibility
属性值。
平台
构建中涉及的“机器类型”。这包括运行 Bazel 的机器(“主机”平台)、机器构建工具在(“exec”平台上执行)以及机器目标构建的目标(“目标平台”)。
提供商
描述要在规则目标之间沿依赖关系关系传递的信息单元的架构。通常,这类文件包含编译器选项、传递源文件或输出文件以及 build 元数据等信息。通常与 depset 结合使用,以高效存储累积的传递数据。内置提供程序的一个示例是 DefaultInfo
。
另请参阅:提供商文档
查询(概念)
分析构建图以了解目标属性和依赖项结构的过程。Bazel 支持三种查询变体:query、cquery 和 aquery。
query(命令)
针对 build 的加载后 目标图运行的查询工具。此操作相对较快,但无法分析 select()
、构建标志、工件或构建操作的效果。
仓库
一个目录树,其根目录下有一个边界标记文件,其中包含可在 Bazel 构建中使用的源文件。通常简称为“repo”。
代码库边界标记文件可以是 MODULE.bazel
(表明此代码库代表 Bazel 模块)、REPO.bazel
;在旧版上下文中,可以是 WORKSPACE
或 WORKSPACE.bazel
。任何代码库边界标记文件都将表示代码库的边界;多个此类文件可以共存于一个目录中。
主代码库是运行当前 Bazel 命令的代码库。
通过在 MODULE.bazel
文件中指定模块或在模块扩展中调用 Repo 规则来定义外部代码库。它们可以按需提取到磁盘上预定的“神奇”位置。
每个代码库都有一个唯一的常量规范名称,在其他代码库查看时,其表观名称可能有所不同。
另请参阅:外部依赖项概览
代码库缓存
Bazel 为 build 下载的文件的共享内容可寻址缓存,可在工作区之间共享。完成初始下载后启用离线 build。通常用于缓存通过 http_archive
等代码库规则和 repository_ctx.download
等代码库规则 API 下载的文件。仅当为下载指定了 SHA-256 校验和时,系统才会缓存文件。
代码库规则
存储库定义的架构,用于告知 Bazel 如何具体化(或“提取”)存储库。通常简称为 Repo 规则。
代码库规则由 Bazel 内部调用,以定义由模块支持的代码库,也可以由模块扩展程序调用。Repo 规则可以访问互联网或执行文件 I/O;最常见的 Repo 规则是 http_archive
,用于从互联网下载包含源文件的归档。
另请参阅:代码库规则文档
可再现性
构建或测试的属性,表示构建或测试的一组输入将始终每次始终生成同一组输出,无论时间、方法或环境如何。请注意,这并不一定表示输出是正确或符合预期。
规则
用于在 BUILD
文件(例如 cc_library
)中定义规则目标的架构。从 BUILD
文件作者的角度来看,规则由一组属性和黑盒逻辑组成。该逻辑会告知规则目标如何生成输出工件以及如何将信息传递给其他规则目标。从 .bzl
作者的角度来看,规则是扩展 Bazel 以支持新的编程语言和环境的主要方式。
规则会进行实例化,以在加载阶段生成规则目标。在分析阶段,规则目标以提供程序的形式向其下游依赖项传达信息,并注册描述如何生成其输出工件的操作。这些操作在执行阶段运行。
另请参阅:规则文档
规则目标
作为规则实例的目标。与文件目标和软件包组相对。不要与规则混淆。
Runfiles
可执行目标的运行时依赖项。最常见的情况是,可执行文件是测试规则的可执行输出,运行文件是测试的运行时数据依赖项。在调用可执行文件(在 bazel 测试期间)之前,Bazel 会根据其源目录结构准备运行文件树以及测试可执行文件。
另请参阅:Runfiles 文档
沙盒
一种用于在受限的临时执行根内隔离正在运行的操作的技术,有助于确保该操作不会读取未声明的输入或写入未声明的输出。沙盒可以极大地提高封闭性,但通常会产生性能成本,并且需要操作系统的支持。性能成本取决于平台。在 Linux 上不重要,但在 macOS 上可能会导致沙盒无法使用。
天框架
Skyframe 是 Bazel 的核心并行、功能和增量评估框架。
冲压
一项可将其他信息嵌入到 Bazel 构建的工件的功能。例如,可用于发布 build 的源代码控制、构建时间和其他工作区或环境相关信息。通过 --workspace_status_command
标志和支持图章属性的规则启用。
星拉克星
用于编写规则和宏的扩展程序语言。Python 的受限子集(在语法和语法上),旨在进行配置和提升性能。使用 .bzl
文件扩展名。BUILD
文件使用限制更严格的 Starlark 版本(例如,无 def
函数定义),之前称为 Skylark。
另请参阅:Starlark 语言文档
启动标志
在 bazel
和命令之间指定的一组标志,例如 bazel --host_jvm_debug
build。这些标志会修改 Bazel 服务器的配置,因此,对启动标志的任何修改都会导致服务器重启。启动标志并不特定于任何命令。
目标
在 BUILD
文件中定义的对象,由标签标识。目标从最终用户的角度表示工作区的可构建单元。
通过实例化规则声明的目标称为“规则目标”。这些依赖项可能是可运行(如 cc_binary
)或可测试(如 cc_test
)。规则目标通常通过其他属性(如 deps
)依赖于其他目标;这些依赖关系构成了目标图表的基础。
除了规则目标之外,还有文件目标和软件包组目标。文件目标对应于 BUILD
文件中引用的工件。特殊情况下,任何软件包的 BUILD
文件始终会被视为该软件包中的源文件目标。
目标是在加载阶段发现的。在分析阶段,目标会与 build 配置相关联,以形成配置的目标。
目标图表
目标及其依赖项的内存中图。在加载阶段生成,用作分析阶段的输入。
目标模式
一种在命令行中指定一组目标的方法。常用模式包括 :all
(所有规则目标)、:*
(所有规则目标 + 文件目标)、...
(以递归方式的当前软件包和所有子软件包)。可以组合使用,例如,//...:*
表示从工作区根目录以递归方式触发所有软件包中的所有规则和文件目标。
测试
根据测试规则实例化的规则目标,因此包含测试可执行文件。如果可执行文件完成后返回代码为零,则表示测试成功。Test Encyclopedia 中指定了 Bazel 与测试(例如测试环境变量、测试结果收集方法)的确切协定。
工具链
一组用于构建语言输出的工具。通常,工具链包括编译器、链接器、解释器和/和 linter。工具链也可以因平台而异,也就是说,Unix 编译器工具链的组件对于 Windows 变体可能有所不同,即使工具链用于同一种语言也是如此。为平台选择正确的工具链称为工具链解析。
顶级目标
如果是通过 Bazel 命令行请求的 build 目标,它是顶级目标。例如,如果 //:foo
依赖于 //:bar
,并且系统调用了 bazel build //:foo
,那么对于此 build,//:foo
是顶级目标,而 //:bar
不是顶级目标,但这两个目标都需要构建。顶级目标和非顶级目标之间的一个重要区别在于,在 Bazel 命令行上设置(或通过 .bazelrc)设置的命令标志将为顶级目标设置配置,但对于非顶级目标,可以通过转换进行修改。
转换
配置状态从一个值到另一个值的映射。使 build 图中的目标具有不同的配置,即使它们是从同一规则实例化的。过渡的常见用途是拆分过渡,其中目标图的某些部分针对每个分支的不同配置进行分支。例如,可以在单个 build 中使用拆分转换,使用针对 ARM 和 x86 编译的原生二进制文件构建 Android APK。
另请参阅:用户定义的转场
树工件
表示文件集合的工件。由于这些文件本身并不是工件,因此对其执行操作的“操作”必须改为将树工件注册为其输入或输出。
公开范围
用于防止构建系统中出现不必要的依赖项的两种机制之一:目标可见性,用于控制目标是否可依赖于其他目标;加载可见性,用于控制 BUILD
或 .bzl
文件是否可以加载给定的 .bzl
文件。如果没有上下文,“可见性”通常是指目标可见性。
另请参阅:可见性文档
Workspace
所有 Bazel 命令共享的环境都从同一个主代码库运行。
请注意,“仓库”和“工作区”的概念历来混淆;术语“工作区”通常用来指代主仓库,有时甚至用作“仓库”的同义词。为清楚起见,应避免此类使用。