代码库规则

报告问题 查看来源 每晚 · 7.4。 ,了解所有最新动态。 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

创建代码库规则

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

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

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

属性

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

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 代码。
  • 使用 environ 声明的任何环境变量的值 repository_rule 的属性值。 您可以使用 --action_env 标志在命令行上对这些环境变量的值进行硬编码(但此标志会使 build 的所有操作失效)。
  • 传递给 repository_ctxread()execute() 和类似方法的任何文件的内容,该方法由标签引用(例如 //mypkg:label.txt,但不包括 mypkg/label.txt
  • 执行 bazel sync 时。

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

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

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

重启实现函数

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

强制重新提取外部代码库

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

此外,有些规则会检查本地机器, 如果本地计算机升级,则会过时。在这里,您可以使用 bazel sync --configure 指示 bazel 仅重新提取 repository_rule 定义设置了 configure 属性的外部代码库。

示例

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

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

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