供应商模式是 Bzlmod 的一项功能,支持您 外部依赖项这在离线构建时非常有用, 控制外部依赖项的来源
启用供应商模式
您可以通过指定 --vendor_dir
标志来启用供应商模式。
例如,通过将其添加到 .bazelrc
文件中:
# Enable vendor mode with vendor directory under <workspace>/vendor_src
common --vendor_dir=vendor_src
供应商目录可以是工作区根目录的相对路径,也可以是 绝对路径。
提供特定外部代码库
您可以使用带有 --repo
标志的 vendor
命令来指定哪个代码库
它同时接受规范代码库
名称和明显代码库
名称。
例如,运行以下命令:
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
或
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc+
都会获得 rules_cc,
<workspace root>/vendor_src/rules_cc+
。
给定目标的供应商外部依赖项
如需提供构建给定目标模式所需的所有外部依赖项,
您可以运行 bazel vendor <target patterns>
。
例如:
bazel vendor --vendor_dir=vendor_src //src/main:hello-world //src/test/...
将提供构建 //src/main:hello-world
目标所需的所有代码库
以及 //src/test/...
下具有当前配置的所有目标。
在后台,它会执行 bazel build --nobuild
命令来分析
目标模式,因此可以将构建标志应用于此命令,
影响结果。
离线构建目标
提供外部依赖项后,您可以通过以下命令离线构建目标:
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
构建应在没有网络访问权限的干净构建环境中运行, 存储库缓存。
因此,您应该能够检查供应商的源代码,并构建 其他机器上的离线目标
提供所有外部依赖项
如需在传递外部依赖项图中提供所有代码库,您可以 运行:
bazel vendor --vendor_dir=vendor_src
请注意,提供所有依赖项都存在一些缺点:
- 提取所有代码库(包括以传递方式引入的代码库)可能非常耗时。
- vendor 目录可能会变得非常大。
- 如果某些代码库与当前平台或环境不兼容,则可能无法提取。
因此,应先考虑通过 vendor 方法指定特定目标。
使用 VENDOR.bazel 配置供应商模式
您可以通过位于以下位置的 VENDOR.bazel 文件来控制如何处理给定的代码库: 放在供应商目录下
可用的指令有两种,都接受 规范代码库名称作为参数:
ignore()
:表示完全忽略供应商模式下的代码库。pin()
:将代码库固定到其当前供应商的源代码,就好像 此代码库的--override_repository
标志。Bazel 不会更新 此代码库的源代码(除非取消固定)。 用户可以手动修改和维护此代码库的供应商源代码。
例如:
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
采用此配置
- 这两个代码库将从后续供应商命令中排除。
- Repo
bazel_skylib
将被替换为位于 vendor 目录中。 - 用户可以安全地修改通过供应商提供的
bazel_skylib
源代码。 - 如需重新添加
bazel_skylib
代码,用户必须停用 PIN 码 。
了解供应商模式的工作原理
Bazel 提取 $(bazel info
output_base)/external
下的项目的外部依赖项。通过 vendoring 方法添加外部依赖项,
相关的文件和目录添加到指定的供应商目录,然后使用
针对后续 build 提供的供应商源代码。
通过供应商提供的内容包括:
- 代码库目录
- 代码库标记文件
在构建期间,如果供应商提供的标记文件是最新版本或代码库是
固定在 VENDOR.bazel 文件中,则 Bazel 会使用供应商提供的源代码,方法是
$(bazel info output_base)/external
下指向它的符号链接,而不是
运行代码库规则否则,系统会显示警告,且 Bazel 会
回退到提取最新版本的代码库。
供应商注册表文件
Bazel 必须执行 Bazel 模块解析才能提取外部
依赖项,这可能需要通过互联网访问注册表文件。接收者
实现离线构建,Bazel 供应商从其中提取的所有注册表文件
位于 <vendor_dir>/_registries
目录下。
供应商符号链接
外部代码库可能包含指向其他文件或 目录。为了确保符号链接正常工作,Bazel 使用以下代码 策略:在供应商源代码中重写符号链接:
- 创建一个指向
$(bazel info output_base)/external
的符号链接<vendor_dir>/bazel-external
。它由每个 Bazel 命令刷新 。 - 对于供应商提供的源,请重写最初指向
$(bazel info output_base)/external
下的相对路径<vendor_dir>/bazel-external
。
例如,如果原始符号链接是
<vendor_dir>/repo_foo+/link => $(bazel info output_base)/external/repo_bar+/file
它将重写为
<vendor_dir>/repo_foo+/link => ../../bazel-external/repo_bar+/file
其中
<vendor_dir>/bazel-external => $(bazel info output_base)/external # This might be new if output base is changed
由于 <vendor_dir>/bazel-external
是由 Bazel 自动生成的,因此它
建议将其添加到 .gitignore
或等效项中,以避免签入。
使用此策略时,即使 在供应商的源代码移至其他位置或 bazel 输出库后 更改。