在Bazel中一个从357字节开始的C++工具链

Lobsters Hottest 工具

摘要

一篇博客文章,描述了一种新的Bazel工具链,它从357字节的stage0引导种子开始编译C++代码,在Bazel中实现了完全源码引导且封闭的C++工具链。作者演示了它从Bazel Central Registry构建未打补丁的Abseil和GoogleTest。

<p><a href="https://lobste.rs/s/pq7dtk/c_toolchain_from_357_bytes_bazel">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/10 21:03

# 一个只有 357 字节的 C++ 工具链,基于 Bazel 来源:https://fzakaria.com/2026/08/01/a-c++-toolchain-from-357-bytes-in-bazel 我着迷于 stage0(https://savannah.nongnu.org/projects/stage0/)已有一段时间了,自从我通过 Guix 了解到它(https://guix.gnu.org/en/blog/2023/the-full-source-bootstrap-building-from-source-all-the-way-down/)——Guix 用它来让两万两千个软件包从 357 字节的种子实现源码引导。 什么是 stage0? 它是一系列可以从源码构建的编译器和汇编器,始于**一个 357 字节**的程序,最终能够构建出较新的 GCC。11一旦你拥有了足够新的 GCC,就可以轻松构建任何 C/C++ 程序乃至更多。 从那时起,NixOS(https://discourse.nixos.org/t/a-full-source-bootstrap-for-nixos/74801)和其他发行版(https://github.com/fosslinux/live-bootstrap)也采用了同样的方法来最小化它们的二进制种子,这使得支持新的架构和平台变得更加简单。 作为一名 Bazel(https://bazel.build/)(以及 Buck(https://buck2.build/))用户,一直让我*沮丧*的是,即便对于那些本应很容易从源码构建的东西(如 protoc(https://fzakaria.com/2024/11/28/bazel-knowledge-protobuf-is-the-worst-when-it-should-be-the-best)),也依赖预构建工具链。 Bazel 已经放弃了提供密封(hermetic)C++ 工具链的努力,上游的 rules_cc(https://github.com/bazelbuild/rules_cc)规则集也只是把你指向别处: > 配置密封的工具链能让你的构建更具确定性。rules_cc 本身尚未提供密封工具链的分发版。 我曾尝试在 2024 年 10 月(https://github.com/fzakaria/stage0-bazel/tree/d22d6b050f66a93c1b843c24b8f17dc519dd4802)通过 https://github.com/fzakaria/stage0-bazel 提供一个 stage0 密封 C++ 工具链。我在引导过程中取得了相当大的进展,但还远未达到可用的程度。 说实话,我也有些心灰意冷,因为社区里似乎没有其他人认为这是有史以来最棒的东西。在人们深入 MODULE.bzl 的疯狂(https://fzakaria.com/2024/07/02/reproducibility-in-disguise)时,似乎大家都满足于使用预构建工具链。 我搁置了一段时间,但最近又开始思考这件事。这些步骤是机械性的,流程也模仿了现有发行版,因此这成了一个绝佳的项目,可以交给 LLM 来完成。22请把这视为我的声明:我使用了 LLM 来帮我编写工具链的其余部分。 现在,你可以利用这个工具链在 Bazel 中构建 `cc_binary`,并由一个其**全部祖先**都来自该仓库、同样源于那个**357 字节种子**的工具链来编译。🎆 这个工具链有多完整? 我直接将工具链指向了 Bazel 中央注册表中的 Abseil(https://abseil.io/)和 GoogleTest(https://github.com/google/googletest),**没有任何补丁**。 `` bazel_dep(name = "stage0-bazel", version = "0.1.0") bazel_dep(name = "abseil-cpp", version = "20260107.1") bazel_dep(name = "googletest", version = "1.17.0.bcr.2") register_toolchains( "@stage0-bazel//toolchain:clang", "@stage0-bazel//toolchain:cc", ) `` 然后我们可以构建并运行它们的测试套件,作为工具链工作正常的 sanity check。 `` $ bazel test --target_pattern_file=absl-tests.txt Executed 236 out of 236 tests: 236 tests pass `` 我们使用 `--target_pattern_file` 来过滤掉需要 `google_benchmark` 的测试。Abseil 将 `google_benchmark` 标记为 `dev_dependency`,而 Bzlmod 会丢弃非根模块的 dev 依赖。 也就是说,我们从注册表构建 Abseil 和 GoogleTest,未打补丁,却是由一个始于 357 字节十六进制的工具链编译的。 bootstrapseedhex0357 bytesstage0hex1 → hex2 → M0 → cc_x86M2-Planet, kaem, M1seed->stage0mesGNU Mesmesccstage0->mestccmestcc-mesmes->tccmestcctinyccself-hostedtccmes->tccmuslmusltcc->muslbinbinutilsmusl->bingcc46GCC 4.6.4bin->gcc46gcc10GCC 10.4.0C++17gcc46->gcc10extrastar, findutilsLinux UAPI headersgcc10->extrasllvmclang 22.1.8+lld 22.1.8gcc10->llvmextras->llvmabslAbseil + GoogleTest236 tests passllvm->absl (https://fzakaria.com/assets/graphviz/1da0a3eca0ecd2cf.svg)我怎么能确定这是一个密封工具链? 该工具链包含一份*审计报告*,它使用 Bazel 的 aspects(https://bazel.build/extending/aspects)来检查构建图中的每一个 action,并验证它只执行由工具链自身构建的程序。这份报告通过运行 `bazel build //:trust-report` 生成,如果有任何 action 执行了 Bazel 输出树之外的程序,报告就会失败。33我们还设置了 `BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1` 来禁用 Bazel 内置的 C++ 主机工具链检测。 报告只有两行: `` Bootstrap trust report Every action in the checked graph runs a program built by this repository, except for these audited seed binaries: external/+_repo_rules+hex0-seeds/POSIX/x86/hex0-seed /nix/store/...-bash-interactive-5.3p3/bin/bash `` 不幸的是,由于 `genrule` 运行的 shell 采用的是绝对系统路径,它也被列为种子二进制文件。`sh_toolchain` 的 `path` 属性是一个字符串,而 shell 并非该 action 的声明输入,因此本仓库构建的任何产物都无法提供它。 对于像 Google 这样完全控制构建环境的公司来说,从引导种子构建工具链从来都不是优先事项。然而,随着 Bazel 及类似构建系统在开源社区中越来越流行,我们似乎也采用了同样的方法。我们应该努力让构建更具可重现性和密封性,而这是朝着这个方向迈出的一步。

相似文章

Bazel 新增内容定义分块

Hacker News Top

BuildBuddy 的远程缓存现在采用内容定义分块 (CDC),实现对大型构建输出的字节级复用,在基准测试中上传量减少 40%,磁盘缓存大小减少 40%。

以Zig风格构建你的项目

Lobsters Hottest

作者详细介绍了构建一个名为bygge-zig的工具,该工具使用Zig构建系统来编译Rust项目,用更少的代码行复制了Cargo的功能,并突出了其中的差异和挑战。

为 Zig 打包的 C/C++ 项目

Hacker News Top

一个工具,可将现有的 C/C++ 项目打包以供 Zig 构建系统使用,从而实现更简单的集成。

自举构建:方法与原因

Hacker News Top

这篇文章涵盖了一场在FOSSY会议上的演讲,解释了自举构建,该构建方法能够从最小可信源构建整个系统,以增强软件安全性和可重现性。

使用并行Claude团队构建C编译器

Anthropic Engineering

Anthropic研究员展示了如何使用16个并行Claude实例自主构建一个基于Rust的C编译器,该编译器能够编译Linux内核。文章详细介绍了这一多智能体自主编码实验的架构、成本和经验教训。