maint.mk (4636B)
1 # mk/maint.mk 2 # =========================================================================== 3 # Developer maintenance targets: source formatting, the clangd compilation 4 # database, optimizer benchmarking, and clean. 5 6 .PHONY: format compile-commands bench-opt bench-cc perf-golden perf-gate code-size clean \ 7 regen-gram-meta regen-gram-unicode-props 8 9 # Format only the .c/.h files changed in the working tree (staged, unstaged, or 10 # new/untracked), restricted to the formatted roots and excluding test/pp. When 11 # nothing has changed, fall back to formatting every source file. 12 format: 13 @files=$$( { git diff --name-only --diff-filter=ACMR HEAD -- '*.c' '*.h'; \ 14 git ls-files --others --exclude-standard -- '*.c' '*.h'; } 2>/dev/null \ 15 | grep -E '^(src|include|driver|lang|test|rt)/' \ 16 | grep -vE '^test/pp/' \ 17 | sort -u ); \ 18 if [ -n "$$files" ]; then \ 19 echo "$$files" | xargs clang-format -i --style=google; \ 20 echo "$$files" | sed 's/^/formatted /'; \ 21 else \ 22 echo "no changed sources; formatting all"; \ 23 find src include driver lang test rt -path test/pp -prune -o \( -name '*.c' -o -name '*.h' \) -print | xargs clang-format -i --style=google; \ 24 fi 25 26 # Regenerate the gram meta-grammar parse tables (src/gram/meta_tables.{c,h}) 27 # from src/gram/meta.ebnf using the just-built `kit gram`. Output is checked in 28 # so ordinary builds need no generator bootstrap; commit the result and `git 29 # diff` shows any drift. 30 regen-gram-meta: bin 31 $(BIN) gram --prefix kit_gram_meta_ -o src/gram/meta_tables.c \ 32 --header src/gram/meta_tables.h src/gram/meta.ebnf 33 34 # Regenerate the gram Unicode property tables (src/gram/unicode_props.{c,h}) 35 # from the vendored, checksummed UCD. Offline and reproducible; run after 36 # bumping data/ucd/<version>/ and commit (git diff = drift). No build needed. 37 regen-gram-unicode-props: 38 python3 scripts/gen_gram_unicode_props.py data/ucd/17.0.0/ppucd.txt \ 39 --header src/gram/unicode_props.h --source src/gram/unicode_props.c 40 41 # Regenerate the clangd compilation database (build/compile_commands.json). 42 # clangd auto-discovers it under build/; re-run after adding/removing sources 43 # or after `make clean`. 44 compile-commands: 45 python3 scripts/gen_compile_commands.py 46 47 bench-opt: 48 $(MAKE) RELEASE=1 bin 49 @KIT='$(abspath build/release/kit)' bash scripts/opt_bench.sh 50 51 # -O0 C compile+link throughput/scaling benchmark + hotspot sampling. Builds a 52 # release kit with clang (-O2, but with -g and without the symbol strip so 53 # `sample` can attribute hotspots) into build/bench/kit, then sweeps each input 54 # axis and fits a scaling exponent. Design + findings: doc/plan/PERF.md. 55 bench-cc: 56 $(MAKE) RELEASE=1 PROFILE=1 CC=clang BUILD_DIR=build/bench bin 57 @KIT='$(abspath build/bench/kit)' bash scripts/cc_bench.sh 58 59 # Perf A/B harness. `perf-golden` builds the current source as RELEASE and 60 # snapshots it as a SELF-CONTAINED golden under build/release/golden/: the 61 # copied binary sits next to its own support/rt symlink (the `%/support/rt` 62 # pattern rule in Makefile), so it resolves its runtime from any cwd without 63 # living in the checkout's build dir — the old "support dir not found" gotcha 64 # when a golden was copied to /tmp. Workflow (see doc/plan/PERF.md): 65 # make perf-golden # snapshot the pre-change build as golden 66 # <edit>; make bin RELEASE=1 # rebuild build/release/kit as the candidate 67 # make perf-gate # byte-identity gate: golden vs candidate 68 PERF_GOLDEN_DIR = build/release/golden 69 perf-golden: $(PERF_GOLDEN_DIR)/support/rt 70 $(MAKE) RELEASE=1 bin 71 cp build/release/kit $(PERF_GOLDEN_DIR)/kit 72 @echo "perf golden snapshot: $(PERF_GOLDEN_DIR)/kit (self-contained; runs from any cwd)" 73 74 perf-gate: 75 @GOLDEN='$(abspath $(PERF_GOLDEN_DIR)/kit)' CAND='$(abspath build/release/kit)' \ 76 bash scripts/perf_identity_gate.sh 77 78 # Regenerate doc/CODE_SIZE.md: per-component cloc line counts plus a binary 79 # code-size section attributed from the release linker map. Requires cloc. 80 # The map step relinks the release objects explicitly (not via libkit.a) so the 81 # full object paths survive in the map and dead_strip still prunes unused code. 82 RELMAP = build/release/kit.map 83 ifeq ($(HOST_OS),darwin) 84 RELMAP_LDFLAG = -Wl,-map,$(RELMAP) 85 else 86 RELMAP_LDFLAG = -Wl,-Map=$(RELMAP) 87 endif 88 89 code-size: 90 $(MAKE) RELEASE=1 bin 91 $(MAKE) RELEASE=1 $(RELMAP) 92 bash scripts/code_size.sh $(RELMAP) 93 94 # Release binary relinked with a linker map (consumed by code-size). 95 $(RELMAP): $(DRIVER_OBJS) $(LIB_OBJS) 96 $(CC) $(HOST_LDFLAGS) $(RELMAP_LDFLAG) -o $(BIN) $(DRIVER_OBJS) $(LIB_OBJS) $(HOST_LDLIBS) 97 98 clean: 99 rm -rf $(BUILD_DIR)