Ports cmd/6l/{dyn,dynout}.c into selfhost/cmd/6l/{dyn,dynout}.ww:
ET_DYN .so loading + PT_INTERP/PT_DYNAMIC ELF emission with .rela.plt,
.gnu.version_r, BIND_NOW. lsym grows dyn fields; pass.ww promotes
undefs to dyn; out.ww dispatches; main.ww takes -L/-l. The ww driver
forwards -L/-l to 6l_ww so 'ww_ww build snake.ww -L /usr/lib -l ncurses
-l c' runs without cc.
Test 996 pins byte-identical output to C-6l on snake.
'make bootstrap' gains a fourth stage with cmp ww3 == ww4, proving
ww3 is byte-stable when used as a compiler — not just a coincidental
two-stage equilibrium.
Four wwstage 6c cgen quirks surfaced and are documented in dynout.ww's
header (two-level field-write through a pointer field, (scalar, str)
tuple returns, def : str, ≤6 arg calling convention).
406 lines
16 KiB
Makefile
406 lines
16 KiB
Makefile
# ww — Plan 9-organised toolchain. POSIX make.
|
|
#
|
|
# Build a small static frontend library libwwc.a and the user-facing
|
|
# driver `ww`. Per-target tools (6c, 6a, 6l) and the runtime are added
|
|
# in their own phases. Everything lands under out/.
|
|
|
|
PREFIX ?= /usr/local
|
|
CC ?= cc
|
|
AR ?= ar
|
|
CFLAGS ?= -O0 -g -Wall -Wextra -Wpedantic -Wno-unused-parameter
|
|
CFLAGS += -std=c99 -fno-strict-aliasing -D_POSIX_C_SOURCE=200809L
|
|
INCS = -Icmd/wwc
|
|
|
|
OUT = out
|
|
BIN = $(OUT)/bin
|
|
LIB = $(OUT)/lib
|
|
OBJ = $(OUT)/obj
|
|
|
|
WWC_SRC = cmd/wwc/mem.c cmd/wwc/err.c cmd/wwc/tok.c cmd/wwc/lex.c \
|
|
cmd/wwc/ast.c cmd/wwc/parse.c cmd/wwc/sym.c cmd/wwc/type.c \
|
|
cmd/wwc/check.c
|
|
WWC_OBJ = $(WWC_SRC:cmd/wwc/%.c=$(OBJ)/wwc/%.o)
|
|
|
|
WW_SRC = cmd/ww/main.c
|
|
WW_OBJ = $(WW_SRC:cmd/ww/%.c=$(OBJ)/ww/%.o)
|
|
|
|
WD_SRC = cmd/wwdump/main.c
|
|
WD_OBJ = $(WD_SRC:cmd/wwdump/%.c=$(OBJ)/wwdump/%.o)
|
|
|
|
C6_SRC = cmd/6c/main.c cmd/6c/cgen.c cmd/6c/txt.c cmd/6c/swt.c \
|
|
cmd/6c/peep.c cmd/6c/reg.c
|
|
C6_OBJ = $(C6_SRC:cmd/6c/%.c=$(OBJ)/6c/%.o)
|
|
|
|
A6_SRC = cmd/6a/main.c cmd/6a/lex.c cmd/6a/parse.c cmd/6a/asm.c cmd/6a/obj.c
|
|
A6_OBJ = $(A6_SRC:cmd/6a/%.c=$(OBJ)/6a/%.o)
|
|
|
|
L6_SRC = cmd/6l/main.c cmd/6l/obj.c cmd/6l/sym.c cmd/6l/pass.c cmd/6l/out.c \
|
|
cmd/6l/dyn.c cmd/6l/dynout.c
|
|
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)
|
|
|
|
# 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-994).
|
|
WWSTAGE_BINS = $(BIN)/wwdump_ww $(BIN)/6c_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/ww_ww
|
|
|
|
BINS = $(CSTAGE_BINS) $(WWSTAGE_BINS)
|
|
LIBS = $(LIB)/libwwc.a $(LIB)/libwwrt.a
|
|
|
|
all: cstage wwstage
|
|
|
|
cstage: $(CSTAGE_BINS) $(LIBS)
|
|
wwstage: $(WWSTAGE_BINS)
|
|
|
|
# ---- libwwc.a ----------------------------------------------------------
|
|
$(LIB)/libwwc.a: $(WWC_OBJ) | $(LIB)
|
|
$(AR) rcs $@ $(WWC_OBJ)
|
|
|
|
$(OBJ)/wwc/%.o: cmd/wwc/%.c cmd/wwc/ww.h | $(OBJ)/wwc
|
|
$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
|
|
|
|
# ---- ww driver ---------------------------------------------------------
|
|
$(BIN)/ww: $(WW_OBJ) $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(WW_OBJ) -L$(LIB) -lwwc
|
|
|
|
$(OBJ)/ww/%.o: cmd/ww/%.c cmd/wwc/ww.h | $(OBJ)/ww
|
|
$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
|
|
|
|
# ---- wwdump (lex/AST diff anchor) --------------------------------------
|
|
$(BIN)/wwdump: $(WD_OBJ) $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(WD_OBJ) -L$(LIB) -lwwc
|
|
|
|
$(OBJ)/wwdump/%.o: cmd/wwdump/%.c cmd/wwc/ww.h | $(OBJ)/wwdump
|
|
$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
|
|
|
|
# ---- 6c amd64 compiler -------------------------------------------------
|
|
$(BIN)/6c: $(C6_OBJ) $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(C6_OBJ) -L$(LIB) -lwwc
|
|
|
|
$(OBJ)/6c/%.o: cmd/6c/%.c cmd/6c/gc.h cmd/6c/6.out.h cmd/wwc/ww.h | $(OBJ)/6c
|
|
$(CC) $(CFLAGS) $(INCS) -Icmd/6c -c -o $@ $<
|
|
|
|
# ---- 6a amd64 assembler ------------------------------------------------
|
|
$(BIN)/6a: $(A6_OBJ) | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(A6_OBJ)
|
|
|
|
$(OBJ)/6a/%.o: cmd/6a/%.c cmd/6a/a.h cmd/6c/6.out.h | $(OBJ)/6a
|
|
$(CC) $(CFLAGS) -Icmd/6a -Icmd/6c -c -o $@ $<
|
|
|
|
# ---- 6l amd64 linker ---------------------------------------------------
|
|
$(BIN)/6l: $(L6_OBJ) | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(L6_OBJ)
|
|
|
|
$(OBJ)/6l/%.o: cmd/6l/%.c cmd/6l/l.h | $(OBJ)/6l
|
|
$(CC) $(CFLAGS) -Icmd/6l -c -o $@ $<
|
|
|
|
# ---- ww-side wwdump (the lexer port, exercised by 990_selfhost) --------
|
|
# Built via the user-facing ww driver, with -I selfhost/cmd/wwc so it
|
|
# can find the lex/tok/mem ports. Output named wwdump_ww to avoid
|
|
# colliding with the C-side wwdump in $(BIN).
|
|
$(BIN)/wwdump_ww: selfhost/cmd/wwdump/main.ww \
|
|
selfhost/cmd/wwc/lex.ww selfhost/cmd/wwc/tok.ww \
|
|
selfhost/cmd/wwc/mem.ww selfhost/cmd/wwc/ast.ww \
|
|
selfhost/cmd/wwc/parse.ww selfhost/cmd/wwc/typ.ww \
|
|
selfhost/cmd/wwc/sym.ww selfhost/cmd/wwc/check.ww \
|
|
selfhost/cmd/wwc/cgen.ww \
|
|
$(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
cd $(BIN) && ./ww build -I $$PWD/../../selfhost/cmd/wwc \
|
|
$$PWD/../../selfhost/cmd/wwdump/main.ww
|
|
mv $(BIN)/main $@
|
|
|
|
# ---- ww-side 6c (compiler port, exercised by 994_6c_ww) ----------------
|
|
# Thin driver: parse + cgen, both already living in selfhost/cmd/wwc.
|
|
# Build through `ww build` like the other wwstage tools.
|
|
$(BIN)/6c_ww: selfhost/cmd/6c/main.ww \
|
|
selfhost/cmd/wwc/lex.ww selfhost/cmd/wwc/tok.ww \
|
|
selfhost/cmd/wwc/mem.ww selfhost/cmd/wwc/ast.ww \
|
|
selfhost/cmd/wwc/parse.ww selfhost/cmd/wwc/typ.ww \
|
|
selfhost/cmd/wwc/sym.ww selfhost/cmd/wwc/check.ww \
|
|
selfhost/cmd/wwc/cgen.ww \
|
|
$(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
cd $(BIN) && ./ww build -I $$PWD/../../selfhost/cmd/wwc \
|
|
$$PWD/../../selfhost/cmd/6c/main.ww
|
|
mv $(BIN)/main $@
|
|
|
|
# ---- ww-side 6a (assembler port, exercised by 991_6a_ww) ---------------
|
|
# Built like wwdump_ww. Needs -I selfhost/cmd/6a for the local types/lex/
|
|
# parse/asm/obj modules and -I selfhost/cmd/wwc to find `mem`.
|
|
$(BIN)/6a_ww: selfhost/cmd/6a/main.ww selfhost/cmd/6a/types.ww \
|
|
selfhost/cmd/6a/lex.ww selfhost/cmd/6a/parse.ww \
|
|
selfhost/cmd/6a/asm.ww selfhost/cmd/6a/obj.ww \
|
|
selfhost/cmd/wwc/mem.ww \
|
|
$(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
cd $(BIN) && ./ww build \
|
|
-I $$PWD/../../selfhost/cmd/6a \
|
|
-I $$PWD/../../selfhost/cmd/wwc \
|
|
$$PWD/../../selfhost/cmd/6a/main.ww
|
|
mv $(BIN)/main $@
|
|
|
|
# ---- ww-side 6l (linker port, exercised by 992_6l_ww) ------------------
|
|
# Built like 6a_ww. Needs -I selfhost/cmd/6l for the local sym/obj/pass/
|
|
# out modules and -I selfhost/cmd/wwc to find `mem`.
|
|
$(BIN)/6l_ww: selfhost/cmd/6l/main.ww selfhost/cmd/6l/sym.ww \
|
|
selfhost/cmd/6l/obj.ww selfhost/cmd/6l/dyn.ww \
|
|
selfhost/cmd/6l/pass.ww selfhost/cmd/6l/dynout.ww \
|
|
selfhost/cmd/6l/out.ww selfhost/cmd/wwc/mem.ww \
|
|
$(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
cd $(BIN) && ./ww build \
|
|
-I $$PWD/../../selfhost/cmd/6l \
|
|
-I $$PWD/../../selfhost/cmd/wwc \
|
|
$$PWD/../../selfhost/cmd/6l/main.ww
|
|
mv $(BIN)/main $@
|
|
|
|
# ---- ww-side ww driver (exercised by 993_ww_ww) ------------------------
|
|
# The driver pulls in lib/os (default search path) and selfhost/cmd/wwc
|
|
# (for the bump arena). It then orchestrates 6c/6a/6l like the C driver.
|
|
$(BIN)/ww_ww: selfhost/cmd/ww/main.ww selfhost/cmd/wwc/mem.ww lib/os/os.ww \
|
|
$(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
cd $(BIN) && ./ww build \
|
|
-I $$PWD/../../selfhost/cmd/wwc \
|
|
$$PWD/../../selfhost/cmd/ww/main.ww
|
|
mv $(BIN)/main $@
|
|
|
|
# ---- runtime (libwwrt.a, assembled by our own 6a) ----------------------
|
|
$(OBJ)/rt/%.o: rt/%.s $(BIN)/6a | $(OBJ)/rt
|
|
$(BIN)/6a -o $@ $<
|
|
|
|
$(LIB)/libwwrt.a: $(RT_OBJ) | $(LIB)
|
|
$(AR) rcs $@ $(RT_OBJ)
|
|
|
|
# ---- directories -------------------------------------------------------
|
|
$(BIN) $(LIB) $(OBJ)/wwc $(OBJ)/ww $(OBJ)/wwdump $(OBJ)/6c $(OBJ)/6a $(OBJ)/6l $(OBJ)/rt:
|
|
mkdir -p $@
|
|
|
|
# ---- tests -------------------------------------------------------------
|
|
# Each phase adds a $(BIN)/test_<name> target; the runner walks them.
|
|
TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
|
$(BIN)/test_6c $(BIN)/test_6a $(BIN)/test_6l $(BIN)/test_arch \
|
|
$(BIN)/test_e2e $(BIN)/test_ffi $(BIN)/test_dyn $(BIN)/test_stdlib \
|
|
$(BIN)/test_selfhost $(BIN)/test_6a_ww $(BIN)/test_6l_ww \
|
|
$(BIN)/test_6c_ww $(BIN)/test_ww_ww $(BIN)/test_self_rebuild \
|
|
$(BIN)/test_dyn_ww
|
|
|
|
$(BIN)/test_smoke: test/wwc/000_smoke.c $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -o $@ $< -L$(LIB) -lwwc
|
|
|
|
$(BIN)/test_lex: test/wwc/100_lex.c $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -o $@ $< -L$(LIB) -lwwc
|
|
|
|
$(BIN)/test_parse: test/wwc/200_parse.c $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -o $@ $< -L$(LIB) -lwwc
|
|
|
|
$(BIN)/test_check: test/wwc/300_check.c $(LIB)/libwwc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -o $@ $< -L$(LIB) -lwwc
|
|
|
|
$(BIN)/test_6c: test/wwc/400_6c.c $(BIN)/6c | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_6a: test/wwc/500_6a.c $(BIN)/6c $(BIN)/6a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_6l: test/wwc/600_6l.c $(BIN)/6c $(BIN)/6a $(BIN)/6l | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_arch: test/wwc/610_arch.c $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(OBJ)/rt/start.o | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_e2e: test/wwc/700_e2e.c $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a $(OBJ)/rt/start.o | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_ffi: test/wwc/800_ffi.c $(BIN)/6c | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_dyn: test/wwc/810_dyn.c $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_stdlib: test/wwc/900_stdlib.c $(BIN)/6c | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_selfhost: test/wwc/990_selfhost.c $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
|
$(BIN)/ww $(BIN)/wwdump $(BIN)/wwdump_ww $(LIB)/libwwrt.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_6a_ww: test/wwc/991_6a_ww.c $(BIN)/6a $(BIN)/6a_ww | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_6l_ww: test/wwc/992_6l_ww.c $(BIN)/6l $(BIN)/6l_ww \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_6c_ww: test/wwc/994_6c_ww.c $(BIN)/6c_ww $(BIN)/wwdump_ww | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_ww_ww: test/wwc/993_ww_ww.c $(BIN)/ww $(BIN)/ww_ww \
|
|
$(BIN)/6c $(BIN)/6a $(BIN)/6l $(LIB)/libwwrt.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_self_rebuild: test/wwc/995_self_rebuild.c $(BIN)/ww_ww \
|
|
$(BIN)/6c_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/wwdump_ww \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
$(BIN)/test_dyn_ww: test/wwc/996_dyn_ww.c $(BIN)/ww $(BIN)/6l $(BIN)/6l_ww \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $<
|
|
|
|
test: all $(TESTS)
|
|
@WW=$(BIN)/ww BIN=$(BIN) sh test/run
|
|
|
|
install: all
|
|
mkdir -p $(PREFIX)/bin $(PREFIX)/lib
|
|
cp $(BIN)/ww $(PREFIX)/bin/
|
|
cp $(LIB)/libwwc.a $(PREFIX)/lib/
|
|
|
|
clean:
|
|
rm -rf $(OUT)
|
|
|
|
# ---- bootstrap (phase 10) ----------------------------------------------
|
|
# Four-stage self-host: Cstage (these C tools) → ww1 → ww2 → ww3 → ww4
|
|
# with cmp ww2 == ww3 and cmp ww3 == ww4. Stage 1 is wwdump_ww (the
|
|
# ww-built frontend); stages 2/3/4 assemble with 6a_ww and link with
|
|
# 6l_ww — every tool below the driver is now in ww. The C `ww` driver
|
|
# still orchestrates the pipeline (porting it is the remaining phase-10
|
|
# work).
|
|
#
|
|
# Why a fourth stage? Stage 3 proves ww1 and ww2 (which differ in how
|
|
# they were built) emit the same machine code. Stage 4 proves ww3 is
|
|
# byte-stable when used as a compiler — i.e. the fixed point is truly
|
|
# fixed, not merely a coincidental two-stage equilibrium.
|
|
BS = $(OUT)/bootstrap
|
|
bootstrap: all
|
|
@echo "=== stage 0 (Cstage): C-built tools ==="
|
|
@echo " $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l"
|
|
@echo
|
|
@echo "=== stage 1: ww-built tools, used to drive stages 2/3/4 ==="
|
|
@ls -l $(BIN)/wwdump_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/ww_ww
|
|
@rm -rf $(BS) && mkdir -p $(BS)
|
|
@echo
|
|
@echo "=== stage 2: ww2 = ww1 self-compiles main.combined.ww ==="
|
|
@$(BIN)/wwdump_ww -c selfhost/cmd/wwdump/main.combined.ww > $(BS)/ww2.s
|
|
@$(BIN)/6a_ww -o $(BS)/ww2.o $(BS)/ww2.s
|
|
@$(BIN)/6l_ww -o $(BS)/ww2 $(BS)/ww2.o $(LIB)/libwwrt.a
|
|
@ls -l $(BS)/ww2
|
|
@echo
|
|
@echo "=== stage 3: ww3 = ww2 self-compiles main.combined.ww ==="
|
|
@$(BS)/ww2 -c selfhost/cmd/wwdump/main.combined.ww > $(BS)/ww3.s
|
|
@$(BIN)/6a_ww -o $(BS)/ww3.o $(BS)/ww3.s
|
|
@$(BIN)/6l_ww -o $(BS)/ww3 $(BS)/ww3.o $(LIB)/libwwrt.a
|
|
@ls -l $(BS)/ww3
|
|
@echo
|
|
@echo "=== stage 4: ww4 = ww3 self-compiles main.combined.ww ==="
|
|
@$(BS)/ww3 -c selfhost/cmd/wwdump/main.combined.ww > $(BS)/ww4.s
|
|
@$(BIN)/6a_ww -o $(BS)/ww4.o $(BS)/ww4.s
|
|
@$(BIN)/6l_ww -o $(BS)/ww4 $(BS)/ww4.o $(LIB)/libwwrt.a
|
|
@ls -l $(BS)/ww4
|
|
@echo
|
|
@echo "=== fixed-point gates ==="
|
|
@cmp $(BS)/ww2.s $(BS)/ww3.s && echo " ww2.s == ww3.s ✓"
|
|
@cmp $(BS)/ww2.o $(BS)/ww3.o && echo " ww2.o == ww3.o ✓ (byte-identical .o)"
|
|
@cmp $(BS)/ww2 $(BS)/ww3 && echo " ww2 == ww3 ✓ (byte-identical exe)"
|
|
@cmp $(BS)/ww3.s $(BS)/ww4.s && echo " ww3.s == ww4.s ✓"
|
|
@cmp $(BS)/ww3.o $(BS)/ww4.o && echo " ww3.o == ww4.o ✓ (byte-identical .o)"
|
|
@cmp $(BS)/ww3 $(BS)/ww4 && echo " ww3 == ww4 ✓ (byte-identical exe, ww3 is byte-stable as a compiler)"
|
|
@echo
|
|
@echo "BOOTSTRAP OK: ww-cgen + 6a_ww + 6l_ww reach a fixed point that holds across two iterations."
|
|
@echo
|
|
@echo "Phase 10 remaining work:"
|
|
@echo " - delete cmd/wwc/ cmd/6c/ cmd/6a/ cmd/6l/ cmd/ww/ in the final commit"
|
|
@echo
|
|
@echo "Already in selfhost/:"
|
|
@echo " - cmd/wwc/ : ww-cgen (lex/parse/check/cgen) — bootstrap fixed point"
|
|
@echo " - cmd/6c/ : ww-6c (lex/parse/cgen front-end) — matches wwdump_ww -c (test 994)"
|
|
@echo " - cmd/6a/ : ww-6a (lex/parse/asm/obj) — byte-identical to C 6a (test 991)"
|
|
@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)"
|
|
|
|
# ---- nocc: bootstrap from a checked-in stage-0 binary, no cc -----------
|
|
# A fresh-checkout flow that never invokes cc. Mirrors `make bootstrap`'s
|
|
# fixed-point check but uses `bootstrap/$(ARCH)/{ww,6c,6a,6l}` as the
|
|
# starting point and lands in $(OUT)/nocc/ so the cstage build under
|
|
# $(OUT)/ stays untouched. See bootstrap/README.md and BOOTSTRAP.md.
|
|
#
|
|
# `make bootstrap-snapshot` populates bootstrap/$(ARCH)/ from the
|
|
# currently-built wwstage so you can verify locally before deciding
|
|
# to commit the binaries.
|
|
ARCH ?= amd64
|
|
STAGE0 = bootstrap/$(ARCH)
|
|
NOCC_OUT = $(OUT)/nocc
|
|
NOCC_BIN = $(NOCC_OUT)/bin
|
|
NOCC_LIB = $(NOCC_OUT)/lib
|
|
NOCC_OBJ = $(NOCC_OUT)/obj
|
|
|
|
bootstrap-snapshot: wwstage
|
|
@mkdir -p $(STAGE0)
|
|
@cp $(BIN)/ww_ww $(STAGE0)/ww
|
|
@cp $(BIN)/6c_ww $(STAGE0)/6c
|
|
@cp $(BIN)/6a_ww $(STAGE0)/6a
|
|
@cp $(BIN)/6l_ww $(STAGE0)/6l
|
|
@echo "snapshot: $(STAGE0)/{ww,6c,6a,6l} populated from $(BIN)/*_ww"
|
|
@echo " (gitignored — 'git add -f bootstrap/$(ARCH)/*' to ship)"
|
|
|
|
nocc:
|
|
@for f in ww 6c 6a 6l; do \
|
|
test -x $(STAGE0)/$$f || { \
|
|
echo "$@: missing $(STAGE0)/$$f"; \
|
|
echo "$@: run 'make bootstrap-snapshot' first, or read bootstrap/README.md"; \
|
|
exit 1; \
|
|
}; \
|
|
done
|
|
@echo "=== nocc: starting from $(STAGE0) (no cc invoked) ==="
|
|
@rm -rf $(NOCC_OUT)
|
|
@mkdir -p $(NOCC_BIN) $(NOCC_LIB) $(NOCC_OBJ)
|
|
@# Stage 0: drop bootstrap binaries under both natural names and
|
|
@# the _ww-suffixed names the driver expects when shelling out.
|
|
@for f in ww 6c 6a 6l; do \
|
|
cp $(STAGE0)/$$f $(NOCC_BIN)/$$f; \
|
|
cp $(STAGE0)/$$f $(NOCC_BIN)/$${f}_ww; \
|
|
done
|
|
@# Assemble libwwrt.a using stage-0 6a — the linker needs it for
|
|
@# every wwstage-built binary in the next stage. Member order
|
|
@# follows $(RT_S) so the embedded symbol table matches the
|
|
@# cstage-built libwwrt.a (cstage uses ar rcs $(RT_OBJ), same
|
|
@# order).
|
|
@objs=""; for s in $(RT_S); do \
|
|
b=`basename $$s .s`; \
|
|
$(NOCC_BIN)/6a -o $(NOCC_OBJ)/$$b.o $$s; \
|
|
objs="$$objs $(NOCC_OBJ)/$$b.o"; \
|
|
done; $(AR) rcs $(NOCC_LIB)/libwwrt.a $$objs
|
|
@echo "=== stage 1: stage-0 rebuilds the wwstage tools from source ==="
|
|
@# The driver's default lib path is $self_dir/../../lib — under
|
|
@# $(NOCC_BIN) that resolves to $(NOCC_OUT)/lib (libwwrt only).
|
|
@# Pass -I $(CURDIR)/lib so `use os` etc. resolve to source.
|
|
@cd $(NOCC_BIN) && ./ww build -I $(CURDIR)/selfhost/cmd/wwc \
|
|
-I $(CURDIR)/lib $(CURDIR)/selfhost/cmd/6c/main.ww && mv main 6c_ww1
|
|
@cd $(NOCC_BIN) && ./ww build -I $(CURDIR)/selfhost/cmd/6a \
|
|
-I $(CURDIR)/selfhost/cmd/wwc -I $(CURDIR)/lib \
|
|
$(CURDIR)/selfhost/cmd/6a/main.ww && mv main 6a_ww1
|
|
@cd $(NOCC_BIN) && ./ww build -I $(CURDIR)/selfhost/cmd/6l \
|
|
-I $(CURDIR)/selfhost/cmd/wwc -I $(CURDIR)/lib \
|
|
$(CURDIR)/selfhost/cmd/6l/main.ww && mv main 6l_ww1
|
|
@cd $(NOCC_BIN) && ./ww build -I $(CURDIR)/selfhost/cmd/wwc \
|
|
-I $(CURDIR)/lib $(CURDIR)/selfhost/cmd/ww/main.ww && mv main ww_ww1
|
|
@echo "=== fixed-point gates: rebuilt tools == stage-0 binaries? ==="
|
|
@cmp $(NOCC_BIN)/6c_ww1 $(STAGE0)/6c && echo " 6c ✓"
|
|
@cmp $(NOCC_BIN)/6a_ww1 $(STAGE0)/6a && echo " 6a ✓"
|
|
@cmp $(NOCC_BIN)/6l_ww1 $(STAGE0)/6l && echo " 6l ✓"
|
|
@cmp $(NOCC_BIN)/ww_ww1 $(STAGE0)/ww && echo " ww ✓"
|
|
@echo
|
|
@echo "NOCC OK: $(STAGE0)/* reproduces itself from source. cc not invoked."
|
|
|
|
.PHONY: all cstage wwstage test install clean bootstrap nocc bootstrap-snapshot
|