如何在 Bazel 工程中配置 carbon_toolchain 模块用 Carbon 工具链编译 C++ 代码?
【免费下载链接】carbon-langCarbon Language's main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang
如果你的 Bazel 工程需要用 Carbon 项目自带的 C++ 工具链(基于 Clang 的carbon工具链)来编译 C++ 代码,可以在工程根目录的MODULE.bazel中引入carbon_toolchain模块并注册其cc_toolchain。carbon-lang 仓库在 examples/bazel 下提供了一个完整的示例工程,演示了整套配置:它声明了对carbon_toolchain的依赖,注册了工具链,然后用cc_library/cc_binary编译一段 C++ 代码。
注意两点前提:
- 示例工程是一个独立的子 Bazel 工程,根在
examples/bazel目录,不属于 carbon-lang 主仓库的 Bazel 工程(不能用bazel build //examples/bazel/...从仓库根构建它)。文档明确要求交互时先cd examples/bazel。 carbon_toolchain模块声明的版本号是0.0.0占位值,即使你会用本地路径或压缩包覆盖它,这个bazel_dep声明也必须保留。
准备 MODULE.bazel:声明模块与依赖
按 examples/bazel/MODULE.bazel 的配置,最小配置包含三部分:
module(name = "example") bazel_dep(name = "rules_cc", version = "0.2.14") # Declare the `carbon_toolchain` module. This is needed even if it will be # overridden with a local path or archive. bazel_dep(name = "carbon_toolchain", version = "0.0.0") register_toolchains("@carbon_toolchain//:all")bazel_dep(name = "carbon_toolchain", version = "0.0.0"):声明依赖。注释明确说明,即使之后用local_path_override或archive_override覆盖,这条声明也是必需的。register_toolchains("@carbon_toolchain//:all"):注册该模块提供的cc_toolchain目标。这是 toolchain/install/bazel/install.MODULE.bazel 文档串中给出的标准用法:"Add the repository to yourMODULES.bazeland then useregister_toolchains(\"@carbon_toolchain//:all\")to get these toolchains."
模块安装后,toolchain/install/bazel/carbon_toolchain.bzl 中的模块扩展会运行安装里的carbon二进制(carbon config --json)提取配置,生成carbon_detected_variables.bzl,再由cc_toolchain把这些值组装成可用的 C++ Bazel 工具链。
指定 carbon_toolchain 的来源:三种覆盖方式
由于 Bazel 中央仓库里还没有正式发布的carbon_toolchain版本(0.0.0只是占位),文档给出了三种指定实际来源的方式(均来自 examples/bazel/MODULE.bazel 头部注释),按使用场景三选一:
方式一:命令行覆盖本地安装(无需改文件)
如果手上已有一个 Carbon 工具链安装目录,直接传启动参数:
bazel build --override_module=carbon_toolchain=/path/to/carbon_toolchain/installation/lib/carbon其中/path/to/carbon_toolchain/installation/lib/carbon是安装产物中lib/carbon子目录的路径,替换为你自己的实际安装位置。carbon-lang 的集成测试 examples/bazel_test_runner.py 就是这样做的:--override_module=carbon_toolchain=<runfiles 中的 toolchain/install 路径>。
方式二:local_path_override 写入 MODULE.bazel
把本地覆盖固化到工程里,替换命令行参数:
local_path_override( module_name = "carbon_toolchain", path = "/path/to/carbon_toolchain/installation/lib/carbon", )path同样指向你本地安装目录下的lib/carbon。
方式三:archive_override 指向 nightly 发布包
如果不想本地安装,可以直接引用 GitHub 上的 nightly 发布 tar.gz:
version = "0.0.0-0.nightly.YYYY.MM.DD" archive_override( module_name = "carbon_toolchain", strip_prefix = "carbon_toolchain-{0}/lib/carbon".format(version), urls = ["https://github.com/carbon-language/carbon-lang/releases/download/v{0}/carbon_toolchain-{0}.tar.gz".format(version)], )文档特别提示:首次使用时 Bazel 会警告缺少integrity字段,并在下载压缩包后打印实际计算出的值,你可以到 GitHub 上核对后再把这个值编码进integrity字段。
编写 BUILD 文件与编译目标
示例工程的 examples/bazel/BUILD 展示了要编译的 C++ 代码目标:
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") cc_library( name = "example_lib", srcs = [ "example_lib.cpp", "example_lib.h", ], # We force static linking here so we can test compilation without performing # a full link that is more expensive with runtimes on demand. linkstatic = 1, ) cc_binary( name = "example", srcs = ["example.cpp"], deps = [":example_lib"], )其中linkstatic = 1是示例工程特意加上的,注释解释了原因:强制静态链接,这样只需验证编译即可,不必做完整链接——在使用按需运行库(runtimes on demand)时完整链接开销更大。如果你的工程不需要只验证编译,可以不加这个参数。
对应的入口代码见 examples/bazel/example.cpp:main调用HelloWorld()后返回EXIT_SUCCESS。
验证编译是否成功
在工程根目录(即含MODULE.bazel的examples/bazel)执行:
bazel build //:example_lib编译目标通过即说明carbon_toolchain提供的cc_toolchain已正确接管 C++ 编译。如果要做更完整的验证,仓库的集成测试 examples/bazel_test_runner.py 还包含运行步骤:
bazel run //:example该测试断言输出为Hello World!,即示例程序成功运行时的预期 stdout(文档示例输出)。测试层对退出码还有明确约定:1(构建失败)、2(命令行或环境问题)、3(测试失败或超时)、4(无测试)、8(构建被显式中断)视为永久性错误,不重试。
可选:用脚本自动生成 nightly 的 archive_override
如果选择方式三,不必手工拼archive_override。examples/bazel/update_module_to_nightly.py 会查询 GitHub 上最新的 nightly 发布(nightly 是预发布版本,所以脚本走的是 release 列表接口而非releases/latest),从 GitHub 获取 tar.gz 的 sha256 digest 并转换为 Bazel 格式,然后写入MODULE.bazel:
cd examples/bazel ./update_module_to_nightly.py使用该脚本前注意副作用和前置条件:
- 它会修改当前目录下的
MODULE.bazel:若已存在carbon_toolchain的archive_override块则整体替换,不存在则插入到bazel_dep声明之后; - 当前目录必须存在
MODULE.bazel,且其中已有carbon_toolchain的bazel_dep声明,否则脚本直接报错退出; - 需要访问 GitHub API(
api.github.com),脚本要求 Python 3.12+(通过uv run --script方式运行); - 脚本成功时会打印
[update_module_to_nightly] Successfully updated MODULE.bazel to version <version>到 stderr,可作为更新完成的判断依据。
生成的archive_override块形如(值由脚本填入):
archive_override( module_name = "carbon_toolchain", integrity = "sha256-...", strip_prefix = "carbon_toolchain-<version>/lib/carbon", urls = ["https://github.com/carbon-language/carbon-lang/releases/download/v<version>/carbon_toolchain-<version>.tar.gz"], )限制与后续变化
- 当前阶段必须通过上述覆盖方式指定
carbon_toolchain来源,bazel_dep的版本号保持0.0.0占位。文档说明:等 Carbon 工具链在 Bazel 中央仓库(BCR)发布正式版本后,更新MODULE.bazel中的版本号即可开箱工作,无需覆盖。 carbon_toolchain模块自身还声明了对rules_cc(0.2.17)、platforms(1.0.0)、bazel_skylib(1.9.0)的依赖(见 toolchain/install/bazel/install.MODULE.bazel),示例工程里显式写的rules_cc 0.2.14会被 Bazel 按模块依赖规则统一解析。- 完整参考实现(工具链如何从
carbon安装产物中生成cc_toolchain配置)可继续阅读 toolchain/install/BUILD 与 toolchain/install/bazel/carbon_toolchain.bzl。
【免费下载链接】carbon-langCarbon Language's main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考