Repository navigation
Description
build/flags.stamp invalidation is target-independent: a maintenance target that builds no PRG still deletes every object and the PRG, and leaves the stale .map behind
Summary
#159's stamp compare runs at Makefile parse time, which is the whole point of the design and is correct. The consequence that is not written down anywhere: it runs whatever target you asked for. make ip65-libs and make ip65-blob — neither of which produces a PRG — will delete every .o and build/c64-https.prg if their (flagless) command line expands differently from the stamped one.
Worse, and this is the part that actually costs you: build/c64-https.map is NOT deleted. You are left with a map file that corresponds to no artifact in the tree, in a repo where every memory-margin figure is measured off exactly that file.
This is not a bug report against #159's behaviour, which is sound and enforced by tools/test_build_flags_stamp.py. It is a request to (a) document the target-independence and (b) decide whether the surviving .map is acceptable.
Measured
All from a clean checkout at master 02e5662, libs/nistcurves v0.14.0.
Baseline — make BACKEND=uci USE_NISTCURVES_ONCHIP_COMB=1: 24 objects, PRG 00e4370ce3086e8b30df243861e56725a09797f08d8e668535c5166c62882152.
| invocation after that build | objects | PRG | map |
|---|---|---|---|
make -n ip65-libs |
24 | present | present |
make ip65-libs |
0 | gone | present (stale) |
make ip65-blob |
0 | gone | present (stale) |
make BACKEND=uci USE_NISTCURVES_ONCHIP_COMB=1 ip65-libs |
24 | present | present |
So:
- It is not
ip65-libs-specific.ip65-blobdoes it too. It is any real invocation whose expandedCA65FLAGS/LD65FLAGSdiffer from the stamp — the target is irrelevant, because the compare happens before target selection. - Carrying the same flags through preserves everything (row 4). That is the workaround, and it is not obvious: you have to know to repeat build flags on a target that does not use them.
-nis correctly exempt and even says so, which ismake -ndeletes all objects and the PRG: the flag-stamp compare runs at parse time #174 working exactly as designed:Makefile:781: A real build would rewrite the stamp and delete every object and build/c64-https.prg Makefile:782: at parse time. NOTHING was deleted; the tree is untouched.
Why it matters here specifically
CLAUDE.md's Memory-layout section demands that margin figures be re-measured in all five profiles off build/c64-https.map, and names "corrected in one profile, left stale in the other four" as the recurring failure. The natural way to do that is: build a profile, read the map, build the next. If anything in that loop shells out to a maintenance target without repeating the flags, the map silently stops matching the PRG — and a .map that survives its .os gives no signal that it has gone stale. Every number in it still parses fine.
This was hit for real while measuring the uci-comb CRYPTO_OVERLAY tail for #193 (the 153 B → 126 B correction on fix/triage-quickwins); the measurement was saved first, by luck rather than by rule.
Suggested resolution
Pick one or more:
- Docs (cheapest). CLAUDE.md's Build section describes
flags.stampat length but frames it entirely as protecting builds. Add that the compare is target-independent, that a flagless maintenance target therefore invalidates, and that repeating the flags is the way to avoid it. Themake ip65-libs/make ip65-blobbullets are the place a reader would look. - Delete the
.mapalongside the PRG. One line in the invalidation, and it converts a silently-stale measurement source into an absent one — the same argument$(PRG)'s recipe already makes forrm -fing the target ("an absent PRG is the honest state after a failed link"). The map deserves the same treatment for the same reason. - Exempt the maintenance targets. Probably wrong — it reintroduces exactly the "make skipped an invalidation it needed" hazard
make -ndeletes all objects and the PRG: the flag-stamp compare runs at parse time #174 fought, and the exemption logic is already the subtlest part of the Makefile. Recorded so it is visibly considered and declined.
My preference is docs + deleting the map; the third option is noted only to be rejected.
Not claimed
I have not checked whether make package / package-verify are exposed to this, nor whether any test suite or rig shells out to a maintenance target mid-measurement. Both are worth a look and neither is in evidence above.
Activity
Merge pull request #231 from JC-000/fix/220-stamp-stale-artifacts
make: a missing object takes the PRG with it; an empty blob counts as…