From 5d6c9899d4b1a6584c6afb50d8f9dd920588f577 Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 23 Jul 2026 16:18:43 +0000 Subject: [PATCH] build: serialize module@X/lib@X per directory to fix a -j race main@ depends on both `modules` and `libs`, so `module@X` (`make -C X module`) and `lib@X` (`make -C X lib`) could run in the same directory concurrently under -j and race on X's shared objects -- each %.o recipe does `rm $*.o; cc -c`, so one make would delete/rebuild an object while the other was linking it, e.g. `ld: cannot find touchtypes.o` while linking libutils.o. It was rare (timing dependent) but real; it surfaced on a --without-tcl --disable-readline -j12 build. Make `lib@%` depend on its own `module@%`: module@X builds the objects, lib@X then only archives them, so the two never touch X's *.o at the same time. Cross-directory parallelism is unchanged (lib@X waits only on module@X, not the whole modules phase). Verified: 4/4 clean --without-tcl -j12 builds pass (previously intermittently failed); Tcl -j12 still builds 375 files. Co-Authored-By: Claude Opus 4.8 (1M context) --- Makefile.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 65aec6ff..06afd531 100644 --- a/Makefile.in +++ b/Makefile.in @@ -106,7 +106,13 @@ LIB_TARGETS := $(addprefix lib@,${MODULES}) .PHONY: $(MODULE_TARGETS) $(LIB_TARGETS) $(MODULE_TARGETS): module@%: ${DATABASE_H} @$(call submake,$*,module) -$(LIB_TARGETS): lib@%: ${DATABASE_H} +# lib@X depends on module@X (its OWN module): main@ pulls both `modules` and +# `libs`, so without this `make -C X module` and `make -C X lib` can run in the +# same directory at once under -j and race on X's shared *.o (each recipe does +# `rm $*.o; cc -c $*.o`). Serializing them per-dir removes the race; module@X +# builds the objects and lib@X then just archives them. Cross-dir parallelism is +# unaffected (lib@X only waits on module@X, not the whole modules phase). +$(LIB_TARGETS): lib@%: ${DATABASE_H} module@% @$(call submake,$*,lib) # Cross-module archive edge (-j correctness): libdatabase.a physically archives