本页面介绍了如何创建代码库规则,并提供了 。
外部代码库是指仅允许使用的规则
(位于 WORKSPACE
文件中),并在加载阶段启用非封闭操作
Vertex AI SDK。每条外部代码库规则都会创建自己的工作区,及其
自己的 BUILD
文件和工件。它们可用于依赖于第三方
库(例如 Maven 打包库),还可以生成 BUILD
文件
运行 Bazel 的主机特有的
创建代码库规则
在 .bzl
文件中,使用
repository_rule 函数,用于创建新
并将其存储在全局变量中。
自定义代码库规则的使用方式与原生代码库规则相同。它具有必需的 name
属性,并且其 build 文件中存在的每个目标都可以称为 @<name>//package:target
,其中 <name>
是 name
属性的值。
系统会在您明确构建规则时加载规则,或者规则的依赖项
构建。在这种情况下,Bazel 将执行其 implementation
函数。这个
函数描述了如何创建代码库及其内容和 BUILD
文件。
属性
属性是作为字典传递给 attrs
规则参数的规则参数。在定义属性及其类型时,
代码库规则。将 url
和 sha256
属性定义为
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.name
。repo_mapping
的含义与
原生代码库规则
local_repository
和
new_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_ctx
的read()
、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 工件。