由于 WORKSPACE 存在缺点,Bzlmod 正在取代旧版 WORKSPACE 系统。WORKSPACE 文件已在 Bazel 8(2024 年末)中停用,并将在 Bazel 9(2025 年末)中移除。本指南可帮助您将项目迁移到 Bzlmod,并放弃使用 WORKSPACE 来管理外部依赖项。
为什么要迁移到 Bzlmod?
与旧版 WORKSPACE 系统相比,该系统具有许多优势,有助于确保 Bazel 生态系统的健康发展。
如果您的项目是其他项目的依赖项,那么迁移到 Bzlmod 将有助于这些项目顺利迁移,并使它们更容易依赖您的项目。
迁移到 Bzlmod 是使用未来 Bazel 版本(在 Bazel 9 中是强制性的)的必要步骤。
如何迁移到 Bzlmod?
建议的迁移流程:
- 使用迁移工具作为辅助工具,尽可能简化迁移流程。请参阅迁移工具和如何使用该工具部分。
- 如果使用迁移工具后仍存在错误,请手动解决这些错误。如需了解
WORKSPACE
和MODULE.bazel
文件中概念的主要区别,请参阅 WORKSPACE 与 Bzlmod 部分。
迁移工具
为了简化从 WORKSPACE 迁移到 Bzlmod 的过程(通常很复杂),强烈建议使用迁移脚本。此辅助工具可自动执行迁移外部依赖项管理系统所涉及的许多步骤。
核心功能
该脚本的主要功能包括:
- 依赖项信息收集:分析项目的
WORKSPACE
文件,以识别指定 build 目标所使用的外部代码库。它使用 Bazel 的 experimental_repository_resolved_file 标志来生成包含此信息的resolved_deps.py
文件。 - 直接依赖项识别:使用
bazel query
确定指定目标的哪些代码库是直接依赖项。 - Bzlmod 迁移:将相关的
WORKSPACE
依赖项转换为其 Bzlmod 等效项。此流程分为两步:- 尝试将所有已识别的直接依赖项引入
MODULE.bazel
文件。 - 尝试在启用 Bzlmod 的情况下构建指定目标,然后以迭代方式识别并修复可识别的错误。由于第一步中可能缺少某些依赖项,因此需要执行此步骤。
- 尝试将所有已识别的直接依赖项引入
- 生成迁移报告:创建记录迁移过程的
migration_info.md
文件。此报告包含直接依赖项的列表、生成的 Bzlmod 声明,以及可能需要执行的任何手动步骤才能完成迁移。
迁移工具支持:
- Bazel 中央注册表中提供的依赖项
- 用户定义的自定义代码库规则
- [即将推出] 软件包管理器依赖项
重要提示:迁移工具是一种尽力而为的实用程序。请务必始终仔细检查其建议是否正确。
如何使用迁移工具
准备工作:
- 升级到最新的 Bazel 7 版本,该版本可为 WORKSPACE 和 Bzlmod 提供强大的支持。
验证以下命令是否针对项目的主要 build 目标成功运行:
bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
满足前提条件后,运行以下命令以使用迁移工具:
# Clone the Bazel Central Registry repository
git clone https://github.com/bazelbuild/bazel-central-registry.git
cd bazel-central-registry
# Build the migration tool
bazel build //tools:migrate_to_bzlmod
# Create a convenient alias for the tool
alias migrate2bzlmod=$(realpath ./bazel-bin/tools/migrate_to_bzlmod)
# Navigate to your project's root directory and run the tool
cd <your workspace root>
migrate2bzlmod -t <your build targets>
WORKSPACE 与 Bzlmod
Bazel 的 WORKSPACE 和 Bzlmod 提供类似的功能,但语法不同。本部分介绍了如何从特定的 WORKSPACE 功能迁移到 Bzlmod。
定义 Bazel 工作区的根目录
WORKSPACE 文件用于标记 Bazel 项目的源代码根目录,在 Bazel 版本 6.3 及更高版本中,此职责由 MODULE.bazel 文件取代。对于低于 6.3 的 Bazel 版本,工作区根目录中仍应有 WORKSPACE
或 WORKSPACE.bazel
文件,可能带有如下注释:
WORKSPACE
# This file marks the root of the Bazel workspace. # See MODULE.bazel for external dependencies setup.
在 bazelrc 中启用 Bzlmod
借助 .bazelrc
,您可以设置每次运行 Bazel 时都适用的标志。如需启用 Bzlmod,请使用 --enable_bzlmod
标志,并将其应用于 common
命令,以便它适用于每个命令:
.bazelrc
# Enable Bzlmod for every Bazel command common --enable_bzlmod
为工作区指定代码库名称
WORKSPACE
workspace
函数用于为工作区指定代码库名称。这样,工作区中的目标//foo:bar
就可以作为@<workspace name>//foo:bar
进行引用。如果未指定,则工作区的默认代码库名称为__main__
。## WORKSPACE workspace(name = "com_foo_bar")
Bzlmod
建议使用不带
@<repo name>
的//foo:bar
语法引用同一工作区中的目标。不过,如果您确实需要旧语法,可以使用module
函数指定的模块名称作为代码库名称。如果模块名称与所需的代码库名称不同,您可以使用module
函数的repo_name
属性来替换代码库名称。## MODULE.bazel module( name = "bar", repo_name = "com_foo_bar", )
以 Bazel 模块的形式提取外部依赖项
如果您的依赖项是 Bazel 项目,那么当该项目也采用 Bzlmod 时,您应该能够将其作为 Bazel 模块依赖项。
WORKSPACE
对于 WORKSPACE,通常使用
http_archive
或git_repository
代码库规则下载 Bazel 项目的源代码。## WORKSPACE load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"], sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa", ) load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() http_archive( name = "rules_java", urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"], sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a", ) load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains") rules_java_dependencies() rules_java_toolchains()
如您所见,用户需要从依赖项的宏加载传递依赖项是一种常见模式。假设
bazel_skylib
和rules_java
都依赖于platform
,platform
依赖项的确切版本由宏的顺序决定。Bzlmod
借助 Bzlmod,只要您的依赖项在 Bazel Central Registry 或您的自定义 Bazel 注册表中可用,您就可以使用
bazel_dep
指令简单地依赖它。## MODULE.bazel bazel_dep(name = "bazel_skylib", version = "1.4.2") bazel_dep(name = "rules_java", version = "6.1.1")
Bzlmod 使用 MVS 算法以传递方式解析 Bazel 模块依赖项。因此,系统会自动选择所需的
platform
的最大版本。
以 Bazel 模块的形式替换依赖项
作为根模块,您可以通过不同方式替换 Bazel 模块依赖项。
如需了解详情,请参阅替换部分。
您可以在示例代码库中找到一些用法示例。
使用模块扩展程序提取外部依赖项
如果您的依赖项不是 Bazel 项目,或者尚未在任何 Bazel 注册表中提供,您可以使用 use_repo_rule
或模块扩展程序来引入该依赖项。
WORKSPACE
使用
http_file
代码库规则下载文件。## WORKSPACE load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") http_file( name = "data_file", url = "http://example.com/file", sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", )
Bzlmod
借助 Bzlmod,您可以在 MODULE.bazel 文件中使用
use_repo_rule
指令直接实例化代码库:## MODULE.bazel http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") http_file( name = "data_file", url = "http://example.com/file", sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", )
在底层,这是使用模块扩展实现的。如果您需要执行比简单调用 repo 规则更复杂的逻辑,也可以自行实现模块扩展。您需要将定义移至
.bzl
文件中,这样还可以在迁移期间在 WORKSPACE 和 Bzlmod 之间共享定义。## repositories.bzl load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") def my_data_dependency(): http_file( name = "data_file", url = "http://example.com/file", sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", )
实现模块扩展程序以加载依赖项宏。您可以在宏的同一
.bzl
文件中定义它,但为了与旧版 Bazel 保持兼容性,最好在单独的.bzl
文件中定义它。## extensions.bzl load("//:repositories.bzl", "my_data_dependency") def _non_module_dependencies_impl(_ctx): my_data_dependency() non_module_dependencies = module_extension( implementation = _non_module_dependencies_impl, )
为了使根项目能够看到代码库,您应在 MODULE.bazel 文件中声明模块扩展程序和代码库的用法。
## MODULE.bazel non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies") use_repo(non_module_dependencies, "data_file")
解决与模块扩展程序的外部依赖项的冲突
项目可以提供一个宏,用于根据调用者的输入引入外部代码库。但如果依赖关系图中有多个调用方,并且它们导致了冲突,该怎么办?
假设项目 foo
提供以下以 version
为实参的宏。
## repositories.bzl in foo {:#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
http_file(
name = "data_file",
url = "http://example.com/file-%s" % version,
# Omitting the "sha256" attribute for simplicity
)
WORKSPACE
借助 WORKSPACE,您可以从
@foo
加载宏,并指定所需的数据依赖项版本。假设您有另一个依赖项@bar
,它也依赖于@foo
,但需要不同版本的数据依赖项。## WORKSPACE # Introduce @foo and @bar. ... load("@foo//:repositories.bzl", "data_deps") data_deps(version = "2.0") load("@bar//:repositories.bzl", "bar_deps") bar_deps() # -> which calls data_deps(version = "3.0")
在这种情况下,最终用户必须仔细调整 WORKSPACE 中宏的顺序,才能获得所需的版本。这是 WORKSPACE 的最大痛点之一,因为它没有提供解决依赖项的合理方法。
Bzlmod
借助 Bzlmod,项目
foo
的作者可以使用模块扩展程序来解决冲突。例如,假设在所有 Bazel 模块中,始终选择数据依赖项的最大必需版本是有意义的。## extensions.bzl in foo load("//:repositories.bzl", "data_deps") data = tag_class(attrs={"version": attr.string()}) def _data_deps_extension_impl(module_ctx): # Select the maximal required version in the dependency graph. version = "1.0" for mod in module_ctx.modules: for data in mod.tags.data: version = max(version, data.version) data_deps(version) data_deps_extension = module_extension( implementation = _data_deps_extension_impl, tag_classes = {"data": data}, )
## MODULE.bazel in bar bazel_dep(name = "foo", version = "1.0") foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension") foo_data_deps.data(version = "3.0") use_repo(foo_data_deps, "data_file")
## MODULE.bazel in root module bazel_dep(name = "foo", version = "1.0") bazel_dep(name = "bar", version = "1.0") foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension") foo_data_deps.data(version = "2.0") use_repo(foo_data_deps, "data_file")
在这种情况下,根模块需要数据版本
2.0
,而其依赖项bar
需要3.0
。foo
中的模块扩展程序可以正确解决此冲突,并自动为数据依赖项选择版本3.0
。
集成第三方软件包管理系统
根据上一部分的内容,由于模块扩展提供了一种从依赖关系图收集信息的方式,因此可以执行自定义逻辑来解析依赖关系并调用代码库规则来引入外部代码库,这为规则作者提供了一种绝佳的方式来增强集成特定语言的软件包管理器的规则集。
请参阅模块扩展程序页面,详细了解如何使用模块扩展程序。
以下是已采用 Bzlmod 从不同软件包管理器获取依赖项的规则集列表:
您可以在 examples 代码库中找到集成伪软件包管理器的最简示例。
检测主机上的工具链
当 Bazel 构建规则需要检测主机上可用的工具链时,它们会使用代码库规则来检查主机,并生成工具链信息作为外部代码库。
WORKSPACE
假设有以下用于检测 shell 工具链的代码库规则。
## local_config_sh.bzl def _sh_config_rule_impl(repository_ctx): sh_path = get_sh_path_from_env("SH_BIN_PATH") if not sh_path: sh_path = detect_sh_from_path() if not sh_path: sh_path = "/shell/binary/not/found" repository_ctx.file("BUILD", """ load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain") sh_toolchain( name = "local_sh", path = "{sh_path}", visibility = ["//visibility:public"], ) toolchain( name = "local_sh_toolchain", toolchain = ":local_sh", toolchain_type = "@bazel_tools//tools/sh:toolchain_type", ) """.format(sh_path = sh_path)) sh_config_rule = repository_rule( environ = ["SH_BIN_PATH"], local = True, implementation = _sh_config_rule_impl, )
您可以在 WORKSPACE 中加载代码库规则。
## WORKSPACE load("//:local_config_sh.bzl", "sh_config_rule") sh_config_rule(name = "local_config_sh")
Bzlmod
借助 Bzlmod,您可以使用模块扩展程序引入相同的代码库,这与上一部分中引入
@data_file
代码库类似。## local_config_sh_extension.bzl load("//:local_config_sh.bzl", "sh_config_rule") sh_config_extension = module_extension( implementation = lambda ctx: sh_config_rule(name = "local_config_sh"), )
然后在 MODULE.bazel 文件中使用该扩展程序。
## MODULE.bazel sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension") use_repo(sh_config_ext, "local_config_sh")
注册工具链和执行平台
按照上一部分中的说明,在引入代码库托管工具链信息(例如 local_config_sh
)后,您可能需要注册该工具链。
WORKSPACE
对于 WORKSPACE,您可以通过以下方式注册工具链。
您可以在
.bzl
文件中注册工具链,并在 WORKSPACE 文件中加载宏。## local_config_sh.bzl def sh_configure(): sh_config_rule(name = "local_config_sh") native.register_toolchains("@local_config_sh//:local_sh_toolchain")
## WORKSPACE load("//:local_config_sh.bzl", "sh_configure") sh_configure()
或者直接在 WORKSPACE 文件中注册工具链。
## WORKSPACE load("//:local_config_sh.bzl", "sh_config_rule") sh_config_rule(name = "local_config_sh") register_toolchains("@local_config_sh//:local_sh_toolchain")
Bzlmod
使用 Bzlmod 时,
register_toolchains
和register_execution_platforms
API 仅在 MODULE.bazel 文件中可用。您无法在模块扩展程序中调用native.register_toolchains
。## MODULE.bazel sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension") use_repo(sh_config_ext, "local_config_sh") register_toolchains("@local_config_sh//:local_sh_toolchain")
在选择工具链时,在 WORKSPACE
、WORKSPACE.bzlmod
和每个 Bazel 模块的 MODULE.bazel
文件中注册的工具链和执行平台遵循以下优先级顺序(从最高到最低):
- 根模块的
MODULE.bazel
文件中注册的工具链和执行平台。 WORKSPACE
或WORKSPACE.bzlmod
文件中注册的工具链和执行平台。- 由根模块的(传递性)依赖项模块注册的工具链和执行平台。
- 未使用
WORKSPACE.bzlmod
时:在WORKSPACE
后缀中注册的工具链。
介绍本地代码库
当您需要依赖项的本地版本进行调试,或者想要将工作区中的目录作为外部代码库纳入时,可能需要将依赖项作为本地代码库引入。
WORKSPACE
对于 WORKSPACE,可通过两个原生代码库规则
local_repository
和new_local_repository
实现此目的。## WORKSPACE local_repository( name = "rules_java", path = "/Users/bazel_user/workspace/rules_java", )
Bzlmod
借助 Bzlmod,您可以使用
local_path_override
通过本地路径替换模块。## MODULE.bazel bazel_dep(name = "rules_java") local_path_override( module_name = "rules_java", path = "/Users/bazel_user/workspace/rules_java", )
还可以通过模块扩展引入本地代码库。不过,您无法在模块扩展中调用
native.local_repository
,我们正在努力将所有原生代码库规则转换为 Starlark 规则(请查看 #18285 以了解进度)。然后,您可以在模块扩展程序中调用相应的 Starlarklocal_repository
。如果这是一个阻碍您的问题,实现local_repository
代码库规则的自定义版本也很简单。
绑定目标
WORKSPACE 中的 bind
规则已被弃用,并且在 Bzlmod 中不受支持。引入它是为了在特殊的 //external
软件包中为目标提供别名。依赖于此的所有用户都应迁移。
举例来说,如果你的
## WORKSPACE
bind(
name = "openssl",
actual = "@my-ssl//src:openssl-lib",
)
这样一来,其他目标就可以依赖于 //external:openssl
。您可以采取以下措施来摆脱此问题:
将
//external:openssl
的所有用法替换为@my-ssl//src:openssl-lib
。- 提示:使用
bazel query --output=build --noenable_bzlmod --enable_workspace [target]
命令可查找有关目标的相关信息。
- 提示:使用
或者使用
alias
build 规则在软件包(例如
//third_party
)中定义以下目标## third_party/BUILD alias( name = "openssl", actual = "@my-ssl//src:openssl-lib", )
将
//external:openssl
的所有用法替换为//third_party:openssl
。
提取与同步
提取和同步命令用于在本地下载外部代码库并保持其更新。有时还用于在提取构建所需的所有代码库后,使用 --nofetch
标志离线构建。
WORKSPACE
同步会强制提取所有代码库或一组特定的已配置代码库,而提取仅用于提取特定目标。
Bzlmod
同步命令不再适用,但提取命令提供了多种选项。 您可以提取目标、代码库、一组已配置的代码库或参与依赖项解析和模块扩展的所有代码库。提取结果会被缓存,如需强制提取,您必须在提取过程中添加
--force
选项。
手动迁移
本部分为您的手动 Bzlmod 迁移流程提供了实用信息和指导。如需了解更自动化的迁移流程,请参阅推荐的迁移流程部分。
了解 WORKSPACE 中的依赖项
迁移的第一步是了解您有哪些依赖项。由于传递依赖项通常通过 *_deps
宏加载,因此可能很难确定 WORKSPACE 文件中引入的确切依赖项。
检查具有工作区已解析文件的外部依赖项
幸运的是,标志 --experimental_repository_resolved_file
可以提供帮助。此标志实际上会生成上一个 Bazel 命令中所有已提取的外部依赖项的“锁定文件”。如需了解详情,请参阅这篇博文。
它可以通过以下两种方式使用:
用于提取构建特定目标所需的外部依赖项的信息。
bazel clean --expunge bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
用于提取 WORKSPACE 文件中定义的所有外部依赖项的信息。
bazel clean --expunge bazel sync --experimental_repository_resolved_file=resolved.bzl
借助
bazel sync
命令,您可以提取 WORKSPACE 文件中定义的所有依赖项,包括:bind
用量register_toolchains
和register_execution_platforms
用法
不过,如果您的项目是跨平台的,那么 bazel 同步可能会在某些平台上中断,因为某些代码库规则可能仅在受支持的平台上正确运行。
运行该命令后,您应该会在 resolved.bzl
文件中看到外部依赖项的信息。
使用 bazel query
检查外部依赖项
您可能还知道,bazel query
可用于检查代码库规则,
bazel query --output=build //external:<repo name>
虽然它更方便且速度更快,但 bazel 查询可能会谎报外部依赖项版本,因此请谨慎使用!使用 Bzlmod 查询和检查外部依赖项将通过新子命令来实现。
内置默认依赖项
如果您检查 --experimental_repository_resolved_file
生成的文件,会发现许多未在 WORKSPACE 中定义的依赖项。这是因为 Bazel 实际上会向用户的 WORKSPACE 文件内容添加前缀和后缀,以注入一些通常是原生规则(例如 @bazel_tools
、@platforms
和 @remote_java_tools
)所需的默认依赖项。借助 Bzlmod,这些依赖项会通过内置模块 bazel_tools
引入,而该模块是所有其他 Bazel 模块的默认依赖项。
用于逐步迁移的混合模式
Bzlmod 和 WORKSPACE 可以并排工作,这样一来,将依赖项从 WORKSPACE 文件迁移到 Bzlmod 的过程就可以逐步完成。
WORKSPACE.bzlmod
在迁移期间,Bazel 用户可能需要在启用和未启用 Bzlmod 的 build 之间切换。实现了 WORKSPACE.bzlmod 支持,以使流程更顺畅。
WORKSPACE.bzlmod 的语法与 WORKSPACE 完全相同。如果启用了 Bzlmod,并且工作区根目录中还存在 WORKSPACE.bzlmod 文件,则:
WORKSPACE.bzlmod
生效,WORKSPACE
的内容会被忽略。- 不会向 WORKSPACE.bzlmod 文件添加任何前缀或后缀。
使用 WORKSPACE.bzlmod 文件可让迁移更轻松,原因如下:
- 当 Bzlmod 处于停用状态时,系统会回退到从原始 WORKSPACE 文件中提取依赖项。
- 启用 Bzlmod 后,您可以使用 WORKSPACE.bzlmod 更好地跟踪还需迁移的依赖项。
代码库公开范围
Bzlmod 能够控制从给定代码库中可以看到哪些其他代码库,如需了解详情,请参阅代码库名称和严格的依赖项。
下表总结了不同类型代码库的库公开范围,同时还考虑了 WORKSPACE。
来自主代码库 | 来自 Bazel 模块代码库 | 来自模块扩展程序代码库 | 来自 WORKSPACE 代码库 | |
---|---|---|---|---|
主代码库 | 可见 | 如果根模块是直接依赖项 | 如果根模块是托管模块扩展的模块的直接依赖项 | 可见 |
Bazel 模块代码库 | 直接依赖项 | 直接依赖项 | 托管模块扩展的模块的直接依赖项 | 根模块的直接依赖项 |
模块扩展代码库 | 直接依赖项 | 直接依赖项 | 托管模块扩展程序的模块的直接依赖项 + 由同一模块扩展程序生成的所有代码库 | 根模块的直接依赖项 |
工作区代码库 | 所有可见 | 不显示 | 不显示 | 所有可见 |
手动迁移流程
典型的 Bzlmod 迁移过程可能如下所示:
- 了解您在 Workspace 中的依赖项。
- 在项目根目录中添加一个空的 MODULE.bazel 文件。
- 添加一个空的 WORKSPACE.bzlmod 文件,以替换 WORKSPACE 文件内容。
- 在启用 Bzlmod 的情况下构建目标,并检查缺少哪个代码库。
- 检查已解析的依赖项文件中的缺失代码库的定义。
- 通过模块扩展程序将缺少的依赖项作为 Bazel 模块引入,或者将其留在 WORKSPACE.bzlmod 中以供日后迁移。
- 返回到第 4 步,然后重复该步骤,直到所有依赖项都可用为止。
发布 Bazel 模块
如果您的 Bazel 项目是其他项目的依赖项,您可以在 Bazel 中央注册表中发布您的项目。
如需在 BCR 中签入项目,您需要项目的源归档网址。创建源归档文件时,请注意以下几点:
确保归档指向特定版本。
BCR 只能接受已纳入版本控制的源归档,因为 Bzlmod 需要在依赖项解析期间进行版本比较。
确保归档网址稳定。
Bazel 会通过哈希值验证归档的内容,因此您应确保下载文件的校验和永远不会更改。如果网址来自 GitHub,请在发布页面中创建并上传发布归档文件。GitHub 不会保证按需生成的源归档的校验和。简而言之,
https://github.com/<org>/<repo>/releases/download/...
形式的网址被认为是稳定的,而https://github.com/<org>/<repo>/archive/...
则不是。如需了解更多背景信息,请参阅 GitHub 归档校验和中断。确保源树遵循原始代码库的布局。
如果您的代码库非常大,并且您想通过剥离不必要的来源来创建大小缩小的分发归档,请确保剥离的源代码树是原始源代码树的子集。这样,最终用户就可以通过
archive_override
和git_override
更轻松地将模块替换为非发布版本。在子目录中包含一个测试最常用 API 的测试模块。
测试模块是一个 Bazel 项目,它在源归档文件的子目录中拥有自己的 WORKSPACE 和 MODULE.bazel 文件,并且依赖于要发布的实际模块。它应包含涵盖最常用 API 的示例或一些集成测试。请参阅测试模块,了解如何设置。
准备好源代码归档网址后,请按照 BCR 贡献指南通过 GitHub Pull Request 将您的模块提交到 BCR。
强烈建议为代码库设置发布到 BCR GitHub 应用,以自动执行向 BCR 提交模块的流程。
最佳做法
本部分介绍了一些最佳实践,您应遵循这些实践来更好地管理外部依赖项。
将目标拆分为不同的软件包,以避免提取不必要的依赖项。
请查看 #12835,其中强制不必要地提取测试的开发依赖项,以构建不需要这些依赖项的目标。这实际上并非 Bzlmod 特有的,但遵循此实践可更轻松地正确指定开发依赖项。
指定开发依赖项
您可以针对 bazel_dep
和 use_extension
指令将 dev_dependency
属性设置为 true,这样它们就不会传播到依赖项目。作为根模块,您可以使用 --ignore_dev_dependency
标志来验证您的目标是否仍然可以在没有开发依赖项和替换项的情况下构建。
社群迁移进度
您可以查看 Bazel 中央注册表,了解您的依赖项是否已可用。否则,欢迎加入此 GitHub 讨论,对阻碍迁移的依赖项进行投票或发布相关信息。
报告问题
请查看 Bazel GitHub 问题列表,了解已知的 Bzlmod 问题。欢迎随时提交新问题或功能请求,以帮助您顺利完成迁移!