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

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

代码库

Bazel build 中使用的源文件组织在 代码库(通常缩写为 repo)中。repo 是一个目录树,其根目录中有一个边界标记文件;此类边界标记文件可以是 MODULE.bazelREPO.bazel,或者 在旧版上下文中,可以是 WORKSPACEWORKSPACE.bazel

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

工作区

工作区是所有从同一主 repo 运行的 Bazel 命令共享的环境。它包含主 repo 和所有已定义的外部 repo 的集合。

请注意,从历史上看,“代码库”和“工作区”这两个概念一直混为一谈;“工作区”一词通常用于指代主代码库,有时甚至用作“代码库”的同义词。

软件包

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

软件包定义为一个包含名为 BUILD 文件 的目录,该文件名为 BUILDBUILD.bazel。软件包包含其目录中的所有文件,以及其下的所有子目录,但本身包含 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属性或来自default_visibility属性的 package函数;它们不会生成或使用文件。如需了解详情,请参阅 package_group 文档

标签