本页面介绍了如何创建代码库规则,并提供了 。
外部代码库是指仅允许使用的规则
(位于 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 代码。
- 传递给
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 sync
要求 bazel 无条件地重新提取所有外部代码库。
此外,有些规则会检查本地机器,
如果本地计算机升级,则会过时。在这里,您可以使用 bazel sync --configure
指示 bazel 仅重新提取 repository_rule
定义设置了 configure
属性的外部代码库。
示例
C++ 自动配置的工具链:它使用代码库规则,通过查找本地 C++ 编译器、环境和 C++ 编译器支持的标志,为 Bazel 自动创建 C++ 配置文件。
Go 代码库使用多个
repository_rule
来定义使用 Go 规则所需的依赖项列表。rules_jvm_external 默认会创建一个名为
@maven
的外部仓库,用于为传递依赖项树中的每个 Maven 工件生成构建目标。