代码库规则

报告问题 查看来源 每晚 · 7.2。 · 7.1敬上 · 7.0 · 6.5 · 6.4

本页面介绍了如何创建代码库规则,并提供了 。

外部代码库是仅允许使用的规则 (位于 WORKSPACE 文件中),并在加载阶段启用非封闭操作 Vertex AI SDK。每条外部代码库规则都会创建自己的工作区,及其 自己的 BUILD 文件和工件。它们可用于依赖于第三方 库(例如 Maven 打包库),还可以生成 BUILD 文件 运行 Bazel 的主机特有的

创建仓库规则

.bzl 文件中,使用 通过 repository_rule 函数创建新的 并将其存储在全局变量中。

自定义代码库规则的使用方式与原生代码库规则相同。它 具有必需的 name 属性,并且其 build 文件中存在每个目标 可以称为 @<name>//package:target,其中 <name>name 属性。

系统会在您明确构建规则时加载规则,或者规则的依赖项 和构建。在这种情况下,Bazel 将执行其 implementation 函数。这个 函数描述了如何创建代码库及其内容和 BUILD 文件。

属性

属性是以字典形式传递给 attrs 规则参数的规则参数。 在定义属性及其类型时, 代码库规则。将 urlsha256 属性定义为 字符串:

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={
        "url": attr.string(mandatory=True)
        "sha256": attr.string(mandatory=True)
    }
)

要访问实现函数中的某个属性,请使用 repository_ctx.attr.<attribute_name>

def _impl(repository_ctx):
    url = repository_ctx.attr.url
    checksum = repository_ctx.attr.sha256

所有 repository_rule 都具有隐式定义的属性(就像 build 一样) 规则)。两个隐式属性是 name(就像构建规则一样)和 repo_mapping。代码库规则的名称可通过 repository_ctx.namerepo_mapping 的含义与 原生代码库规则 local_repositorynew_local_repository

如果属性名称以 _ 开头,则该属性为私有属性,用户无法设置。

实现函数

每条代码库规则都需要一个 implementation 函数。它包含 规则的实际逻辑,并严格在加载阶段执行。

该函数只有一个输入参数 repository_ctx。函数 会返回 None,这表示在给定给定条件的情况下,规则可重现。 或包含该规则的一组参数的字典 会将该规则变为可重现的规则,从而生成相同的代码库。对于 例如,对于跟踪 git 代码库的规则,这意味着 指定的提交标识符,而不是最初作为浮动分支的 。

输入参数 repository_ctx 可用于 访问属性值和非封闭函数(查找二进制文件、 执行二进制文件、在代码库中创建文件或下载文件 来自互联网)。如需了解详情,请参阅 上下文。示例:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

何时执行实现函数?

当 Bazel 需要 目标,例如当另一个目标(在另一个 依赖于它,或者命令行中是否提到了它。通过 实现函数需要在文件中创建代码库 系统。此过程称为“提取”代码库

与常规目标不同, 导致代码库与众不同的更改这是 因为 Bazel 要么无法检测到对某些方面所做的更改 每次构建都会耗费过多开销(例如,提取的内容 )。因此,只有在出现以下任一情况时,系统才会重新提取代码库: 会发生以下变化:

  • 传递给 WORKSPACE 文件。
  • 构成存储库实现的 Starlark 代码。
  • 传递给 repository_ctx 的任何环境变量的值 getenv() 方法,或使用environ repository_rule。值 您可以使用 --repo_env 标志。
  • 传递给 read()execute() 等方法的任何文件的内容 repository_ctx 的方法,该方法由标签引用(例如, //mypkg:label.txt,但不包括 mypkg/label.txt
  • 执行 bazel sync 时。

repository_rule 的两个参数用于控制代码库 :

  • 如果设置了 configure 标志,系统仅会在以下时间重新提取仓库: bazel sync(如果--configure参数传递给它时(如果 属性未设置,则此命令不会导致重新提取)
  • 如果设置了 local 标志,则除了上述情况之外, 以及当 Bazel 服务器重启或任何影响 代码库的声明更改(例如 WORKSPACE 文件或文件 无论更改是否导致 存储库或其代码的声明

    在这些情况下,系统不会重新提取非本地代码库。这是因为 假定这些代码库与网络通信 价格高昂。

重启实现函数

在存储库期间,可以重启实现函数 如果其请求的依赖项缺失,则获取。在这种情况下, 实现函数将停止,缺少的依赖项会被解析, 依赖项解决后,系统将重新执行该函数。接收者 避免不必要的重启(重启成本高昂,因为网络访问 标签参数会被预提取,前提是 标签参数可解析为现有文件。请注意,解析 仅在执行期间构造的字符串或标签的路径 也仍可能导致重启。

强制重新提取外部代码库

有时,外部仓库可能已经过时, 定义或依赖项。例如,提取源代码的代码库 跟踪第三方代码库的特定分支,并且新提交会 该分支提供的所有资源这种情况下,您可以让 bazel 重新获取 外部代码库。bazel sync

此外,有些规则会检查本地机器, 如果本地计算机升级,则会过时。在这里,你可以让 bazel 完成以下操作: 则只会重新提取 repository_rule 设置了 configure 属性,请使用 bazel sync --configure

示例

  • C++ 自动配置的工具链: 它使用仓库规则自动创建 为 Bazel 创建 C++ 配置文件,方法是查找本地 C++ 编译器 环境和 C++ 编译器支持的标志。

  • Go 代码库 使用多个 repository_rule 定义依赖项列表 使用 Go 规则所需的操作。

  • rules_jvm_external 用于创建 默认名为 @maven 的外部代码库,用于生成构建目标 传递依赖项树中的每个 Maven 工件。