build: split cstage/wwstage targets, document bootstrap
Phase 10 step 8 (delete the C trees) is deferred to v1.0 — until the compiler stops churning we keep Cstage as the fresh-checkout entry point. Split the Makefile so the two stages are named, and add BOOTSTRAP.md describing the cstage → ww1 → ww2 → ww3 fixed-point flow. PLAN.md gets a status note pointing at it.
This commit is contained in:
70
BOOTSTRAP.md
Normal file
70
BOOTSTRAP.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 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/wwc/ frontend library (lex, parse, check) → libwwc.a
|
||||
cmd/6c/ amd64 compiler .ww → .s
|
||||
cmd/6a/ amd64 assembler .s → .o
|
||||
cmd/6l/ amd64 linker .o → static ELF
|
||||
cmd/ww/ user-facing driver (orchestrates 6c → 6a → 6l)
|
||||
|
||||
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, 6c, 6a, 6l, wwdump, libs)
|
||||
make wwstage wwstage only (assumes cstage)
|
||||
make bootstrap three-stage build; gates on cmp ww2 == ww3
|
||||
make test runs all tests, including the 990–993 diffs
|
||||
(ww-side tools vs C-side tools, byte-for-byte)
|
||||
|
||||
## Status
|
||||
|
||||
Phase 10 of `PLAN.md` is at its first exit criterion: the bootstrap is
|
||||
green and `selfhost/cmd/{wwc,6a,6l,ww}` are byte-identical to their
|
||||
Cstage counterparts. The second exit criterion — deleting the C trees
|
||||
— is **deferred to v1.0**: until the compiler stops churning, the
|
||||
Cstage stays as the fresh-checkout entry point. A `git clone` today
|
||||
still requires `cc`.
|
||||
|
||||
## What "no C" looks like
|
||||
|
||||
When the compiler stabilises:
|
||||
|
||||
1. Cross-compile or natively build a known-good wwstage on each
|
||||
supported arch.
|
||||
2. Ship those binaries under `bootstrap/<arch>/{ww,6c,6a,6l}` in the
|
||||
tree. They are the new stage 0.
|
||||
3. Delete `cmd/wwc/`, `cmd/6c/`, `cmd/6a/`, `cmd/6l/`, `cmd/ww/`.
|
||||
4. Move `selfhost/cmd/*` to `cmd/*`.
|
||||
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.
|
||||
19
Makefile
19
Makefile
@@ -40,11 +40,22 @@ L6_OBJ = $(L6_SRC:cmd/6l/%.c=$(OBJ)/6l/%.o)
|
||||
RT_S = rt/start.s rt/syscall.s rt/alloc.s rt/streq.s rt/abort.s
|
||||
RT_OBJ = $(RT_S:rt/%.s=$(OBJ)/rt/%.o)
|
||||
|
||||
BINS = $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l $(BIN)/wwdump \
|
||||
$(BIN)/wwdump_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/ww_ww
|
||||
# Cstage: one-time C bootstrap (see BOOTSTRAP.md). Built by `cc`.
|
||||
# Goes away at v1.0, replaced by a checked-in stage-0 binary.
|
||||
CSTAGE_BINS = $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l $(BIN)/wwdump
|
||||
|
||||
# Wwstage: ww-rewritten toolchain. Built by Cstage today; will be the
|
||||
# only toolchain after Phase 10 closeout. Byte-identical to Cstage
|
||||
# (tests 990-993).
|
||||
WWSTAGE_BINS = $(BIN)/wwdump_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/ww_ww
|
||||
|
||||
BINS = $(CSTAGE_BINS) $(WWSTAGE_BINS)
|
||||
LIBS = $(LIB)/libwwc.a $(LIB)/libwwrt.a
|
||||
|
||||
all: $(BINS) $(LIBS)
|
||||
all: cstage wwstage
|
||||
|
||||
cstage: $(CSTAGE_BINS) $(LIBS)
|
||||
wwstage: $(WWSTAGE_BINS)
|
||||
|
||||
# ---- libwwc.a ----------------------------------------------------------
|
||||
$(LIB)/libwwc.a: $(WWC_OBJ) | $(LIB)
|
||||
@@ -266,4 +277,4 @@ bootstrap: all
|
||||
@echo " - cmd/6l/ : ww-6l (linker w/ archive support) — byte-identical to C 6l (test 992)"
|
||||
@echo " - cmd/ww/ : ww-driver (build/run/version) — byte-identical to C ww (test 993)"
|
||||
|
||||
.PHONY: all test install clean bootstrap
|
||||
.PHONY: all cstage wwstage test install clean bootstrap
|
||||
|
||||
25
PLAN.md
25
PLAN.md
@@ -291,6 +291,31 @@ Exit criteria:
|
||||
- The C `cmd/wwc/`, `cmd/6c/`, `cmd/6a/`, `cmd/6l/` C trees are
|
||||
deleted in this phase's final commit.
|
||||
|
||||
### Status (2026-05)
|
||||
|
||||
Steps 1–6 done. The four ww-side tools live in `selfhost/cmd/`:
|
||||
|
||||
- `wwc/` — ww-native lex/parse/check/cgen
|
||||
- `6a/` — ww-native amd64 assembler
|
||||
- `6l/` — ww-native amd64 linker
|
||||
- `ww/` — ww-native driver
|
||||
|
||||
Step 7 reaches its fixed point: `make bootstrap` produces ww1 → ww2 →
|
||||
ww3 with `cmp ww2 ww3` byte-identical. Tests 990–993 confirm each
|
||||
selfhost tool is byte-identical to its Cstage counterpart.
|
||||
|
||||
Exit criterion 1 (bootstrap green) is met. Exit criterion 2 (delete
|
||||
the C trees) is **deferred to v1.0**: removing `cmd/wwc/`, `cmd/6c/`,
|
||||
`cmd/6a/`, `cmd/6l/`, `cmd/ww/` is a one-way door. Until the compiler
|
||||
stops churning we keep Cstage as the canonical fresh-checkout entry
|
||||
point and treat `selfhost/cmd/*` as the path forward. At v1.0, the
|
||||
plan is to ship a checked-in stage-0 binary archive
|
||||
(`bootstrap/<arch>/{ww,6c,6a,6l}`), delete the C trees, and promote
|
||||
`selfhost/cmd/*` to `cmd/*`.
|
||||
|
||||
See `BOOTSTRAP.md` for the build flow and `make cstage`/`make wwstage`
|
||||
targets.
|
||||
|
||||
## Phase 11 — CSP
|
||||
|
||||
Goal: channels and lightweight processes, without GC.
|
||||
|
||||
Reference in New Issue
Block a user