Files
ww/BOOTSTRAP.md

97 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BOOTSTRAP
How `ww` builds itself.
`ww` is self-hosted: the ww-side compiler/assembler/linker/driver live
under `selfhost/cmd/` and reach a byte-identical fixed point under
`make bootstrap`. But the *first* ww binary on a fresh checkout has to
come from somewhere. Today, that "somewhere" is a small C bootstrap
toolchain — the **Cstage**:
cmd/wcc/ frontend library (lex, parse, check) → libwcc.a
cmd/w6c/ amd64 compiler .ww → .s
cmd/w6a/ amd64 assembler .s → .o
cmd/w6l/ amd64 linker .o → static ELF
cmd/ww/ user-facing driver (orchestrates w6c → w6a → w6l)
Cstage is built with `cc`. Once it exists, it compiles the
ww-rewritten tools (the **wwstage**) under `selfhost/cmd/`, which then
self-compile to a byte-identical fixed point. After that, no C is
involved.
## Build flow
cstage (cc → C tools, one-time)
├──→ ww1 wwstage tools, built by Cstage
│ │
│ └──→ ww2 wwstage self-compiles
│ │
│ └──→ ww3 ww2 self-compiles
│ │
│ ↓
│ cmp ww2 ww3 → fixed point ✓
└ from here on, no C is invoked
## Make targets
make builds cstage + wwstage + libs
make cstage Cstage only (cc → ww, w6c, w6a, w6l, wwdump, libs)
make wwstage wwstage only (assumes cstage)
make bootstrap three-stage build; gates on cmp ww2 == ww3
make test runs all tests, including 990995 (ww-side
tools vs C-side tools, byte-for-byte, plus
the wwstage rebuilding itself in 995)
Without cc:
make bootstrap-snapshot populate bootstrap/$(ARCH)/ from the
currently-built wwstage (gitignored
by default)
make nocc cold-start from bootstrap/$(ARCH)/,
rebuild the wwstage from source, gate
on `stage-0 == rebuilt` byte-for-byte.
cc is never invoked.
## Status
Phase 10 of `PLAN.md` is at its first exit criterion: the bootstrap is
green and `selfhost/cmd/{wcc,w6c,w6a,w6l,ww}` are byte-identical to their
Cstage counterparts. Test 995 pins the stronger property — the
wwstage rebuilds every one of its own tools through `ww_ww + w6c_ww +
w6a_ww + w6l_ww`, byte-for-byte. Test 996 pins the equivalent for the
dynamic linker: `w6l_ww` with `-L`/`-l` produces a byte-identical
PT_INTERP+PT_DYNAMIC binary to C-side `w6l`.
`make nocc` is wired and verifies stage-0 self-reproduction locally;
the stage-0 binaries under `bootstrap/$(ARCH)/` are gitignored until
ready to commit. The second exit criterion — deleting the C trees —
is **still deferred to v1.0**: shipping the stage-0 binaries is a
one-way door (they become the project's new trust surface), and the
compiler is still churning. A `git clone` today still requires `cc`
unless the local working copy has already done `make
bootstrap-snapshot` once.
## What "no C" looks like
The pieces are already wired; only the binary commit is held back.
When the compiler stabilises:
1. On each supported arch, run `make wwstage && make bootstrap-snapshot`
to populate `bootstrap/<arch>/{ww,w6c,w6a,w6l}` from the current
wwstage. Verify with `make nocc`.
2. `git add -f bootstrap/<arch>/{ww,w6c,w6a,w6l}` — explicit because
the dir is gitignored. The binary SHAs become the new trust
surface.
3. Delete `cmd/wcc/`, `cmd/w6c/`, `cmd/w6a/`, `cmd/w6l/`, `cmd/ww/`.
Drop `CC`/`AR` C-tool dependencies from the top-level Makefile.
4. Move `selfhost/cmd/*` to `cmd/*` and `make nocc` becomes the
default `make`.
5. Build path: stage-0 binary → ww1 → ww2 → fixed point, same as
today, just without `cc`.
This is the standard self-hosting story (Go, Rust, OCaml all do
variants of it). The bootstrap binaries become the new "trusting
trust" surface.