尧图精选

Bazel 项目如何从 WORKSPACE 迁移到 Bzlmod 管理外部依赖?

🕒 发布时间:2026/9/14 17:30:54 📁 来源:尧图网络
Bazel 项目如何从 WORKSPACE 迁移到 Bzlmod 管理外部依赖【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel如果你的 Bazel 项目还在用WORKSPACE文件声明http_archive、maven_install等外部依赖就需要完成这件事Bazel 82024 年底已默认禁用WORKSPACEBazel 92025 年底将彻底移除它迁移到 BzlmodMODULE.bazel是继续使用 Bazel 9 的必要步骤来源docs/external/migration.mdx。Bzlmod 用确定性的 MVS 算法解析版本MODULE.bazel只需声明直接依赖传递依赖由 Bazel Central Registry 自动发现不再需要靠deps.bzl宏和调用顺序管理传递依赖。本文给出一条完整可执行的迁移路径准备环境 → 用官方迁移脚本自动转换 → 手动补齐剩余错误 → 用bazel build和bazel mod验证 → 清理收尾。一、准备条件先明确 Bazel 版本要求迁移涉及两个不同阶段的版本约束不要混淆阶段Bazel 版本说明运行官方迁移脚本最新的 Bazel 7迁移脚本明确要求 Use the migration tool with Bazel 7 (not supported with Bazel 8)且 Bazel 7 对 WORKSPACE 和 Bzlmod 都有健壮支持来源docs/external/migration_tool.mdx迁移完成后的日常构建Bazel 8 及以上Bazel 8 已禁用 WORKSPACEBazel 9 移除 WORKSPACE迁移是升级到 Bazel 9 的前提来源docs/external/migration.mdx在开始之前先验证你的项目在当前 WORKSPACE 体系下能正常解析依赖文档给出的检查命令targets替换为你项目的主要构建目标如//...bazel build --nobuild --enable_workspace --noenable_bzlmod targets这条命令只解析依赖、不执行构建动作能确认你的WORKSPACE声明目前是完整的。二、主路径用官方迁移脚本自动转换官方推荐流程分两步先使用迁移脚本自动化迁移再用本文第五节的手动流程解决脚本剩下的错误。构建并运行迁移脚本脚本位于 Bazel Central Registry 仓库的tools/migrate_to_bzlmod需要先克隆并用 Bazel 7 构建出来# 克隆 Bazel Central Registry 仓库文档步骤会新建一个本地目录 git clone https://github.com/bazelbuild/bazel-central-registry.git cd bazel-central-registry # 用 Bazel 7 构建迁移工具 bazel build //tools:migrate_to_bzlmod # 创建命令别名指向构建产物 alias migrate2bzlmod$(realpath ./bazel-bin/tools/migrate_to_bzlmod) # 回到你自己的项目根目录并运行 cd your project root migrate2bzlmod -t targetsmigrate2bzlmod是上面alias定义的本地命令不是系统自带的。-t/--target指定要迁移的目标可重复传入、目标会累加-t //...表示全部目标。注意副作用脚本会修改你的项目生成MODULE.bazel、migration_info.md、resolved_deps.py、query_direct_deps等文件并为无法直接成为模块的依赖生成extension_for_XXX扩展文件来源docs/external/migration_tool.mdx。--i/--initial标志会删除MODULE.bazel、resolved_deps.py、migration_info.md然后从头检测只在需要推倒重来时使用。脚本支持的依赖类型Bazel Central Registry 中的模块、自定义 repository rule、以及 Maven / Go / Python 包管理器依赖。脚本输出的含义文档中的示例输出文档示例具体依赖名以你的项目为准bazel 7.6.1 Generating ./resolved_deps.py file - It might take a while... RESOLVED: rules_python has been introduced as a Bazel module. IMPORTANT: 3.11 is used as a default python version. If you need a different version, please change it manually and then rerun the migration tool. RESOLVED: my_python_deps has been introduced as python extension. ... Congratulations! All external repositories needed for building //... are available with Bzlmod! IMPORTANT: Fix potential build time issues by running the following command: bazel build --enable_bzlmod --noenable_workspace //... IMPORTANT: For details about the migration process, check migration_info.md file.判断要点RESOLVED表示该依赖已被写入MODULE.bazel可能是 Bazel 模块、pip/go/maven 扩展或原样的 repository rule 调用IMPORTANT是需要你人工确认的信息例如 Python 默认版本被取为 3.11不符合预期就手动修改后重跑脚本脚本是 best-effort 工具文档明确要求始终复核它的建议是否正确。三、验证迁移结果脚本跑完后按以下顺序验证。1. 阅读迁移报告打开项目根目录生成的migration_info.md。报告包含本地测试命令、直接依赖列表、每个依赖在WORKSPACE中的原始声明位置用于调试、以及它在MODULE.bazel中的实现方式。如果报告列出了需要手动完成的步骤先处理这些步骤。2. 跑一次完整构建按脚本给出的命令执行完整构建--nobuild只能证明依赖解析通过构建时还会暴露工具链未注册等问题bazel build --enable_bzlmod --noenable_workspace targets能全部构建成功说明依赖迁移在构建层面已经就绪出现错误则进入第五节手动处理。3. 用bazel mod检查依赖图bazel mod提供检查模块依赖关系的子命令用于确认解析结果符合预期# 查看完整模块依赖图root 即你的项目 bazel mod graph # 查看某个仓库的最终定义确认它来自哪里、哪个版本 bazel mod show_repo rules_python # 查看某个模块扩展生成了哪些仓库、被谁 use_repo bazel mod show_extension rules_python//python/extensions:pip.bzl%pip例如bazel mod show_repo rules_cc stardoc会打印出解析后实际生效的http_archive定义URL、integrity 等可以据此核对版本是否和你原来WORKSPACE中的一致。四、把 WORKSPACE 声明翻译成 Bzlmod 语法对于脚本没有覆盖、或需要你手工改写的部分迁移指南按功能类型给出了一一对照。下面是迁移中最常见的几类。在 .bazelrc 中全局启用 Bzlmod# Enable Bzlmod for every Bazel command common --enable_bzlmod用common前缀让--enable_bzlmod对所有 Bazel 命令生效。声明模块身份与依赖Bazel 6.3 中MODULE.bazel取代WORKSPACE标记 workspace 根。原来workspace(name com_foo_bar)指定的仓库名用module的repo_name属性保留当你仍需要com_foo_bar//foo:bar这种旧式标签时否则推荐直接用//foo:bar写法## MODULE.bazel module( name bar, repo_name com_foo_bar, )依赖本身是 Bazel 项目且已在 Bazel Central Registry时原来的一大段http_archive*_deps()宏## 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()收敛成一行传递依赖由 MVS 算法自动选出最高可满足版本## MODULE.bazel bazel_dep(name bazel_skylib, version 1.4.2) bazel_dep(name rules_java, version 6.1.1)非 Bazel 依赖use_repo_rule 或模块扩展依赖不在任何 Bazel registry 中时用use_repo_rule直接实例化 repo rule或自己实现模块扩展。以http_file为例## 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, )需要更复杂逻辑比如原来的*_deps宏时把宏定义放进.bzl文件再包装成模块扩展迁移期可与 WORKSPACE 共享同一份定义## 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, )## 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 non_module_dependencies use_extension(//:extensions.bzl, non_module_dependencies) use_repo(non_module_dependencies, data_file)本地仓库、工具链注册与 bind本地依赖WORKSPACE 的local_repository(name, path)对应local_path_override注意后者要求本地目录本身是 Bazel 模块有自己的MODULE.bazel## MODULE.bazel bazel_dep(name rules_java) local_path_override( module_name rules_java, path /Users/bazel_user/workspace/rules_java, )所有 override 指令只能由根模块使用。工具链注册register_toolchains/register_execution_platforms在 Bzlmod 下只能在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)过渡期间工具链选择优先级从高到低根模块MODULE.bazel→WORKSPACE/WORKSPACE.bzlmod→ 依赖模块的MODULE.bazel→未使用WORKSPACE.bzlmod时WORKSPACE的 Bazel 注入后缀。bind 规则bind已废弃且不受 Bzlmod 支持。迁移方式是全局把//external:openssl这类标签替换为真实标签my-ssl//src:openssl-lib可用bazel query --outputbuild --noenable_bzlmod --enable_workspace [target]查目标信息或者在某个包里如//third_party定义alias目标再替换标签。五、手动补齐处理脚本剩下的错误官方给出的典型手动迁移循环来源docs/external/migration.mdx弄清楚WORKSPACE里到底有哪些依赖下节的方法。在项目根添加MODULE.bazel脚本已生成的话可跳过。添加一个空的WORKSPACE.bzlmod文件。它语法与WORKSPACE完全相同Bzlmod 启用时它会生效并忽略WORKSPACE的内容且不会追加 Bazel 默认的 prefix/suffix。这样 Bzlmod 关闭时回退到原WORKSPACE开启时WORKSPACE.bzlmod里剩下的内容就是待迁移清单。官方建议从WORKSPACE.bzlmod起步、避免在其中 load 传递依赖宏。用 Bzlmod 构建目标看报出哪个仓库缺失。在 resolved 依赖文件中找到该缺失仓库的原始定义。把它引入为 Bazel 模块、模块扩展或暂时留在WORKSPACE.bzlmod里以后再说。回到第 4 步重复直到所有依赖可用。摸清 WORKSPACE 里的依赖用--experimental_repository_resolved_file生成依赖锁文件。注意前置命令bazel clean --expunge会清除整个 output base包括缓存的已 fetch 仓库来源docs/remote/output-directories.mdx之后首次构建会重新下载依赖属于预期副作用# 方式一只为构建某些目标生成 resolved 文件 bazel clean --expunge bazel build --nobuild --experimental_repository_resolved_fileresolved.bzl //foo:bar# 方式二抓取 WORKSPACE 中定义的全部依赖含 bind、register_toolchains bazel clean --expunge bazel sync --experimental_repository_resolved_fileresolved.bzl方式二的bazel sync在跨平台项目上可能在某些平台失败部分 repository rule 只能在支持的平台运行。另外提醒bazel query --outputbuild //external:repo name更快但文档明确警告它可能对外部依赖版本说谎核对版本时以 resolved 文件为准。resolved 文件中还会看到很多你不在WORKSPACE里定义的依赖如bazel_tools、platforms——它们是 Bazel 注入的默认依赖Bzlmod 下由内置模块bazel_tools自动提供不需要迁移。排查版本被 MVS 提升了Bzlmod 可能选出比WORKSPACE时代更高的依赖版本MVS 总是取依赖图里要求的最高版本导致构建行为变化。文档给出的排查手段来源docs/external/migration_tool.mdx用single_version_override(module_name {dep_name}, version {version})把该依赖钉回原版本对比差异定位问题。文档说明这用于调试 WORKSPACE 与 Bzlmod 的行为差异不应作为长期方案。bazel mod show_repo rules_python确认当前解析到的仓库定义。如需监控或控制某个仓库的来源可用 vendor 模式创建本地副本bazel vendor --enable_bzlmod --vendor_dirvendor_src --repoprotobuf六、收尾清理与升级限制迁移全部通过后的清理步骤文档明确要求删除migration_info.md、resolved_deps.py、query_direct_deps。清理MODULE.bazel中迁移工具留下的注释例如# -- bazel_dep definitions -- #。版本层面的限制再强调一次迁移脚本只支持 Bazel 7不支持 Bazel 8Bazel 8 中WORKSPACE已默认禁用可用--enable_workspace临时打开如bazel build --nobuild --enable_workspace --noenable_bzlmod targetsBazel 9 中WORKSPACE被移除届时未迁移的项目将无法构建。如果某个依赖还查不到对应的 Bazel 模块可以到 docs/external/faq.mdx 和 Bazel Central Registry 确认该依赖是否已被收录这是迁移能否完全去 WORKSPACE 化的最后一个瓶颈。【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →