Skip to content

fix(gcc,llvm,rust): let each compiler build hello-world from its own closure - #805

Draft
norrietaylor wants to merge 3 commits into
mainfrom
fix/toolchain-hello-world
Draft

norrietaylor wants to merge 3 commits into
mainfrom
fix/toolchain-hello-world

Conversation

@norrietaylor

@norrietaylor norrietaylor commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Problem

A box that adds one compiler package on its own can't build a trivial program:

Package added Command Error
gcc gcc h.c cannot execute 'as': posix_spawnp: No such file or directory
gcc g++ on code that includes <linux/types.h> header not found
llvm clang h.c unable to execute command: posix_spawn failed at the link step
rust rustc h.rs linker 'cc' not found

The assembler and linker come from binutils and the kernel headers from linux_headers, and neither is in these packages' runtime closures. gcc also installs no cc, and cc is the linker rustc invokes by default. The rust stack already works around all of this: it adds gcc, binutils and linux_headers and sets the linker to gcc. Packages can't set environment variables, so the package fix has to supply a real cc.

Change

  • gcc
    • Adds binutils and linux_headers to runtime_deps.
    • build.sh installs usr/bin/cc -> gcc. The existing usr/bin/* glob covers it. gcc already installs c++, so only cc was missing.
    • The four existing compile tests no longer add binutils to their test_deps (that was the TODO: Some of these need to be runtime_deps). A new test builds and runs a C program with cc and a C++ program that includes <linux/types.h> with g++, using only bash-bootstrap and coreutils as test_deps.
  • llvm
    • Adds binutils (clang's driver links through ld) and linux_headers to runtime_deps.
    • A new test compiles and runs a C program that includes <linux/types.h> with clang.
  • rust
    • Adds toolchain to runtime_deps. This is the same C toolchain set the rust stack adds (gcc, which now provides cc, plus binutils, glibc and linux_headers), so rustc's default cc linker resolves without -C linker=gcc.
    • toolchain moves out of build_deps, because runtime deps are already injected into the build.
    • A new test compiles and runs a hello-world with rustc.

Design note: cc

Two alternatives were considered and rejected:

  • Set rust.default-linker = "gcc" in bootstrap.toml. rustc would still need a C toolchain at runtime, and cargo-driven C builds (the cc crate) would still look for cc.
  • A cc shim in toolchain. A gcc-only box would still lack cc.

A cc symlink in gcc fixes all three cases with one line.

Things a reviewer should weigh

  1. Runtime cycle. binutils already runtime-depends on subsetOf gcc ["libstdcpp", "libgcc"], so this change adds the cycle gcc → binutils → gcc. The planner handles it: both gcc and binutils declare a replace_on_cycle. Locally, min check passes and a branch session resolves and installs the new gcc closure. CI's full-graph build is the authoritative proof.
  2. Closure growth for subsetOf gcc users. A subsetOf dependency inherits the source package's full runtime_deps; it already does this for gmp, mpc, mpfr, zlib and zstd. About 128 packages runtime-depend on subsetOf gcc [...] to get libgcc_s or libstdc++, so their runtime closures now also gain binutils and linux_headers. That adds about 28 MiB for binutils and about 6.5 MiB for the headers, measured with du --apparent-size on arm64. Sessions already include gcc, so they barely change, but the closures of packaged programs grow. If that is not acceptable, the alternative is to split libgcc/libstdc++ into their own package, or to fall back to pointing gcc-only users at toolchain. Either is a larger change than this PR.
  3. Rebuild scope. gcc's build changes, so every package re-keys. The local rebuild hit one memory issue, described in the test plan.

Test plan

Run on an arm64 Minimal VM (macOS host, 10 vCPU, 16 GiB), in sessions synced from this branch:

  • Baseline, sessions on main:
    • gcc only: as not found, and <linux/types.h> not found.
    • llvm only: clang fails at link (posix_spawn failed), and clang++ can't find <linux/types.h>.
    • rust only: linker 'cc' not found.
  • Equivalent closures from the published cache, sessions on main:
    • gcc + binutils + linux_headers: gcc h.c and g++ with <linux/types.h> build and run.
    • llvm + binutils + linux_headers: clang h.c and clang++ with <linux/types.h> build and run.
    • rust + toolchain: rustc h.rs still fails on cc. With a cc -> gcc symlink on PATH, plain rustc h.rs builds and the binary prints hi.
  • min check --packages gcc,llvm,rust,toolchain,binutils passes, including the output checks for gcc after its build.
  • min package patched-build gcc succeeds. In a fresh branch session, /usr/bin/cc -> gcc, as, ld and /usr/include/linux/types.h are present without adding binutils or linux_headers. gcc h.c, cc h.c and g++ with <linux/types.h> all build and run.
  • min package patched-build rust succeeds with toolchain moved to runtime_deps.
  • Not verified locally: the llvm build, and installing the rebuilt rust. The gcc change re-keys llvm-bootstrap, which llvm and rust need. Its rebuild was OOM-killed in the 16 GiB VM (g++: fatal error: Killed signal terminated program cc1plus). That is a memory limit of this VM, not a compile error. So min package patched-build llvm couldn't run, and min add --session rust couldn't install the rebuilt rust. The clang and rustc results above come from the equivalent-closure runs, not from the rebuilt packages.
  • Not run locally: the standalone tests blocks (there's no in-session test runner), and amd64. CI is the first run of both.

Refs gominimal/inbox#843

Summary by CodeRabbit

  • New Features
    • GCC now provides the cc command as an alternative way to invoke its C compiler.
    • GCC and LLVM packages include the supporting tools and Linux headers needed by compiled programs.
    • The Rust toolchain is available at runtime, with a hello-world program verified to compile and run.

…closure

A box that adds only gcc, llvm or rust could not compile a trivial
program: gcc and clang had no assembler or linker, C and C++ code could
not include kernel headers, and rustc found no cc to link through.

- gcc: runtime-depend on binutils and linux_headers, and install a cc
  symlink (gcc already installs c++). The existing tests no longer add
  binutils themselves, and a new test covers cc and g++ with
  <linux/types.h>.
- llvm: runtime-depend on binutils and linux_headers so clang finds ld
  and the kernel headers.
- rust: runtime-depend on toolchain, the same C toolchain the rust stack
  adds, so rustc's default cc linker resolves.

Refs gominimal/inbox#843
@norrietaylor
norrietaylor requested a review from a team as a code owner October 4, 2026 05:12
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: gominimal/pkgs/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: e7107ddc-df15-46b0-bbbf-7038c936dedd
📥 Commits

Reviewing files that changed from the base of the PR and between c583978 and 1b10dae.

📒 Files selected for processing (4)
  • packages/gcc/build.ncl
  • packages/gcc/build.sh
  • packages/llvm/build.ncl
  • packages/rust/build.ncl

Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour.


📝 Walkthrough

Walkthrough

GCC and LLVM add runtime dependencies and standalone compiler tests. GCC also creates a cc symlink. Rust moves toolchain from an unconditional build dependency to a runtime dependency and adds a standalone Rust test.

Changes

Compiler Package Changes

Layer / File(s) Summary
GCC runtime setup and compiler tests
packages/gcc/build.ncl, packages/gcc/build.sh
GCC adds binutils and linux_headers as runtime dependencies, removes binutils from four test dependency lists, and adds a C and C++ compile-and-run test. The build script creates cc as a relative symlink to gcc.
LLVM runtime dependencies and header test
packages/llvm/build.ncl
LLVM adds build imports and runtime dependencies for binutils and Linux headers. A standalone test compiles and runs C code that includes linux/types.h.
Rust dependency staging and compiler test
packages/rust/build.ncl
Rust removes the unconditional toolchain build dependency and adds toolchain as a runtime dependency. A standalone test compiles and runs a Rust hello-world program.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: twitchyliquid64

Merge Risk: ⚪ Minimal · up to bb47f

The change lets each compiler package build a simple program from its own dependency closure. No merge-blocking issue was identified, and CI should confirm the LLVM and Rust builds.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: each compiler can build a hello-world program using its own dependency closure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

bryan-minimal and others added 2 commits October 5, 2026 17:11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oss a buildbot restart)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants