aboutsummaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile141
1 files changed, 75 insertions, 66 deletions
diff --git a/Makefile b/Makefile
index 6a3898d..7f8f3f2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,27 +1,30 @@
# tinyvm and zc. `make` builds the tools, the interpreter, the microcore and the
-# language server into bin/. nothing built is kept in the tree.
+# language server into build/bin/. everything built or generated goes under
+# build/; the tree holds sources only, and `make clean` (rm -rf build) returns it
+# to a fresh checkout.
#
# make everything below that is a program
# make test the whole suite (tests/test.sh)
# make check the minimal suite, for iterating (tests/test.sh -q)
# make test JOBS=4 the same, four sections at a time
-# make genome rebuild build/core/genome.h from src/ and check the fixpoint
-# make lsp bin/zclsp, the language server
-# make web src/web/zc.wasm (needs clang with the wasm32 target)
-# make js build/js/genome.json and the vm, for the javascript vm
+# make genome build/core/genome.bin from src/, with the fixpoint check
+# make lsp build/bin/zclsp, the language server
+# make web build/web/: the page, its script and zc.wasm
+# make js build/js/: the javascript vm, its layout and genome
# make run PROG=examples/hello.zc
# compile one program into a run-only image on a memory
# map sized to it (src/tools/automap.sh) -> build/run/zymr
# make vsix the vscode extension, server and all
-# make clean remove bin/ and build/ and the web build
+# make clean remove build/
#
-# nothing built is kept in the tree: the genome, the javascript vm and its
-# layout, and the packed editor server all land in build/ (the web build keeps
-# its historical src/web/zc.wasm path because the page loads it by name).
-#
-# CC picks the compiler (cc by default; clang works too).
+# the cores take their genome in with c23 #embed (src/core/genome.h), so CC has
+# to be clang 19 or gcc 15 or later. src/tools/findcc.sh picks one when CC is
+# not given on the command line or in the environment.
-CC ?= cc
+ifeq ($(origin CC),default)
+ CC := $(shell sh src/tools/findcc.sh || echo cc)
+endif
+export CC
CFLAGS ?= -O2 -w -fwrapv
ifeq ($(OS),Windows_NT)
EXE := .exe
@@ -35,99 +38,105 @@ else
MICRO_THREADS := -DZY_THREADS
endif
-BIN := bin
B := build
+BIN := $(B)/bin
JS := $(B)/js
-# the hand-written core headers, then the generated genome beside them
-COREINC := -Isrc/core -I$(B)/core
-# the sources the compiler genome is built from
+WEB := $(B)/web
+# the default memory map, generated from the const blocks in the zc sources
+MAP := $(B)/core/map
+# hand-written core headers, the generated map, and where #embed finds the genome image
+COREINC := -Isrc/core -I$(MAP) --embed-dir=$(B)/core
+CORE_H := src/core/genome.h src/core/fops.h src/core/bops.h src/core/stack.h $(MAP)/memmap.h
+# the sources the compiler genome is built from, and the files it embeds
ZC_SRC := src/runtime/rt.zc src/core/core.zc src/compiler/compiler.zc
+ZC_DEPS := $(ZC_SRC) src/lib/std.zc src/lib/icon.zc src/tools/build.zc
TOOLS := $(BIN)/zc0$(EXE) $(BIN)/mkgenome$(EXE) $(BIN)/genmap$(EXE)
PROGS := $(BIN)/zy$(EXE) $(BIN)/zym$(EXE) $(BIN)/zclsp$(EXE)
all: $(TOOLS) $(PROGS)
-$(BIN) $(B):
+$(BIN):
mkdir -p $@
-$(BIN)/zc0$(EXE): src/tools/zc0.c src/core/memmap.h src/core/fops.h src/core/bops.h | $(BIN)
- $(CC) -O1 -w -fwrapv src/tools/zc0.c -Isrc/core -o $@
-$(BIN)/mkgenome$(EXE): src/tools/mkgenome.c src/core/memmap.h | $(BIN)
- $(CC) -O1 -w -fwrapv src/tools/mkgenome.c -Isrc/core -o $@
+# genmap needs no map of its own; everything else is built against the one it writes
$(BIN)/genmap$(EXE): src/tools/genmap.c | $(BIN)
- $(CC) $(CFLAGS) src/tools/genmap.c -Isrc/core -o $@
+ $(CC) $(CFLAGS) src/tools/genmap.c -o $@
+$(MAP)/memmap.h: $(BIN)/genmap$(EXE) src/runtime/rt.zc src/compiler/compiler.zc
+ mkdir -p $(B)/core
+ $(BIN)/genmap$(EXE) --preset default --check -o $(MAP) >$(B)/core/genmap.log 2>&1 || { cat $(B)/core/genmap.log; exit 1; }
+$(BIN)/zc0$(EXE): src/tools/zc0.c src/core/fops.h src/core/bops.h $(MAP)/memmap.h | $(BIN)
+ $(CC) -O1 -w -fwrapv src/tools/zc0.c -Isrc/core -I$(MAP) -o $@
+$(BIN)/mkgenome$(EXE): src/tools/mkgenome.c $(MAP)/memmap.h | $(BIN)
+ $(CC) -O1 -w -fwrapv src/tools/mkgenome.c -I$(MAP) -o $@
+
+# bootstrap: zc0 compiles the compiler to g0, g0 compiles it to g1, g1 to g2.
+# g1 and g2 must be identical (the fixpoint), and g1 becomes build/core/genome.bin.
+# each stage's core embeds the image beside it, so no stage reads another's.
+genome: $(B)/core/genome.bin
+$(B)/core/genome.bin: $(ZC_DEPS) $(BIN)/zc0$(EXE) $(BIN)/mkgenome$(EXE) src/core/core.c $(IO) $(CORE_H)
+ mkdir -p $(B)/s0 $(B)/s1 $(B)/core
+ cat $(ZC_SRC) | $(BIN)/zc0$(EXE) > $(B)/s0/g0.bin
+ $(BIN)/mkgenome$(EXE) < $(B)/s0/g0.bin > $(B)/s0/genome.bin
+ $(CC) $(CFLAGS) -DJTYPE=int src/core/core.c $(IO) -Isrc/core -I$(MAP) --embed-dir=$(B)/s0 -o $(B)/s0/zy0$(EXE)
+ (cat src/tools/build.zc; printf '`'; cat $(ZC_SRC)) | $(B)/s0/zy0$(EXE) > $(B)/s1/g1.bin
+ $(BIN)/mkgenome$(EXE) < $(B)/s1/g1.bin > $(B)/s1/genome.bin
+ $(CC) $(CFLAGS) -DJTYPE=int src/core/core.c $(IO) -Isrc/core -I$(MAP) --embed-dir=$(B)/s1 -o $(B)/s1/zy1$(EXE)
+ (cat src/tools/build.zc; printf '`'; cat $(ZC_SRC)) | $(B)/s1/zy1$(EXE) > $(B)/s1/g2.bin
+ cmp $(B)/s1/g1.bin $(B)/s1/g2.bin
+ cp $(B)/s1/genome.bin $@
+ @echo "fixpoint: $$(( $$(wc -c < $@) / 8 )) words, $@ updated"
# the interpreter: the vm core with the compiler genome inside
-$(BIN)/zy$(EXE): src/core/core.c $(IO) $(B)/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h | $(BIN)
+$(BIN)/zy$(EXE): src/core/core.c $(IO) $(B)/core/genome.bin $(CORE_H) | $(BIN)
$(CC) $(CFLAGS) -DJTYPE=int src/core/core.c $(IO) $(COREINC) -o $@
# the portable microcore
-$(BIN)/zym$(EXE): src/micro/micro.c src/micro/micro_port.h $(PORT) $(B)/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h | $(BIN)
+$(BIN)/zym$(EXE): src/micro/micro.c src/micro/micro_port.h $(PORT) $(B)/core/genome.bin $(CORE_H) | $(BIN)
$(CC) $(CFLAGS) $(MICRO_THREADS) src/micro/micro.c $(PORT) $(COREINC) -Isrc/micro -o $@
# the language server is the compiler in check mode plus src/lsp/server.zc, on a map
# sized to it
+LSP_DEPS := src/core/core.c src/core/io_linux.c $(filter-out $(MAP)/memmap.h,$(CORE_H)) $(ZC_DEPS) src/lsp/server.zc \
+ src/tools/zc0.c src/tools/genmap.c src/tools/mkgenome.c src/tools/automap.sh src/tools/mklsp.sh
lsp: $(BIN)/zclsp$(EXE)
-$(BIN)/zclsp$(EXE): src/core/core.c src/core/io_linux.c src/core/fops.h src/core/bops.h src/core/stack.h src/core/memmap.h src/runtime/rt.zc src/core/core.zc src/compiler/compiler.zc src/lsp/server.zc src/lib/std.zc src/lib/icon.zc src/tools/embed.sh src/tools/zc0.c src/tools/genmap.c src/tools/automap.sh src/tools/mklsp.sh | $(BIN)
- CC="$(CC)" bash src/tools/mklsp.sh $(B)/lsp
+$(BIN)/zclsp$(EXE): $(LSP_DEPS) | $(BIN)
+ bash src/tools/mklsp.sh $(B)/lsp
cp $(B)/lsp/zclsp$(EXE) $@
-src/compiler/compiler.zc: src/lib/std.zc src/lib/icon.zc src/tools/embed.sh
- bash src/tools/embed.sh all
-
-# bootstrap: zc0 compiles the compiler to g0, g0 compiles it to g1, g1 to g2.
-# g1 and g2 must be identical (the fixpoint), and g1 becomes build/core/genome.h.
-# run this by hand after editing a .zc source; `make check` reports a stale genome.
-genome: $(BIN)/zc0$(EXE) $(BIN)/mkgenome$(EXE) src/compiler/compiler.zc | $(B)
- mkdir -p $(B)/s0 $(B)/s1 $(B)/core
- cp src/core/core.c $(IO) src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h $(B)/s0/
- cp src/core/core.c $(IO) src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h $(B)/s1/
- cat $(ZC_SRC) | $(BIN)/zc0$(EXE) > $(B)/s0/genome.h
- $(CC) $(CFLAGS) -DJTYPE=int $(B)/s0/core.c $(B)/s0/$(notdir $(IO)) -o $(B)/zy0$(EXE)
- (cat src/tools/build.zc; printf '`'; cat $(ZC_SRC)) | $(B)/zy0$(EXE) > $(B)/g1.bin
- $(BIN)/mkgenome$(EXE) < $(B)/g1.bin > $(B)/s1/genome.h
- $(CC) $(CFLAGS) -DJTYPE=int $(B)/s1/core.c $(B)/s1/$(notdir $(IO)) -o $(B)/zy1$(EXE)
- (cat src/tools/build.zc; printf '`'; cat $(ZC_SRC)) | $(B)/zy1$(EXE) > $(B)/g2.bin
- cmp $(B)/g1.bin $(B)/g2.bin
- cp $(B)/s1/genome.h $(B)/core/genome.h
- @echo "fixpoint: $$(( $$(wc -c < $(B)/g1.bin) / 8 )) words, $(B)/core/genome.h updated"
-
-# a fresh clone has no genome, so bootstrap one on demand. it is deliberately
-# not rebuilt from source dependencies: the fixpoint run is expensive, and
-# `make genome` is the explicit way to refresh it after editing a .zc file.
-$(B)/core/genome.h:
- $(MAKE) genome
-
-js: $(JS)/genome.json $(JS)/layout.js $(JS)/tinyvm.js
+# the javascript vm: tinyvm.js loads genome.bin from beside itself
+js: $(JS)/tinyvm.js $(JS)/layout.js $(JS)/genome.bin
$(JS):
mkdir -p $@
-$(JS)/genome.json: $(B)/core/genome.h src/core/memmap.h src/js/extract_genome.js src/js/mapvalues.js | $(JS)
- node src/js/extract_genome.js
-$(JS)/layout.ts $(JS)/layout.js: $(JS)/genome.json
- @test -f $@ || node src/js/extract_genome.js
+$(JS)/genome.bin: $(B)/core/genome.bin | $(JS)
+ cp $< $@
+$(JS)/layout.js: $(MAP)/memmap.h src/js/mklayout.js src/js/mapvalues.js | $(JS)
+ node src/js/mklayout.js --map $(MAP)/memmap.h --out $(JS)
$(JS)/tinyvm.js: src/js/tinyvm.ts src/js/layout.d.ts | $(JS)
tsc src/js/tinyvm.ts --target es2020 --lib es2020,dom --module commonjs --outDir $(JS)
# the language server image for the javascript vm, and the wasm server
-lspimage: $(JS)/lsp.json
-$(JS)/lsp.json: $(BIN)/zclsp$(EXE) src/js/extract_lsp.js src/js/mapvalues.js | $(JS)
+lspimage: $(JS)/lsp.bin
+$(JS)/lsp.bin: $(BIN)/zclsp$(EXE) src/js/extract_lsp.js src/js/mapvalues.js | $(JS)
node src/js/extract_lsp.js
# the vscode extension, with the server and its image inside it
-vsix: | $(B)
+vsix:
bash src/tools/mkvsix.sh
-web: src/web/zc.wasm
-src/web/zc.wasm: src/micro/micro.c src/micro/micro_port.h src/web/port_wasm.c src/web/build.sh $(B)/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h
+# the browser compiler: the page and its loader beside the wasm build
+web: $(WEB)/zc.wasm $(WEB)/index.html $(WEB)/zc.js
+$(WEB)/zc.wasm: src/micro/micro.c src/micro/micro_port.h src/web/port_wasm.c src/web/build.sh $(B)/core/genome.bin $(CORE_H)
bash src/web/build.sh $@
+$(WEB)/index.html $(WEB)/zc.js: $(WEB)/%: src/web/%
+ mkdir -p $(WEB)
+ cp $< $@
# one program as a run-only image: the runtime, the program, and a map exactly
# big enough for them
-run: | $(B)
+run:
@test -n "$(PROG)" || { echo "make run PROG=examples/hello.zc"; exit 2; }
bash src/tools/automap.sh run $(B)/run src/runtime/run.zc $(PROG)
- cp src/micro/micro.c src/micro/micro_port.h $(PORT) src/core/fops.h src/core/bops.h src/core/stack.h $(B)/run/
- $(CC) $(CFLAGS) $(MICRO_THREADS) $(B)/run/micro.c $(B)/run/$(notdir $(PORT)) -I$(B)/run -o $(B)/run/zymr$(EXE)
+ $(CC) $(CFLAGS) $(MICRO_THREADS) src/micro/micro.c $(PORT) -Isrc/core -Isrc/micro -I$(B)/run --embed-dir=$(B)/run -o $(B)/run/zymr$(EXE)
@echo "built $(B)/run/zymr$(EXE)"
# JOBS sets how many sections run at once: make test JOBS=4
@@ -139,6 +148,6 @@ check:
bash tests/test.sh -q -j $(or $(JOBS),2)
clean:
- rm -rf $(BIN) $(B) src/web/zc.wasm
+ rm -rf $(B)
.PHONY: all lsp genome js lspimage vsix web run test check clean