ww: own the scratch contract, drop the package cache, add -S

Scratch acquisition is one bare mkdir that refuses a pre-existing
.sepwork; the path reaches cleanup only after acquisition succeeds.
ww build and ww test -o keep the tree for the caller; ww run and
no-output ww test build under an owned /tmp/ww_{run,test}_<pid> dir
and remove it on every result, escalating rc on cleanup failure.
The content-keyed package cache is deleted from both stages; -S stops
after per-package .s emission; --sep is gone and unknown flags are
rejected; directory ww test delegates to the wwtest coordinator; the
wwstage driver routes every subprocess through os.exec.

The wwstage Makefile recipes move off the persistent <tool>_ww.d
build-in-place shape to a per-invocation mktemp workspace: the old
recipes relied on the retired pre-wipe semantics and any rebuild
would trip the new refusal on their leftover main.sepwork.

The three 989_pkgcache_* carriers lose their subject with the cache
and go with it; the rest of the wave's carrier adaptation follows in
its own commits.
This commit is contained in:
2026-08-07 23:12:54 +09:00
parent 7a2c21acfb
commit 350bcd8913
7 changed files with 1243 additions and 2032 deletions

View File

@@ -132,12 +132,16 @@ $(BIN)/wwdump_ww: selfhost/cmd/wwdump/main.ww \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
@mkdir -p $(BIN)/wwdump_ww.d
cd $(BIN)/wwdump_ww.d && $(CURDIR)/$(BIN)/ww build \
-o main \
-I $(CURDIR)/lib/ww \
-I $(CURDIR)/selfhost/cmd/wcc \
$(CURDIR)/selfhost/cmd/wwdump/main.ww
mv $(BIN)/wwdump_ww.d/main $@
@d=$$(mktemp -d "$(CURDIR)/$(BIN)/wwdump_ww.d/build.XXXXXX") || exit 1; \
rc=0; published=0; \
(cd "$$d" && $(CURDIR)/$(BIN)/ww build -o main \
-I $(CURDIR)/lib/ww -I $(CURDIR)/selfhost/cmd/wcc \
$(CURDIR)/selfhost/cmd/wwdump/main.ww) || rc=$$?; \
rm -rf -- "$$d/main.sepwork" || { echo "$@: scratch cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; \
if [ $$rc -eq 0 ]; then mv "$$d/main" "$(CURDIR)/$@" && published=1 || rc=$$?; fi; \
if [ $$published -eq 0 ]; then rm -f -- "$$d/main" || { echo "$@: output cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; fi; \
if ! rmdir "$$d"; then echo "$@: workspace cleanup failed" >&2; if [ $$published -eq 1 ]; then rm -f -- "$(CURDIR)/$@" || echo "$@: published-output cleanup failed" >&2; fi; if [ $$rc -eq 0 ]; then rc=1; fi; fi; \
exit $$rc
# ---- ww-side w6c (compiler port, exercised by 994_w6c_ww) -------------
# Thin driver: parse + cgen. The frontend (lex/parse/ast/...) is the
@@ -153,12 +157,16 @@ $(BIN)/w6c_ww: selfhost/cmd/w6c/main.ww \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
@mkdir -p $(BIN)/w6c_ww.d
cd $(BIN)/w6c_ww.d && $(CURDIR)/$(BIN)/ww build \
-o main \
-I $(CURDIR)/lib/ww \
-I $(CURDIR)/selfhost/cmd/wcc \
$(CURDIR)/selfhost/cmd/w6c/main.ww
mv $(BIN)/w6c_ww.d/main $@
@d=$$(mktemp -d "$(CURDIR)/$(BIN)/w6c_ww.d/build.XXXXXX") || exit 1; \
rc=0; published=0; \
(cd "$$d" && $(CURDIR)/$(BIN)/ww build -o main \
-I $(CURDIR)/lib/ww -I $(CURDIR)/selfhost/cmd/wcc \
$(CURDIR)/selfhost/cmd/w6c/main.ww) || rc=$$?; \
rm -rf -- "$$d/main.sepwork" || { echo "$@: scratch cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; \
if [ $$rc -eq 0 ]; then mv "$$d/main" "$(CURDIR)/$@" && published=1 || rc=$$?; fi; \
if [ $$published -eq 0 ]; then rm -f -- "$$d/main" || { echo "$@: output cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; fi; \
if ! rmdir "$$d"; then echo "$@: workspace cleanup failed" >&2; if [ $$published -eq 1 ]; then rm -f -- "$(CURDIR)/$@" || echo "$@: published-output cleanup failed" >&2; fi; if [ $$rc -eq 0 ]; then rc=1; fi; fi; \
exit $$rc
# ---- ww-side w6a (assembler port, exercised by 991_w6a_ww) ------------
# Built like wwdump_ww. Needs -I selfhost/cmd/w6a for the local types/lex/
@@ -171,11 +179,16 @@ $(BIN)/w6a_ww: selfhost/cmd/w6a/main.ww selfhost/cmd/w6a/opcodes.ww \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
@mkdir -p $(BIN)/w6a_ww.d
cd $(BIN)/w6a_ww.d && $(CURDIR)/$(BIN)/ww build \
-o main \
-I $(CURDIR)/selfhost/cmd/w6a \
$(CURDIR)/selfhost/cmd/w6a/main.ww
mv $(BIN)/w6a_ww.d/main $@
@d=$$(mktemp -d "$(CURDIR)/$(BIN)/w6a_ww.d/build.XXXXXX") || exit 1; \
rc=0; published=0; \
(cd "$$d" && $(CURDIR)/$(BIN)/ww build -o main \
-I $(CURDIR)/selfhost/cmd/w6a \
$(CURDIR)/selfhost/cmd/w6a/main.ww) || rc=$$?; \
rm -rf -- "$$d/main.sepwork" || { echo "$@: scratch cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; \
if [ $$rc -eq 0 ]; then mv "$$d/main" "$(CURDIR)/$@" && published=1 || rc=$$?; fi; \
if [ $$published -eq 0 ]; then rm -f -- "$$d/main" || { echo "$@: output cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; fi; \
if ! rmdir "$$d"; then echo "$@: workspace cleanup failed" >&2; if [ $$published -eq 1 ]; then rm -f -- "$(CURDIR)/$@" || echo "$@: published-output cleanup failed" >&2; fi; if [ $$rc -eq 0 ]; then rc=1; fi; fi; \
exit $$rc
# ---- 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/
@@ -189,25 +202,36 @@ $(BIN)/w6l_ww: selfhost/cmd/w6l/main.ww selfhost/cmd/w6l/sym.ww \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
@mkdir -p $(BIN)/w6l_ww.d
cd $(BIN)/w6l_ww.d && $(CURDIR)/$(BIN)/ww build \
-o main \
-I $(CURDIR)/selfhost/cmd/w6l \
$(CURDIR)/selfhost/cmd/w6l/main.ww
mv $(BIN)/w6l_ww.d/main $@
@d=$$(mktemp -d "$(CURDIR)/$(BIN)/w6l_ww.d/build.XXXXXX") || exit 1; \
rc=0; published=0; \
(cd "$$d" && $(CURDIR)/$(BIN)/ww build -o main \
-I $(CURDIR)/selfhost/cmd/w6l \
$(CURDIR)/selfhost/cmd/w6l/main.ww) || rc=$$?; \
rm -rf -- "$$d/main.sepwork" || { echo "$@: scratch cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; \
if [ $$rc -eq 0 ]; then mv "$$d/main" "$(CURDIR)/$@" && published=1 || rc=$$?; fi; \
if [ $$published -eq 0 ]; then rm -f -- "$$d/main" || { echo "$@: output cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; fi; \
if ! rmdir "$$d"; then echo "$@: workspace cleanup failed" >&2; if [ $$published -eq 1 ]; then rm -f -- "$(CURDIR)/$@" || echo "$@: published-output cleanup failed" >&2; fi; if [ $$rc -eq 0 ]; then rc=1; fi; fi; \
exit $$rc
# ---- 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/os.ww lib/rt/malloc.ww \
$(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/strconv/strconv.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 $(BIN)/ww_ww.d
cd $(BIN)/ww_ww.d && $(CURDIR)/$(BIN)/ww build \
-o main \
$(CURDIR)/selfhost/cmd/ww/main.ww
mv $(BIN)/ww_ww.d/main $@
@d=$$(mktemp -d "$(CURDIR)/$(BIN)/ww_ww.d/build.XXXXXX") || exit 1; \
rc=0; published=0; \
(cd "$$d" && $(CURDIR)/$(BIN)/ww build -o main \
$(CURDIR)/selfhost/cmd/ww/main.ww) || rc=$$?; \
rm -rf -- "$$d/main.sepwork" || { echo "$@: scratch cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; \
if [ $$rc -eq 0 ]; then mv "$$d/main" "$(CURDIR)/$@" && published=1 || rc=$$?; fi; \
if [ $$published -eq 0 ]; then rm -f -- "$$d/main" || { echo "$@: output cleanup failed" >&2; if [ $$rc -eq 0 ]; then rc=1; fi; }; fi; \
if ! rmdir "$$d"; then echo "$@: workspace cleanup failed" >&2; if [ $$published -eq 1 ]; then rm -f -- "$(CURDIR)/$@" || echo "$@: published-output cleanup failed" >&2; fi; if [ $$rc -eq 0 ]; then rc=1; fi; fi; \
exit $$rc
# ---- runtime (libwwrt.a, assembled by our own w6a) ---------------------
$(OBJ)/rt/%.o: rt/%.s $(BIN)/w6a | $(OBJ)/rt