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_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)
|
RT_OBJ = $(RT_S:rt/%.s=$(OBJ)/rt/%.o)
|
||||||
|
|
||||||
BINS = $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l $(BIN)/wwdump \
|
# Cstage: one-time C bootstrap (see BOOTSTRAP.md). Built by `cc`.
|
||||||
$(BIN)/wwdump_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/ww_ww
|
# 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
|
LIBS = $(LIB)/libwwc.a $(LIB)/libwwrt.a
|
||||||
|
|
||||||
all: $(BINS) $(LIBS)
|
all: cstage wwstage
|
||||||
|
|
||||||
|
cstage: $(CSTAGE_BINS) $(LIBS)
|
||||||
|
wwstage: $(WWSTAGE_BINS)
|
||||||
|
|
||||||
# ---- libwwc.a ----------------------------------------------------------
|
# ---- libwwc.a ----------------------------------------------------------
|
||||||
$(LIB)/libwwc.a: $(WWC_OBJ) | $(LIB)
|
$(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/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)"
|
@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
|
- The C `cmd/wwc/`, `cmd/6c/`, `cmd/6a/`, `cmd/6l/` C trees are
|
||||||
deleted in this phase's final commit.
|
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
|
## Phase 11 — CSP
|
||||||
|
|
||||||
Goal: channels and lightweight processes, without GC.
|
Goal: channels and lightweight processes, without GC.
|
||||||
|
|||||||
Reference in New Issue
Block a user