993 lines
44 KiB
Makefile
993 lines
44 KiB
Makefile
# ww — Plan 9-organised toolchain. POSIX make.
|
|
#
|
|
# Build a small static frontend library libwcc.a and the user-facing
|
|
# driver `ww`. Per-target tools (w6c, w6a, w6l) and the runtime are added
|
|
# in their own phases. Everything lands under out/.
|
|
|
|
PREFIX ?= /usr/local
|
|
CC ?= cc
|
|
AR ?= ar
|
|
|
|
# Fixture-cell concurrency is separate from caller-owned Make scheduling.
|
|
JOBS ?= 1
|
|
|
|
# Wrap the C compiler with ccache when present — content-addressed, so
|
|
# byte-identical to plain cc; just skips recompiling unchanged TUs.
|
|
# Falls back cleanly to bare $(CC) when ccache is absent. A command-line
|
|
# CC= override wins and is left unwrapped.
|
|
CC := $(shell command -v ccache >/dev/null 2>&1 && echo "ccache $(CC)" || echo "$(CC)")
|
|
CFLAGS ?= -O0 -g -Wall -Wextra -Wpedantic -Wno-unused-parameter
|
|
CFLAGS += -std=c99 -fno-strict-aliasing -D_POSIX_C_SOURCE=200809L
|
|
INCS = -Icmd/wcc
|
|
|
|
OUT = out
|
|
BIN = $(OUT)/bin
|
|
LIB = $(OUT)/lib
|
|
OBJ = $(OUT)/obj
|
|
|
|
WCC_SRC = cmd/wcc/mem.c cmd/wcc/err.c cmd/wcc/tok.c cmd/wcc/lex.c \
|
|
cmd/wcc/ast.c cmd/wcc/parse.c cmd/wcc/sym.c cmd/wcc/type.c \
|
|
cmd/wcc/check.c
|
|
WCC_OBJ = $(WCC_SRC:cmd/wcc/%.c=$(OBJ)/wcc/%.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)
|
|
|
|
W6C_SRC = cmd/w6c/main.c cmd/w6c/cgen.c cmd/w6c/txt.c cmd/w6c/swt.c \
|
|
cmd/w6c/peep.c cmd/w6c/reg.c cmd/w6c/wwi.c
|
|
W6C_OBJ = $(W6C_SRC:cmd/w6c/%.c=$(OBJ)/w6c/%.o)
|
|
|
|
W6A_SRC = cmd/w6a/main.c cmd/w6a/lex.c cmd/w6a/parse.c cmd/w6a/asm.c cmd/w6a/obj.c
|
|
W6A_OBJ = $(W6A_SRC:cmd/w6a/%.c=$(OBJ)/w6a/%.o)
|
|
|
|
W6L_SRC = cmd/w6l/main.c cmd/w6l/obj.c cmd/w6l/sym.c cmd/w6l/pass.c cmd/w6l/out.c \
|
|
cmd/w6l/dyn.c cmd/w6l/dynout.c
|
|
W6L_OBJ = $(W6L_SRC:cmd/w6l/%.c=$(OBJ)/w6l/%.o)
|
|
|
|
RT_S = rt/start.s rt/syscall.s rt/alloc.s rt/streq.s rt/abort.s
|
|
RT_WW = rt/ensure.ww rt/malloc.ww
|
|
RT_OBJ = $(RT_S:rt/%.s=$(OBJ)/rt/%.o) $(RT_WW:rt/%.ww=$(OBJ)/rt/%.o)
|
|
|
|
WWTEST_BIN = $(BIN)/wwtest
|
|
WWTEST_SRC = cmd/wwtest/wwtest.ww \
|
|
internal/wwpackage/package.ww lib/os/exec/exec.ww \
|
|
lib/ascii/ascii.ww lib/bytes/bytes.ww \
|
|
lib/encoding/utf8/utf8.ww lib/math/floats.ww lib/math/math.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww \
|
|
lib/strconv/decimal.ww lib/strconv/ftos.ww lib/strconv/ftos_data.ww \
|
|
lib/strconv/stof.ww lib/strconv/stof_data.ww lib/strconv/strconv.ww \
|
|
lib/strings/strings.ww lib/temp/temp.ww lib/time/time.ww \
|
|
lib/types/types.ww
|
|
|
|
WWFIXTURE_BIN = $(BIN)/wwfixture
|
|
WWFIXTURE_SRC = cmd/wwfixture/wwfixture.ww \
|
|
internal/wwfixture/command.ww internal/wwfixture/corpus.ww \
|
|
internal/wwfixture/protocol.ww internal/wwfixture/run.ww \
|
|
internal/wwfixture/types.ww lib/os/exec/exec.ww \
|
|
lib/ascii/ascii.ww lib/bytes/bytes.ww \
|
|
lib/crypto/math/math.ww lib/crypto/sha256/sha256.ww \
|
|
lib/encoding/hex/hex.ww lib/encoding/utf8/utf8.ww \
|
|
lib/endian/endian.ww lib/errors/errors.ww lib/fmt/fmt.ww \
|
|
lib/fnmatch/fnmatch.ww lib/hash/hash.ww \
|
|
lib/io/io.ww lib/io/stream.ww lib/io/types.ww \
|
|
lib/math/floats.ww lib/math/math.ww lib/memio/memio.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww \
|
|
lib/strconv/decimal.ww lib/strconv/ftos.ww \
|
|
lib/strconv/ftos_data.ww lib/strconv/stof.ww \
|
|
lib/strconv/stof_data.ww lib/strconv/strconv.ww \
|
|
lib/strings/strings.ww lib/temp/temp.ww lib/time/time.ww \
|
|
lib/types/types.ww
|
|
|
|
WWFIXTURE_BUILD_TOOLS = $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a
|
|
WWFIXTURE_TOOLS = $(WWFIXTURE_BUILD_TOOLS) $(BIN)/w6c_ww \
|
|
$(BIN)/w6a_ww $(BIN)/w6l_ww $(BIN)/ww_ww
|
|
|
|
EXEC_TEST_SRC = test/wwfixture/process/main.ww \
|
|
lib/os/exec/exec.ww lib/os/os.ww lib/rt/malloc.ww \
|
|
lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww \
|
|
lib/strings/strings.ww lib/temp/temp.ww lib/time/time.ww \
|
|
lib/types/types.ww
|
|
EXEC_TEST_C = $(BIN)/test_exec
|
|
EXEC_TEST_WW = $(BIN)/test_exec_ww
|
|
|
|
PACKAGE_TEST_BIN = $(BIN)/test_package
|
|
PACKAGE_TEST_SRC = test/package/package_test.ww lib/os/exec/exec.ww \
|
|
lib/test/run.ww lib/fnmatch/fnmatch.ww \
|
|
lib/ascii/ascii.ww lib/bytes/bytes.ww \
|
|
lib/encoding/utf8/utf8.ww lib/os/os.ww lib/rt/malloc.ww \
|
|
lib/strings/strings.ww lib/temp/temp.ww lib/time/time.ww \
|
|
lib/types/types.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)/w6c $(BIN)/w6a $(BIN)/w6l $(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)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww $(BIN)/ww_ww
|
|
|
|
# Driver-produced binaries build in persistent per-target `ww build -w`
|
|
# workdirs: package artifacts are reused across rebuilds on exact content
|
|
# identity (see docs/test-system-v2.md), and the finished binary is
|
|
# published into $(BIN) by one atomic mv. One workdir per target keeps
|
|
# `make -jN` recipe concurrency race-free. test-incremental proves the
|
|
# reuse path byte-identical to a from-scratch build.
|
|
WWBUILD = $(OUT)/wwbuild
|
|
|
|
BINS = $(CSTAGE_BINS) $(WWSTAGE_BINS) $(WWTEST_BIN)
|
|
LIBS = $(LIB)/libwcc.a $(LIB)/libwwrt.a
|
|
|
|
all: cstage wwstage $(WWTEST_BIN)
|
|
|
|
cstage: $(CSTAGE_BINS) $(LIBS)
|
|
wwstage: $(WWSTAGE_BINS)
|
|
|
|
# ---- libwcc.a ----------------------------------------------------------
|
|
$(LIB)/libwcc.a: $(WCC_OBJ) | $(LIB)
|
|
$(AR) rcs $@ $(WCC_OBJ)
|
|
|
|
$(OBJ)/wcc/%.o: cmd/wcc/%.c cmd/wcc/ww.h | $(OBJ)/wcc
|
|
$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
|
|
|
|
# ---- ww driver ---------------------------------------------------------
|
|
$(BIN)/ww: $(WW_OBJ) $(LIB)/libwcc.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(WW_OBJ) -L$(LIB) -lwcc
|
|
|
|
$(OBJ)/ww/%.o: cmd/ww/%.c cmd/wcc/ww.h | $(OBJ)/ww
|
|
$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
|
|
|
|
# ---- wwdump (lex/AST diff anchor) --------------------------------------
|
|
$(BIN)/wwdump: $(WD_OBJ) $(LIB)/libwcc.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(WD_OBJ) -L$(LIB) -lwcc
|
|
|
|
$(OBJ)/wwdump/%.o: cmd/wwdump/%.c cmd/wcc/ww.h | $(OBJ)/wwdump
|
|
$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
|
|
|
|
# ---- w6c amd64 compiler ------------------------------------------------
|
|
$(BIN)/w6c: $(W6C_OBJ) $(LIB)/libwcc.a | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(W6C_OBJ) -L$(LIB) -lwcc
|
|
|
|
$(OBJ)/w6c/%.o: cmd/w6c/%.c cmd/w6c/gc.h cmd/w6c/6.out.h cmd/wcc/ww.h | $(OBJ)/w6c
|
|
$(CC) $(CFLAGS) $(INCS) -Icmd/w6c -c -o $@ $<
|
|
|
|
# ---- w6a amd64 assembler -----------------------------------------------
|
|
$(BIN)/w6a: $(W6A_OBJ) | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(W6A_OBJ)
|
|
|
|
$(OBJ)/w6a/%.o: cmd/w6a/%.c cmd/w6a/a.h cmd/w6c/6.out.h | $(OBJ)/w6a
|
|
$(CC) $(CFLAGS) -Icmd/w6a -Icmd/w6c -c -o $@ $<
|
|
|
|
# ---- w6l amd64 linker --------------------------------------------------
|
|
$(BIN)/w6l: $(W6L_OBJ) | $(BIN)
|
|
$(CC) $(CFLAGS) -o $@ $(W6L_OBJ)
|
|
|
|
$(OBJ)/w6l/%.o: cmd/w6l/%.c cmd/w6l/l.h | $(OBJ)/w6l
|
|
$(CC) $(CFLAGS) -Icmd/w6l -c -o $@ $<
|
|
|
|
# ---- ww-side wwdump (the frontend dump tool; oracle for 950/994) -------
|
|
# Built via the user-facing ww driver. The frontend (lex, tok, ast,
|
|
# parse, typ, sym) is the `syntax` package in lib/ww/syntax/; the
|
|
# compiler-only bits (check, cgen*) stay in selfhost/cmd/wcc/. Output named wwdump_ww
|
|
# to avoid colliding with the C-side wwdump in $(BIN).
|
|
$(BIN)/wwdump_ww: selfhost/cmd/wwdump/main.ww \
|
|
lib/ww/syntax/lex.ww lib/ww/syntax/tok.ww lib/ww/syntax/ast.ww \
|
|
lib/ww/syntax/parse.ww lib/ww/syntax/expr.ww lib/ww/syntax/stmt.ww lib/ww/syntax/decl.ww lib/ww/syntax/typ.ww lib/ww/syntax/sym.ww \
|
|
selfhost/cmd/wcc/check.ww \
|
|
selfhost/cmd/wcc/cgen.ww selfhost/cmd/wcc/cgenexpr.ww \
|
|
selfhost/cmd/wcc/cgenstmt.ww selfhost/cmd/wcc/cgenutil.ww \
|
|
selfhost/cmd/wcc/cgendecl.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww lib/strconv/strconv.ww lib/strconv/stof_data.ww lib/strconv/decimal.ww lib/strconv/stof.ww lib/strconv/ftos_data.ww lib/strconv/ftos.ww lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww lib/ascii/ascii.ww lib/errors/errors.ww lib/io/io.ww lib/io/stream.ww lib/io/types.ww lib/math/floats.ww lib/math/math.ww lib/memio/memio.ww lib/types/types.ww \
|
|
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/wwdump_ww
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/wwdump_ww \
|
|
-o $(WWBUILD)/wwdump_ww/main \
|
|
-I $(CURDIR)/lib/ww -I $(CURDIR)/selfhost/cmd/wcc \
|
|
$(CURDIR)/selfhost/cmd/wwdump/main.ww
|
|
@mv $(WWBUILD)/wwdump_ww/main $@
|
|
|
|
# ---- ww-side w6c (compiler port, exercised by 994_w6c_ww) -------------
|
|
# Thin driver: parse + cgen. The frontend (lex/parse/ast/...) is the
|
|
# `syntax` package in lib/ww/syntax/; cgen + check live in selfhost/cmd/wcc/.
|
|
$(BIN)/w6c_ww: selfhost/cmd/w6c/main.ww \
|
|
lib/ww/syntax/lex.ww lib/ww/syntax/tok.ww lib/ww/syntax/ast.ww \
|
|
lib/ww/syntax/parse.ww lib/ww/syntax/expr.ww lib/ww/syntax/stmt.ww lib/ww/syntax/decl.ww lib/ww/syntax/typ.ww lib/ww/syntax/sym.ww \
|
|
selfhost/cmd/wcc/check.ww selfhost/cmd/wcc/wwi.ww \
|
|
selfhost/cmd/wcc/cgen.ww selfhost/cmd/wcc/cgenexpr.ww \
|
|
selfhost/cmd/wcc/cgenstmt.ww selfhost/cmd/wcc/cgenutil.ww \
|
|
selfhost/cmd/wcc/cgendecl.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww lib/strconv/strconv.ww lib/strconv/stof_data.ww lib/strconv/decimal.ww lib/strconv/stof.ww lib/strconv/ftos_data.ww lib/strconv/ftos.ww lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww lib/ascii/ascii.ww lib/errors/errors.ww lib/io/io.ww lib/io/stream.ww lib/io/types.ww lib/math/floats.ww lib/math/math.ww lib/memio/memio.ww lib/types/types.ww \
|
|
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/w6c_ww
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/w6c_ww \
|
|
-o $(WWBUILD)/w6c_ww/main \
|
|
-I $(CURDIR)/lib/ww -I $(CURDIR)/selfhost/cmd/wcc \
|
|
$(CURDIR)/selfhost/cmd/w6c/main.ww
|
|
@mv $(WWBUILD)/w6c_ww/main $@
|
|
|
|
# ---- ww-side w6a (assembler port, exercised by 991_w6a_ww) ------------
|
|
# Built like wwdump_ww. Needs -I selfhost/cmd/w6a for the local types/lex/
|
|
# parse/asm/obj modules.
|
|
$(BIN)/w6a_ww: selfhost/cmd/w6a/main.ww selfhost/cmd/w6a/opcodes.ww \
|
|
selfhost/cmd/w6a/lex.ww selfhost/cmd/w6a/parse.ww \
|
|
selfhost/cmd/w6a/asm.ww selfhost/cmd/w6a/obj.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww \
|
|
lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww \
|
|
lib/types/types.ww \
|
|
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/w6a_ww
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/w6a_ww \
|
|
-o $(WWBUILD)/w6a_ww/main \
|
|
-I $(CURDIR)/selfhost/cmd/w6a \
|
|
$(CURDIR)/selfhost/cmd/w6a/main.ww
|
|
@mv $(WWBUILD)/w6a_ww/main $@
|
|
|
|
# ---- ww-side w6l (linker port, exercised by 992_w6l_ww) ---------------
|
|
# Built like 6a_ww. Needs -I selfhost/cmd/w6l for the local sym/obj/pass/
|
|
# out modules.
|
|
$(BIN)/w6l_ww: selfhost/cmd/w6l/main.ww selfhost/cmd/w6l/sym.ww \
|
|
selfhost/cmd/w6l/obj.ww selfhost/cmd/w6l/dyn.ww \
|
|
selfhost/cmd/w6l/pass.ww selfhost/cmd/w6l/dynout.ww \
|
|
selfhost/cmd/w6l/out.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww \
|
|
lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww \
|
|
lib/types/types.ww \
|
|
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/w6l_ww
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/w6l_ww \
|
|
-o $(WWBUILD)/w6l_ww/main \
|
|
-I $(CURDIR)/selfhost/cmd/w6l \
|
|
$(CURDIR)/selfhost/cmd/w6l/main.ww
|
|
@mv $(WWBUILD)/w6l_ww/main $@
|
|
|
|
# ---- ww-side ww driver (exercised by 993_ww_ww) ------------------------
|
|
# The driver pulls in lib/os (default search path) and orchestrates
|
|
# w6c/w6a/w6l like the C driver.
|
|
$(BIN)/ww_ww: selfhost/cmd/ww/main.ww lib/os/exec/exec.ww \
|
|
lib/os/os.ww lib/rt/malloc.ww \
|
|
lib/time/time.ww lib/types/types.ww \
|
|
lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww \
|
|
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/ww_ww
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/ww_ww \
|
|
-o $(WWBUILD)/ww_ww/main \
|
|
$(CURDIR)/selfhost/cmd/ww/main.ww
|
|
@mv $(WWBUILD)/ww_ww/main $@
|
|
|
|
# ---- runtime (libwwrt.a, assembled by our own w6a) ---------------------
|
|
$(OBJ)/rt/%.o: rt/%.s $(BIN)/w6a | $(OBJ)/rt
|
|
$(BIN)/w6a -o $@ $<
|
|
|
|
# ww-side runtime helpers (rt/*.ww): compile via w6c to .s, then w6a.
|
|
# Each .ww module is standalone — uses @symbol FFI for rt_alloc/rt_free
|
|
# rather than `use os;` so no bundling is required.
|
|
$(OBJ)/rt/%.s: rt/%.ww $(BIN)/w6c | $(OBJ)/rt
|
|
$(BIN)/w6c $< > $@
|
|
$(OBJ)/rt/%.o: $(OBJ)/rt/%.s $(BIN)/w6a | $(OBJ)/rt
|
|
$(BIN)/w6a -o $@ $<
|
|
|
|
$(LIB)/libwwrt.a: $(RT_OBJ) | $(LIB)
|
|
$(AR) rcs $@ $(RT_OBJ)
|
|
|
|
$(WWTEST_BIN): $(WWTEST_SRC) $(BIN)/ww $(BIN)/w6c $(BIN)/w6a \
|
|
$(BIN)/w6l $(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/wwtest
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/wwtest \
|
|
-o $(WWBUILD)/wwtest/main \
|
|
-I $(CURDIR)/internal $(CURDIR)/cmd/wwtest/wwtest.ww
|
|
@mv $(WWBUILD)/wwtest/main $@
|
|
|
|
wwfixture: $(WWFIXTURE_BIN)
|
|
|
|
test-wwfixture-process: $(EXEC_TEST_C) $(EXEC_TEST_WW)
|
|
$(CURDIR)/$(EXEC_TEST_C)
|
|
$(CURDIR)/$(EXEC_TEST_WW)
|
|
|
|
test-wwfixture: wwfixture test-wwfixture-process
|
|
sh test/wwfixture/integration.sh
|
|
|
|
$(WWFIXTURE_BIN): $(WWFIXTURE_SRC) $(WWFIXTURE_BUILD_TOOLS) | $(BIN)
|
|
@mkdir -p $(WWBUILD)/wwfixture
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/wwfixture \
|
|
-o $(WWBUILD)/wwfixture/main \
|
|
-I $(CURDIR)/internal $(CURDIR)/cmd/wwfixture/wwfixture.ww
|
|
@mv $(WWBUILD)/wwfixture/main $@
|
|
|
|
$(EXEC_TEST_C): $(EXEC_TEST_SRC) $(WWFIXTURE_TOOLS) | $(BIN)
|
|
@mkdir -p $(WWBUILD)/test_exec
|
|
@$(CURDIR)/$(BIN)/ww build -w $(WWBUILD)/test_exec \
|
|
-o $(WWBUILD)/test_exec/main \
|
|
-I $(CURDIR)/internal $(CURDIR)/test/wwfixture/process/main.ww
|
|
@mv $(WWBUILD)/test_exec/main $@
|
|
|
|
# Built by the wwstage driver: the ordinary Make path exercises
|
|
# ww_ww's -w implementation, not only the cstage twin's.
|
|
$(EXEC_TEST_WW): $(EXEC_TEST_SRC) $(WWFIXTURE_TOOLS) | $(BIN)
|
|
@mkdir -p $(WWBUILD)/test_exec_ww
|
|
@$(CURDIR)/$(BIN)/ww_ww build -w $(WWBUILD)/test_exec_ww \
|
|
-o $(WWBUILD)/test_exec_ww/main \
|
|
-I $(CURDIR)/internal $(CURDIR)/test/wwfixture/process/main.ww
|
|
@mv $(WWBUILD)/test_exec_ww/main $@
|
|
|
|
$(PACKAGE_TEST_BIN): $(PACKAGE_TEST_SRC) $(WWTEST_BIN) \
|
|
$(BIN)/ww $(BIN)/ww_ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a | $(BIN)
|
|
@mkdir -p $(WWBUILD)/test_package
|
|
@$(CURDIR)/$(BIN)/ww test -c -w $(WWBUILD)/test_package \
|
|
-I $(CURDIR)/internal $(CURDIR)/test/package/package_test.ww
|
|
@mv $(WWBUILD)/test_package/main $@
|
|
|
|
test-package: $(PACKAGE_TEST_BIN) $(WWTEST_BIN) $(BIN)/ww $(BIN)/ww_ww \
|
|
$(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6a_ww \
|
|
$(BIN)/w6l $(BIN)/w6l_ww $(LIB)/libwwrt.a
|
|
@WW_PACKAGE_REPO=$(CURDIR) $(CURDIR)/$(PACKAGE_TEST_BIN)
|
|
|
|
# ---- directories -------------------------------------------------------
|
|
$(BIN) $(LIB) $(OBJ)/wcc $(OBJ)/ww $(OBJ)/wwdump $(OBJ)/w6c $(OBJ)/w6a $(OBJ)/w6l $(OBJ)/rt:
|
|
mkdir -p $@
|
|
|
|
# ---- tests -------------------------------------------------------------
|
|
|
|
# Five in-process C compiler units. Every other surviving C gate has a named
|
|
# artifact owner below and is built by one generic rule; source presence is
|
|
# the registration, so adding a case never requires a TESTS edit and a second
|
|
# per-case Make rule.
|
|
UNIT_SOURCES = test/wcc/000_smoke.c test/wcc/100_lex.c \
|
|
test/wcc/200_parse.c test/wcc/300_check.c test/wcc/400_w6c.c
|
|
# Ww-native byte/artifact observers: single-file ww tests under
|
|
# test/byteid/ on the test/testenv helper package (asm-pattern/symbol
|
|
# windows, .wwi round-trips, inline sources with no corpus twin, the
|
|
# wwstage-driver-leg gates). The native byteid carrier partition is
|
|
# EMPTY: 61 pure data-fixture carriers retired into test-data-byteid
|
|
# (fold-4, 2026-08-07) and the last 11 observers ported here
|
|
# (2026-08-08). Each test drives the stage tools it observes itself,
|
|
# so the build needs only cstage plus the wwstage binaries it
|
|
# launches.
|
|
BYTEID_WW_TESTS = test/byteid/libbyteid_test.ww test/byteid/wwi_test.ww \
|
|
test/byteid/asmwindow_test.ww test/byteid/freenoop_test.ww \
|
|
test/byteid/structabi_test.ww test/byteid/mangle_test.ww
|
|
BYTEID_WW_TARGETS = $(BYTEID_WW_TESTS:%=wwtest/%)
|
|
# Ww-native sep-driver/tool observers: single-file ww tests under
|
|
# test/sep/ on the test/testenv helper package, porting the residual
|
|
# 989_sep* driver-observer C carriers. These are compiler/driver
|
|
# gates (module trees, sepwork artifact layout, composed //ww:module
|
|
# units, link rejects), NOT byteid suites: they run under
|
|
# test-compiler beside the surviving residual carriers.
|
|
SEP_WW_TESTS = test/sep/sepbuild_test.ww test/sep/sepimport_test.ww \
|
|
test/sep/seplink_test.ww test/sep/sepscratch_test.ww \
|
|
test/sep/septest_test.ww test/sep/m3sep_test.ww
|
|
SEP_WW_TARGETS = $(SEP_WW_TESTS:%=wwtest/%)
|
|
# Ww-native multi-module-TREE observers: single-file ww tests under
|
|
# test/xmod/ on the test/testenv helper package, porting the residual
|
|
# multi-module C carriers (import-tree collisions, path-mangle and
|
|
# label-mangle runs, cross-module typecheck rejects, enumerator
|
|
# capacity, directive adjacency). Compiler/driver gates like test/sep:
|
|
# they run under test-compiler.
|
|
XMOD_WW_TESTS = test/xmod/collide_test.ww test/xmod/m1_test.ww \
|
|
test/xmod/label_test.ww test/xmod/typecheck_test.ww \
|
|
test/xmod/enumcap_test.ww test/xmod/modreset_test.ww
|
|
XMOD_WW_TARGETS = $(XMOD_WW_TESTS:%=wwtest/%)
|
|
|
|
# Ww-native asm-window observers: single-file ww tests under test/asm/
|
|
# on the test/testenv helper package, porting the retired 7xx
|
|
# assembly-window C carriers (positional TEXT..RET windows,
|
|
# needle/anti-needle pairs, occurrence counts, per-row cs-vs-ws
|
|
# byte-id legs). They observe compiler BEHAVIOR by driving w6c and
|
|
# w6c_ww per row — not identity gates — so they run under
|
|
# test-compiler beside the surviving residual carriers.
|
|
ASM_WW_TESTS = test/asm/modshadow_test.ww test/asm/sret_test.ww \
|
|
test/asm/callarg_test.ww test/asm/chain_test.ww \
|
|
test/asm/dataemit_test.ww test/asm/matchdispatch_test.ww \
|
|
test/asm/ampfn_test.ww test/asm/tagsret_test.ww \
|
|
test/asm/memarg_test.ww
|
|
ASM_WW_TARGETS = $(ASM_WW_TESTS:%=wwtest/%)
|
|
|
|
# Ww-native assembler/linker OBJECT-level observers: single-file ww
|
|
# tests under test/object/ on the test/testenv helper package, porting
|
|
# the residual w6a/w6l artifact C carriers (ELF section/symbol/reloc
|
|
# layout, program-header split and BSS trim, archive selectivity,
|
|
# linker flag capacity, assembler input gates). Compiler/driver gates
|
|
# like test/sep: they run under test-compiler.
|
|
OBJECT_WW_TESTS = test/object/elfobj_test.ww test/object/link_test.ww \
|
|
test/object/archive_test.ww test/object/asmgate_test.ww
|
|
OBJECT_WW_TARGETS = $(OBJECT_WW_TESTS:%=wwtest/%)
|
|
|
|
# Ww-native misc observers: single-file ww tests under test/misc/ on
|
|
# the test/testenv helper package, porting the residual mixed-shape C
|
|
# carriers (per-stage divergence pins, wwstage stamp-diagnostic and
|
|
# run-stderr probes, .wwi round-trip trees, tool-dump AST proofs,
|
|
# cstage-only rejects). Compiler/driver gates like test/sep: they run
|
|
# under test-compiler.
|
|
MISC_WW_TESTS = test/misc/arrglob_test.ww test/misc/packedwwi_test.ww \
|
|
test/misc/reject_test.ww test/misc/heldasym_test.ww \
|
|
test/misc/stampdiag_test.ww test/misc/qualast_test.ww \
|
|
test/misc/abortmsg_test.ww
|
|
MISC_WW_TARGETS = $(MISC_WW_TESTS:%=wwtest/%)
|
|
|
|
# Ww-native driver/tool observers: single-file ww tests under
|
|
# test/tool/ on the test/testenv helper package, porting the residual
|
|
# driver/tool observer C carriers (cstage-only reject sets, wwdump_ww
|
|
# diagnostic gates, driver-CLI parity, @symbol FFI asm needles, .wwi
|
|
# wide-rune round-trips, the c6 sep soak). Compiler/driver gates like
|
|
# test/sep: they run under test-compiler.
|
|
TOOL_WW_TESTS = test/tool/rejects_test.ww test/tool/driver_test.ww \
|
|
test/tool/wwdump_test.ww test/tool/ffi_test.ww \
|
|
test/tool/attest_test.ww
|
|
TOOL_WW_TARGETS = $(TOOL_WW_TESTS:%=wwtest/%)
|
|
BOOTSTRAP_WRAPPER_SOURCES = test/wcc/950_selfcheck.c \
|
|
test/wcc/991_w6a_ww.c \
|
|
test/wcc/992_w6l_ww.c test/wcc/993_ww_ww.c \
|
|
test/wcc/994_w6c_ww.c test/wcc/995_self_rebuild.c
|
|
PLATFORM_WRAPPER_SOURCES = test/wcc/996_dyn_ww.c
|
|
ALL_WRAPPER_SOURCES = $(wildcard test/wcc/*.c)
|
|
COMPILER_WRAPPER_SOURCES = $(filter-out $(UNIT_SOURCES) \
|
|
$(BOOTSTRAP_WRAPPER_SOURCES) \
|
|
$(PLATFORM_WRAPPER_SOURCES),$(ALL_WRAPPER_SOURCES))
|
|
|
|
UNIT_BINS = $(patsubst test/wcc/%.c,$(BIN)/test_%,$(UNIT_SOURCES))
|
|
BOOTSTRAP_WRAPPER_BINS = $(patsubst test/wcc/%.c,$(BIN)/test_%,$(BOOTSTRAP_WRAPPER_SOURCES))
|
|
PLATFORM_WRAPPER_BINS = $(patsubst test/wcc/%.c,$(BIN)/test_%,$(PLATFORM_WRAPPER_SOURCES))
|
|
COMPILER_WRAPPER_BINS = $(patsubst test/wcc/%.c,$(BIN)/test_%,$(COMPILER_WRAPPER_SOURCES))
|
|
WRAPPER_TOOLS = $(CSTAGE_BINS) $(WWSTAGE_BINS) $(WWTEST_BIN) $(LIBS)
|
|
|
|
$(filter-out $(BIN)/test_400_w6c,$(UNIT_BINS)): $(BIN)/test_%: \
|
|
test/wcc/%.c $(LIB)/libwcc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -o $@ $< $(LIB)/libwcc.a
|
|
|
|
$(BIN)/test_200_parse $(BIN)/test_300_check: test/wcc/wwtestpkg.h
|
|
|
|
$(BIN)/test_400_w6c: test/wcc/400_w6c.c \
|
|
test/wcc/wwtestpkg.h $(OBJ)/w6c/cgen.o $(OBJ)/w6c/txt.o \
|
|
$(LIB)/libwcc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -Icmd/w6c -o $@ $< \
|
|
$(OBJ)/w6c/cgen.o $(OBJ)/w6c/txt.o $(LIB)/libwcc.a
|
|
|
|
$(BIN)/test_%: test/wcc/%.c test/wcc/wwtestpkg.h $(LIB)/libwcc.a | $(BIN)
|
|
$(CC) $(CFLAGS) $(INCS) -o $@ $< $(LIB)/libwcc.a
|
|
|
|
# 989_ffivariadic depends on a C callee archive the harness finds via
|
|
# $(BIN)/../ffivariadic. The fixture is built self-contained (zero
|
|
# relocs + undef syms) so w6l links it with no libc; flags are fixed,
|
|
# NOT $(CFLAGS), to keep that property. The rule was dropped in the
|
|
# test-graph rewrite (228a632a) and a stale out/ tree masked it.
|
|
$(OUT)/ffivariadic/libffifix.a: test/wcc/data/ffivariadic/fixture.c
|
|
@mkdir -p $(OUT)/ffivariadic
|
|
$(CC) -O1 -fno-stack-protector -fno-asynchronous-unwind-tables \
|
|
-fcf-protection=none -c -o $(OUT)/ffivariadic/fixture.o $<
|
|
$(AR) rcs $@ $(OUT)/ffivariadic/fixture.o
|
|
|
|
$(BIN)/test_989_ffivariadic_run: $(OUT)/ffivariadic/libffifix.a
|
|
|
|
# Native library tests execute their source owner directly. The retired C
|
|
# launchers added no assertion beyond this exit status.
|
|
LIBRARY_TESTS = lib/errors/errno_test.ww lib/ascii/ascii_test.ww \
|
|
lib/ww/syntax/tok_test.ww lib/ww/syntax/ast_test.ww \
|
|
lib/ww/syntax/sym_test.ww \
|
|
lib/strconv/test/ftos_test.ww lib/strconv/test/stof_test.ww \
|
|
lib/strconv/test/int_test.ww lib/strings/strings_test.ww \
|
|
lib/bytes/bytes_test.ww lib/encoding/utf8/utf8_test.ww \
|
|
lib/bufio/bufio_test.ww lib/math/random/random_test.ww \
|
|
lib/math/checked/checked_test.ww lib/fmt/fmt_test.ww \
|
|
lib/log/log_test.ww lib/fnmatch/fnmatch_test.ww \
|
|
lib/shlex/shlex_test.ww lib/time/time_test.ww \
|
|
lib/encoding/hex/hex_test.ww lib/memio/memio_test.ww \
|
|
lib/temp/temp_test.ww lib/getopt/getopt_test.ww \
|
|
lib/encoding/base32/base32_test.ww \
|
|
lib/encoding/base64/base64_test.ww \
|
|
lib/hash/adler32/adler32_test.ww lib/hash/crc16/crc16_test.ww \
|
|
lib/hash/crc32/crc32_test.ww lib/hash/crc64/crc64_test.ww \
|
|
lib/path/path_test.ww lib/crypto/sha256/sha256_test.ww \
|
|
lib/hash/siphash/siphash_test.ww
|
|
|
|
# These real sources have a standalone-compilation contract that is not
|
|
# subsumed by a library @test import owner.
|
|
LIBRARY_STANDALONE_SOURCES = lib/io/io.ww lib/strconv/strconv.ww \
|
|
lib/hash/fnv/fnv.ww lib/net/net.ww
|
|
|
|
test-unit: $(UNIT_BINS)
|
|
@set -e; for t in $(UNIT_BINS); do \
|
|
echo "unit $$t"; $(CURDIR)/$$t; \
|
|
done
|
|
|
|
# One compile-only declarative fixture is the ordinary C/WW smoke slice.
|
|
test-compiler-smoke: $(WWFIXTURE_BIN) $(BIN)/w6c_ww $(BIN)/w6a_ww \
|
|
$(BIN)/w6l_ww $(BIN)/ww_ww
|
|
@$(CURDIR)/$(WWFIXTURE_BIN) -j 1 \
|
|
-run compiler.r78_strict_package_main_accept
|
|
|
|
# Complete declarative corpus plus the residual native artifact/integration
|
|
# gates that cannot be represented by a single compiler fixture, plus the
|
|
# ww-native sep observers that replaced the 989_sep* carriers.
|
|
test-compiler: $(WWFIXTURE_BIN) $(WRAPPER_TOOLS) $(COMPILER_WRAPPER_BINS) \
|
|
$(SEP_WW_TARGETS) $(XMOD_WW_TARGETS) $(ASM_WW_TARGETS) \
|
|
$(OBJECT_WW_TARGETS) $(MISC_WW_TARGETS) $(TOOL_WW_TARGETS)
|
|
@$(CURDIR)/$(WWFIXTURE_BIN) -j $(JOBS)
|
|
@set -e; for t in $(COMPILER_WRAPPER_BINS); do \
|
|
echo "compiler artifact $$t"; BIN=$(CURDIR)/$(BIN) $(CURDIR)/$$t; \
|
|
done
|
|
|
|
# One phony target per language/library test file so `make -jN`
|
|
# parallelizes the suites, each in its own persistent -w workdir so only
|
|
# changed packages rebuild. Tests always execute — the workdir caches
|
|
# builds, never results.
|
|
LANG_TEST_FILES = $(wildcard test/lang/*_test.ww)
|
|
LANG_TEST_TARGETS = $(LANG_TEST_FILES:%=wwtest/%)
|
|
LIBRARY_TEST_TARGETS = $(LIBRARY_TESTS:%=wwtest/%)
|
|
|
|
$(LANG_TEST_TARGETS): wwtest/%: $(BIN)/ww \
|
|
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@$(BIN)/ww test -w $(WWBUILD)/wwtest/$(subst /,_,$*) $*
|
|
|
|
$(LIBRARY_TEST_TARGETS): wwtest/%: $(BIN)/ww \
|
|
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@$(BIN)/ww test -w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/lib/ww $*
|
|
|
|
$(BYTEID_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a \
|
|
$(BIN)/w6l $(BIN)/wwdump $(LIB)/libwwrt.a \
|
|
$(BIN)/ww_ww $(BIN)/w6c_ww
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@WW_TEST_REPO=$(CURDIR) $(BIN)/ww test \
|
|
-w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/test $*
|
|
|
|
# The sep observers drive both driver stages end-to-end (compile,
|
|
# assemble, link, run), so both full per-stage toolchains are
|
|
# prerequisites.
|
|
$(SEP_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww \
|
|
$(BIN)/w6l_ww
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@WW_TEST_REPO=$(CURDIR) $(BIN)/ww test \
|
|
-w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/test $*
|
|
|
|
# The xmod observers drive both driver stages (and the modreset row the
|
|
# raw w6c/w6a/w6l chain) end-to-end, so both full per-stage toolchains
|
|
# are prerequisites.
|
|
$(XMOD_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww \
|
|
$(BIN)/w6l_ww
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@WW_TEST_REPO=$(CURDIR) $(BIN)/ww test \
|
|
-w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/test $*
|
|
|
|
# The asm observers launch only the per-stage compilers (w6c, w6c_ww);
|
|
# the remaining tools build and run the test binary itself.
|
|
$(ASM_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a $(BIN)/w6c_ww
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@WW_TEST_REPO=$(CURDIR) $(BIN)/ww test \
|
|
-w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/test $*
|
|
|
|
# The object observers feed hand-written .s (and w6c output) to the
|
|
# assemblers and linkers of both stages and parse the resulting ELF
|
|
# artifacts, so w6c plus both stages' w6a/w6l are prerequisites;
|
|
# libwwrt.a carries the $(OBJ)/rt/start.o the archive rows link.
|
|
$(OBJECT_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a \
|
|
$(BIN)/w6l $(LIB)/libwwrt.a $(BIN)/w6a_ww $(BIN)/w6l_ww
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@WW_TEST_REPO=$(CURDIR) $(BIN)/ww test \
|
|
-w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/test $*
|
|
|
|
# The misc observers drive both driver stages end-to-end plus the
|
|
# wwdump twins, so both full per-stage toolchains are prerequisites.
|
|
$(MISC_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww \
|
|
$(BIN)/w6l_ww $(BIN)/wwdump $(BIN)/wwdump_ww
|
|
|
|
# The tool observers drive both driver stages, both bare frontend/
|
|
# assembler/linker triples, and the wwstage checker/dumper. wwdump_ww,
|
|
# never cstage wwdump: the -c/-r arms and the asserttyped diagnostics
|
|
# under observation are wwstage-only (wwstage-warn-audit rule).
|
|
$(TOOL_WW_TARGETS): wwtest/%: $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
|
$(LIB)/libwwrt.a $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww \
|
|
$(BIN)/w6l_ww $(BIN)/wwdump_ww
|
|
@echo "ww test $*"
|
|
@mkdir -p $(WWBUILD)/wwtest/$(subst /,_,$*)
|
|
@WW_TEST_REPO=$(CURDIR) $(BIN)/ww test \
|
|
-w $(WWBUILD)/wwtest/$(subst /,_,$*) \
|
|
-I $(CURDIR)/test $*
|
|
|
|
test-lang: $(LANG_TEST_TARGETS)
|
|
|
|
test-library: $(LIBRARY_TEST_TARGETS) $(BIN)/w6c $(BIN)/w6c_ww \
|
|
$(WWTEST_BIN) $(LIBRARY_STANDALONE_SOURCES)
|
|
@set -e; for f in $(LIBRARY_STANDALONE_SOURCES); do \
|
|
echo "library compile c $$f"; \
|
|
$(CURDIR)/$(BIN)/w6c $(CURDIR)/$$f > /dev/null; \
|
|
echo "library compile ww $$f"; \
|
|
$(CURDIR)/$(BIN)/w6c_ww $(CURDIR)/$$f > /dev/null; \
|
|
done
|
|
@echo "ww test lib/regex"
|
|
@$(CURDIR)/$(BIN)/ww test lib/regex
|
|
|
|
test-bootstrap-native: $(WRAPPER_TOOLS) $(BOOTSTRAP_WRAPPER_BINS)
|
|
@set -e; for t in $(BOOTSTRAP_WRAPPER_BINS); do \
|
|
echo "bootstrap $$t"; BIN=$(CURDIR)/$(BIN) $(CURDIR)/$$t; \
|
|
done
|
|
|
|
test-platform: $(WRAPPER_TOOLS) $(PLATFORM_WRAPPER_BINS)
|
|
@set -e; for t in $(PLATFORM_WRAPPER_BINS); do \
|
|
echo "platform $$t"; BIN=$(CURDIR)/$(BIN) $(CURDIR)/$$t; \
|
|
done
|
|
|
|
# Public composition. The default developer gate is intentionally small;
|
|
# byte identity and self-host fixed points are never hidden prerequisites.
|
|
test: test-unit test-compiler-smoke
|
|
|
|
test-commit: test-unit test-compiler test-package test-lang test-library
|
|
|
|
# Compiler-output identity stops after w6c has emitted every package `.s`.
|
|
# Driver -S still performs discovery, unit composition, dependency ordering,
|
|
# and `.wwi` production; it never invokes w6a, archive creation, or w6l.
|
|
LANGBYTEID_DIR = $(OUT)/langbyteid
|
|
LANGBYTEID_FILES = $(filter-out %_runonly_test.ww,$(wildcard test/lang/*_test.ww))
|
|
LANGBYTEID_EXPECTED_MIN = 158
|
|
$(if $(LANGBYTEID_FILES),,$(error test-byteid: empty language corpus))
|
|
test-lang-byteid: $(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww
|
|
@work=$$(mktemp -d "$(CURDIR)/$(LANGBYTEID_DIR).XXXXXX") || exit 1; \
|
|
rc=0; n=0; base=; \
|
|
for f in $(LANGBYTEID_FILES); do \
|
|
base=$$work/`basename $$f .ww`; \
|
|
WW_W6C=$(BIN)/w6c $(BIN)/ww test -S -o $$base.cs $$f \
|
|
|| { rc=$$?; break; }; \
|
|
WW_W6C=$(BIN)/w6c_ww $(BIN)/ww test -S -o $$base.ww $$f \
|
|
|| { rc=$$?; break; }; \
|
|
test -d $$base.cs.sepwork && test -d $$base.ww.sepwork || { \
|
|
echo "test-byteid: FAIL $$f: missing .sepwork"; rc=1; break; }; \
|
|
cs_set=`cd $$base.cs.sepwork && find . -maxdepth 1 -type f -name '*.s' -printf '%f\n' | sort`; \
|
|
ww_set=`cd $$base.ww.sepwork && find . -maxdepth 1 -type f -name '*.s' -printf '%f\n' | sort`; \
|
|
if [ "$$cs_set" != "$$ww_set" ]; then \
|
|
echo "test-byteid: FAIL $$f: .s set differs"; rc=1; break; \
|
|
fi; \
|
|
echo "$$cs_set" | grep -qx __root.s || { \
|
|
echo "test-byteid: FAIL $$f: no __root.s"; rc=1; break; }; \
|
|
ns=0; \
|
|
for s in $$cs_set; do \
|
|
cmp -s $$base.cs.sepwork/$$s $$base.ww.sepwork/$$s || { \
|
|
echo "test-byteid: FAIL $$f: $$s differs"; rc=1; break; }; \
|
|
ns=`expr $$ns + 1`; \
|
|
done; \
|
|
if [ $$rc -ne 0 ]; then break; fi; \
|
|
test $$ns -ge 1 || { rc=1; break; }; \
|
|
rm -rf -- $$base.cs.sepwork $$base.ww.sepwork || { \
|
|
echo "test-byteid: FAIL $$f: scratch cleanup"; rc=1; break; }; \
|
|
base=; n=`expr $$n + 1`; \
|
|
done; \
|
|
if [ -n "$$base" ]; then \
|
|
rm -rf -- $$base.cs.sepwork $$base.ww.sepwork || { \
|
|
echo "test-byteid: scratch cleanup failed"; \
|
|
if [ $$rc -eq 0 ]; then rc=1; fi; }; \
|
|
fi; \
|
|
if [ $$rc -eq 0 ] && [ $$n -lt $(LANGBYTEID_EXPECTED_MIN) ]; then \
|
|
echo "test-byteid: corpus shrank ($$n < $(LANGBYTEID_EXPECTED_MIN))"; \
|
|
rc=1; \
|
|
fi; \
|
|
rmdir "$$work" || { echo "test-byteid: workspace cleanup failed"; \
|
|
if [ $$rc -eq 0 ]; then rc=1; fi; }; \
|
|
if [ $$rc -eq 0 ]; then \
|
|
echo "test-byteid: $$n language files compared at compiler output"; \
|
|
fi; \
|
|
exit $$rc
|
|
|
|
# Blanket compiler-output identity over the declarative fixture corpus:
|
|
# every non-error case.ww builds through the fixed cstage driver twice,
|
|
# swapping only the frontend (WW_W6C), and every emitted per-package .s
|
|
# must be byte-identical. This is the fold-4 end-state comparator that
|
|
# retired the per-snippet byte-id C carriers; //ww:error fixtures have no
|
|
# .s and their both-stage reject parity is owned by the fixture corpus.
|
|
DATABYTEID_DIR = $(OUT)/databyteid
|
|
DATABYTEID_FILES = $(wildcard test/wcc/data/*/case.ww)
|
|
DATABYTEID_EXPECTED_MIN = 915
|
|
# Known cs!=ww divergences (loud over blind, the 989_lib_byteid DIVERGE
|
|
# discipline): each entry must still build on both stages AND still differ.
|
|
# When a compiler fix lands the entry fails demanding graduation out of
|
|
# this list rather than silently widening coverage.
|
|
# r700_strings_byteindex: latent, exposed by the 700_e2e migration —
|
|
# wwstage spills a wwi-decl'd tagged call-result arg through a 16B
|
|
# scratch pair where cstage PUSHQes AX/DX (frame 64 vs 80); runtime-
|
|
# equivalent, sibling of the closed #211 name-keyed family.
|
|
# r839_xmod_nominal_match: latent, exposed by the 839 migration (the
|
|
# carrier waived byte-id silently) — same spill family as r700: wwstage
|
|
# routes the cross-module tagged call-result through a 16B scratch pair
|
|
# where cstage PUSHQes AX/DX (frame 16 vs 32); runtime-equivalent
|
|
# (both stages run exit 42).
|
|
# alias_g73_heapfill: held divergence — the ww-side heap struct-lit
|
|
# str-arm deref-field READ leaks a field(SB) load (task #24); both
|
|
# stages frontend-compile rc 0, only the .s differs. Graduates out
|
|
# when #24 lands.
|
|
DATABYTEID_DIVERGED = r700_strings_byteindex r839_xmod_nominal_match \
|
|
alias_g73_heapfill
|
|
$(if $(DATABYTEID_FILES),,$(error test-byteid: empty data corpus))
|
|
test-data-byteid: $(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww
|
|
@work=$$(mktemp -d "$(CURDIR)/$(DATABYTEID_DIR).XXXXXX") || exit 1; \
|
|
rc=0; n=0; pn=0; base=; \
|
|
for f in $(DATABYTEID_FILES); do \
|
|
head -1 $$f | grep -q '^//ww:error' && continue; \
|
|
d=`basename \`dirname $$f\``; \
|
|
base=$$work/$$d; \
|
|
WW_W6C=$(BIN)/w6c $(BIN)/ww build -S -o $$base.cs $$f \
|
|
|| { rc=$$?; break; }; \
|
|
WW_W6C=$(BIN)/w6c_ww $(BIN)/ww build -S -o $$base.ww $$f \
|
|
|| { rc=$$?; break; }; \
|
|
test -d $$base.cs.sepwork && test -d $$base.ww.sepwork || { \
|
|
echo "test-byteid: FAIL $$f: missing .sepwork"; rc=1; break; }; \
|
|
cs_set=`cd $$base.cs.sepwork && find . -maxdepth 1 -type f -name '*.s' -printf '%f\n' | sort`; \
|
|
ww_set=`cd $$base.ww.sepwork && find . -maxdepth 1 -type f -name '*.s' -printf '%f\n' | sort`; \
|
|
if [ "$$cs_set" != "$$ww_set" ]; then \
|
|
echo "test-byteid: FAIL $$f: .s set differs"; rc=1; break; \
|
|
fi; \
|
|
echo "$$cs_set" | grep -qx __root.s || { \
|
|
echo "test-byteid: FAIL $$f: no __root.s"; rc=1; break; }; \
|
|
ns=0; diffs=0; firstdiff=; \
|
|
for s in $$cs_set; do \
|
|
cmp -s $$base.cs.sepwork/$$s $$base.ww.sepwork/$$s || { \
|
|
diffs=`expr $$diffs + 1`; \
|
|
if [ -z "$$firstdiff" ]; then firstdiff=$$s; fi; }; \
|
|
ns=`expr $$ns + 1`; \
|
|
done; \
|
|
case " $(DATABYTEID_DIVERGED) " in \
|
|
*" $$d "*) \
|
|
if [ $$diffs -eq 0 ]; then \
|
|
echo "test-byteid: $$f: now byte-identical — graduate out of DATABYTEID_DIVERGED"; \
|
|
rc=1; break; \
|
|
fi; \
|
|
pn=`expr $$pn + 1`;; \
|
|
*) \
|
|
if [ $$diffs -ne 0 ]; then \
|
|
echo "test-byteid: FAIL $$f: $$firstdiff differs"; \
|
|
rc=1; break; \
|
|
fi;; \
|
|
esac; \
|
|
test $$ns -ge 1 || { rc=1; break; }; \
|
|
rm -rf -- $$base.cs.sepwork $$base.ww.sepwork || { \
|
|
echo "test-byteid: FAIL $$f: scratch cleanup"; rc=1; break; }; \
|
|
base=; n=`expr $$n + 1`; \
|
|
done; \
|
|
if [ -n "$$base" ]; then \
|
|
rm -rf -- $$base.cs.sepwork $$base.ww.sepwork || { \
|
|
echo "test-byteid: scratch cleanup failed"; \
|
|
if [ $$rc -eq 0 ]; then rc=1; fi; }; \
|
|
fi; \
|
|
if [ $$rc -eq 0 ] && [ $$n -lt $(DATABYTEID_EXPECTED_MIN) ]; then \
|
|
echo "test-byteid: data corpus shrank ($$n < $(DATABYTEID_EXPECTED_MIN))"; \
|
|
rc=1; \
|
|
fi; \
|
|
rmdir "$$work" || { echo "test-byteid: workspace cleanup failed"; \
|
|
if [ $$rc -eq 0 ]; then rc=1; fi; }; \
|
|
if [ $$rc -eq 0 ]; then \
|
|
echo "test-byteid: $$n data fixtures compared at compiler output ($$pn pinned-divergent)"; \
|
|
fi; \
|
|
exit $$rc
|
|
|
|
test-byteid: test-lang-byteid test-data-byteid $(BYTEID_WW_TARGETS)
|
|
|
|
# Incremental == clean. The -w reuse path must be byte-identical to a
|
|
# from-scratch build, or it is not a build-graph optimization but a
|
|
# correctness bug. Four warm shapes per driver stage — cold populate,
|
|
# full-skip rerun, surgical staleness (one package's artifacts deleted),
|
|
# and a 0-byte .o poison drill (must recompile, never reuse) — each
|
|
# compared against a classic fresh-scratch build, plus the cross-stage
|
|
# clean compare. The w6a graph keeps the gate small while covering the
|
|
# skip, recompile, commit, and legal-empty-.s (FFI-only rt) paths.
|
|
INCR_DIR = $(OUT)/incrcheck
|
|
test-incremental: $(BIN)/ww $(BIN)/ww_ww $(BIN)/w6c $(BIN)/w6c_ww \
|
|
$(BIN)/w6a $(BIN)/w6a_ww $(BIN)/w6l $(BIN)/w6l_ww \
|
|
$(LIB)/libwwrt.a
|
|
@rm -rf $(INCR_DIR)
|
|
@set -e; \
|
|
src=$(CURDIR)/selfhost/cmd/w6a/main.ww; \
|
|
inc=$(CURDIR)/selfhost/cmd/w6a; \
|
|
for stage in cs ws; do \
|
|
drv=$(CURDIR)/$(BIN)/ww; \
|
|
if [ $$stage = ws ]; then drv=$(CURDIR)/$(BIN)/ww_ww; fi; \
|
|
w=$(INCR_DIR)/$$stage.w; mkdir -p $$w; \
|
|
$$drv build -w $$w -o $(INCR_DIR)/$$stage.cold -I $$inc $$src; \
|
|
$$drv build -w $$w -o $(INCR_DIR)/$$stage.warm -I $$inc $$src; \
|
|
rm $$w/strings.s $$w/strings.o $$w/strings.a; \
|
|
$$drv build -w $$w -o $(INCR_DIR)/$$stage.surg -I $$inc $$src; \
|
|
: > $$w/bytes.o; \
|
|
$$drv build -w $$w -o $(INCR_DIR)/$$stage.heal -I $$inc $$src; \
|
|
(cd $(INCR_DIR) && $$drv build -o $$stage.clean -I $$inc $$src); \
|
|
for v in cold warm surg heal; do \
|
|
cmp $(INCR_DIR)/$$stage.$$v $(INCR_DIR)/$$stage.clean || { \
|
|
echo "test-incremental: $$stage.$$v differs from clean" >&2; \
|
|
exit 1; }; \
|
|
done; \
|
|
done; \
|
|
cmp $(INCR_DIR)/cs.clean $(INCR_DIR)/ws.clean || { \
|
|
echo "test-incremental: cstage/wwstage clean builds differ" >&2; \
|
|
exit 1; }; \
|
|
rm -rf $(INCR_DIR) || { echo "test-incremental: cleanup failed" >&2; exit 1; }; \
|
|
echo "test-incremental: -w reuse byte-identical to clean, both stages"
|
|
|
|
test-bootstrap: bootstrap test-bootstrap-native
|
|
|
|
test-all: test-commit test-byteid test-bootstrap test-platform \
|
|
test-wwfixture test-incremental
|
|
|
|
install: all
|
|
mkdir -p $(PREFIX)/bin $(PREFIX)/lib
|
|
cp $(BIN)/ww $(PREFIX)/bin/
|
|
cp $(WWTEST_BIN) $(PREFIX)/bin/
|
|
cp $(LIB)/libwcc.a $(PREFIX)/lib/
|
|
|
|
clean:
|
|
rm -rf $(OUT)
|
|
|
|
# ---- explicit bootstrap ------------------------------------------------
|
|
# Four-stage self-host on the SEPARATE-COMPILATION path: Cstage (these C
|
|
# tools) builds the wwstage tools, then the wwstage compiler reproduces
|
|
# itself three times with cmp ww2 == ww3 == ww4.
|
|
#
|
|
# Orchestration vs. proof — drawn explicitly so this demo claims no more
|
|
# self-host than it delivers (#66):
|
|
# - The cstage `ww` driver runs the sep GLUE only: dep-discovery,
|
|
# per-package `w6c -c -I`, archiving, and the final link. It is a
|
|
# fixed C orchestrator and is NOT part of the fixed point.
|
|
# - The fixed point ww2 == ww3 == ww4 proves the wwstage COMPILER
|
|
# (w6c, genuinely chained — stage N's frontend is stage N-1's output,
|
|
# injected via WW_W6C) plus the wwstage ASSEMBLER (w6a_ww) and LINKER
|
|
# (w6l_ww) reach a byte-stable fixed point: the load-bearing
|
|
# compiler-reproduces-itself proof. wwdump is unchainable under sep
|
|
# (it takes no -o/-I and writes asm to stdout), so the chainable sep
|
|
# frontend w6c is the bootstrapped target (test 994 pins w6c ==
|
|
# wwdump -c).
|
|
# - The wwstage DRIVER (`ww_ww`) is NOT yet in this loop: it cannot
|
|
# swap its frontend (it hardcodes <selfdir>/w6c_ww and honors no
|
|
# WW_W6C override). Closing that — so `ww_ww` itself carries the
|
|
# glue — is task #66. Until then cstage `ww` orchestrates and this
|
|
# bootstrap does NOT claim a fully wwstage-driven self-host.
|
|
#
|
|
# Why a fourth stage? Stage 3 proves stage-1 w6c_ww 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
|
|
W6CSRC = selfhost/cmd/w6c/main.ww
|
|
W6CINC = -I lib/ww -I selfhost/cmd/wcc
|
|
bootstrap: all
|
|
@echo "=== stage 0 (Cstage): C-built tools ==="
|
|
@echo " $(BIN)/ww (sep orchestrator) $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l"
|
|
@echo
|
|
@echo "=== stage 1: wwstage tools the fixed point chains ==="
|
|
@ls -l $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww
|
|
@rm -rf $(BS) && mkdir -p $(BS)
|
|
@echo
|
|
@echo "=== stage 2: ww2 = stage-1 w6c_ww sep-compiles w6c ==="
|
|
@WW_W6C=$(BIN)/w6c_ww WW_W6A=$(BIN)/w6a_ww WW_W6L=$(BIN)/w6l_ww \
|
|
$(BIN)/ww build -o $(BS)/ww2 $(W6CINC) $(W6CSRC)
|
|
@ls -l $(BS)/ww2
|
|
@echo
|
|
@echo "=== stage 3: ww3 = ww2 sep-compiles w6c ==="
|
|
@WW_W6C=$(BS)/ww2 WW_W6A=$(BIN)/w6a_ww WW_W6L=$(BIN)/w6l_ww \
|
|
$(BIN)/ww build -o $(BS)/ww3 $(W6CINC) $(W6CSRC)
|
|
@ls -l $(BS)/ww3
|
|
@echo
|
|
@echo "=== stage 4: ww4 = ww3 sep-compiles w6c ==="
|
|
@WW_W6C=$(BS)/ww3 WW_W6A=$(BIN)/w6a_ww WW_W6L=$(BIN)/w6l_ww \
|
|
$(BIN)/ww build -o $(BS)/ww4 $(W6CINC) $(W6CSRC)
|
|
@ls -l $(BS)/ww4
|
|
@echo
|
|
@echo "=== fixed-point gates ==="
|
|
@cmp $(BS)/ww2 $(BS)/ww3 && echo " ww2 == ww3 ✓ (byte-identical exe)"
|
|
@cmp $(BS)/ww3 $(BS)/ww4 && echo " ww3 == ww4 ✓ (byte-identical exe, ww3 is byte-stable as a compiler)"
|
|
@echo
|
|
@echo "BOOTSTRAP OK: ww-cgen (w6c) + w6a_ww + w6l_ww reach a fixed point that holds across two iterations (sep path)."
|
|
@echo
|
|
@echo "Phase 10 remaining work:"
|
|
@echo " - delete cmd/wcc/ cmd/w6c/ cmd/w6a/ cmd/w6l/ cmd/ww/ in the final commit"
|
|
@echo
|
|
@echo "Already in selfhost/:"
|
|
@echo " - cmd/wcc/ : ww-cgen (lex/parse/check/cgen) — bootstrap fixed point"
|
|
@echo " - cmd/w6c/ : ww-w6c (lex/parse/cgen front-end) — matches wwdump_ww -c (test 994)"
|
|
@echo " - cmd/w6a/ : ww-w6a (lex/parse/asm/obj) — byte-identical to C w6a (test 991)"
|
|
@echo " - cmd/w6l/ : ww-w6l (linker w/ archive support) — byte-identical to C w6l (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,w6c,w6a,w6l}` 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)/w6c_ww $(STAGE0)/w6c
|
|
@cp $(BIN)/w6a_ww $(STAGE0)/w6a
|
|
@cp $(BIN)/w6l_ww $(STAGE0)/w6l
|
|
@echo "snapshot: $(STAGE0)/{ww,w6c,w6a,w6l} populated from $(BIN)/*_ww"
|
|
@echo " (gitignored — 'git add -f bootstrap/$(ARCH)/*' to ship)"
|
|
|
|
nocc:
|
|
@for f in ww w6c w6a w6l; 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 w6c w6a w6l; do \
|
|
cp $(STAGE0)/$$f $(NOCC_BIN)/$$f; \
|
|
cp $(STAGE0)/$$f $(NOCC_BIN)/$${f}_ww; \
|
|
done
|
|
@# Assemble libwwrt.a using stage-0 w6a — 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)/w6a -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 -o main \
|
|
-I $(CURDIR)/lib/ww \
|
|
-I $(CURDIR)/selfhost/cmd/wcc \
|
|
-I $(CURDIR)/lib $(CURDIR)/selfhost/cmd/w6c/main.ww && mv main w6c_ww1
|
|
@cd $(NOCC_BIN) && ./ww build -o main -I $(CURDIR)/selfhost/cmd/w6a \
|
|
-I $(CURDIR)/selfhost/cmd/wcc -I $(CURDIR)/lib \
|
|
$(CURDIR)/selfhost/cmd/w6a/main.ww && mv main w6a_ww1
|
|
@cd $(NOCC_BIN) && ./ww build -o main -I $(CURDIR)/selfhost/cmd/w6l \
|
|
-I $(CURDIR)/selfhost/cmd/wcc -I $(CURDIR)/lib \
|
|
$(CURDIR)/selfhost/cmd/w6l/main.ww && mv main w6l_ww1
|
|
@cd $(NOCC_BIN) && ./ww build -o main -I $(CURDIR)/selfhost/cmd/wcc \
|
|
-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)/w6c_ww1 $(STAGE0)/w6c && echo " w6c ✓"
|
|
@cmp $(NOCC_BIN)/w6a_ww1 $(STAGE0)/w6a && echo " w6a ✓"
|
|
@cmp $(NOCC_BIN)/w6l_ww1 $(STAGE0)/w6l && echo " w6l ✓"
|
|
@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 wwfixture test-wwfixture-process test-wwfixture \
|
|
test test-unit test-compiler-smoke test-compiler test-package \
|
|
test-lang test-library test-commit test-lang-byteid \
|
|
$(LANG_TEST_TARGETS) $(LIBRARY_TEST_TARGETS) $(BYTEID_WW_TARGETS) \
|
|
$(SEP_WW_TARGETS) test-data-byteid test-byteid \
|
|
test-bootstrap-native test-bootstrap test-incremental \
|
|
test-platform test-all install clean bootstrap nocc bootstrap-snapshot
|