代码库、工作区、软件包和目标

报告问题 查看源代码

Bazel 会根据源代码(在目录树中称为代码库)来构建软件。一组定义的代码库由工作区组成。代码库中的源文件按软件包的嵌套层次结构进行组织,其中每个软件包都是一个目录,其中包含一组相关的源文件和一个 BUILD 文件。BUILD 文件指定可以从源代码构建哪些软件输出。

仓库

Bazel 构建中使用的源文件会整理到“代码库”中(通常简称为“代码库”)。代码库是一种目录树,其根目录下有一个边界标记文件;此类边界标记文件可以是 MODULE.bazelREPO.bazel;在旧版上下文中,可以是 WORKSPACEWORKSPACE.bazel

运行当前 Bazel 命令的代码库称为主代码库。其他(外部)仓库由 Repo 规则定义;如需了解详情,请参阅外部依赖项概览

工作区

工作区是指从同一主代码库运行的所有 Bazel 命令共享的环境。它包含主代码库以及所有已定义的外部代码库的集合。

请注意,“仓库”和“工作区”的概念历来混淆;术语“工作区”通常用来指代主仓库,有时甚至用作“仓库”的同义词。

软件包

代码库中的代码组织主要单元是软件包。软件包是相关文件的集合,以及有关如何使用这些文件来生成输出工件的规范。

软件包指的是包含名为 BUILDBUILD.bazelBUILD 文件的目录。软件包包含其目录中的所有文件,以及其下的所有子目录,但那些本身包含 BUILD 文件的子目录除外。根据此定义,任何文件或目录都不能包含在两个不同的软件包中。

例如,以下目录树中有两个软件包:my/app 和子软件包 my/app/tests。请注意,my/app/data 不是软件包,而是属于软件包 my/app 的目录。

src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc

目标

软件包是包含目标的容器,目标在软件包的 BUILD 文件中定义。大多数目标都是两种主要种类之一,即文件和规则

文件进一步分为两种。源文件通常由人们编写并签入代码库。生成的文件(有时称为衍生文件或输出文件)不会签入,而是从源文件生成。

第二种定位条件是使用规则声明的。每个规则实例都指定了一组输入和一组输出文件之间的关系。规则的输入可能是源文件,但也可能是其他规则的输出。

在大多数情况下,规则的输入是源文件还是生成的文件并不重要;重要的只是该文件的内容。这一点使得系统可以轻松地将复杂的源文件替换为由规则生成的生成的文件,例如,手动维护高度结构化文件的负担过于繁琐时,会有人编写程序来派生该文件。该文件的使用者无需做出任何更改。相反,生成的文件可能很容易被替换为仅本地更改的源文件。

规则的输入内容可能还包括其他规则。这种关系的确切含义通常非常复杂,并且取决于语言或规则,但直觉上很简单:一个 C++ 库规则 A 可能有另一个用于输入的 C++ 库规则 B。此依赖项的影响在于,B 的头文件在编译期间可供 A 使用,B 的符号在链接期间可供 A 使用,B 的运行时数据在执行期间可供 A 使用。

所有规则的不变之处在于,由规则生成的文件始终与规则本身属于同一软件包;无法将文件生成到其他软件包中。不过,规则的输入来自其他软件包的情况并不少见。

软件包组是一组软件包,其用途是限制某些规则的可访问性。软件包组由 package_group 函数定义。它们具有三个属性:它们包含的软件包列表、其名称及其包含的其他软件包组。引用它们的唯一方式是:通过规则的 visibility 属性或 package 函数的 default_visibility 属性来引用它们;它们不会生成或使用文件。如需了解详情,请参阅 package_group 文档

标签