The Makefile deliberately names the executable in exactly one place:
# the executable this build produces, named in one place so the build and clean steps cannot disagree
TARGET = testing
cr.sh, however, hardcodes the same name independently:
The stated intent of TARGET is that the build and clean steps cannot disagree, and within the Makefile that holds. It does not extend to cr.sh. Changing TARGET — the first thing many users of a starter template will want to do, since testing is a placeholder name — leaves cr.sh invoking a path that no longer exists. Because cr.sh sets -e, the failure is loud rather than silent, but it is still a break that the single-source-of-truth comment implies should not happen.
Possible resolutions, in increasing order of intrusiveness:
- A
run target in the Makefile (run: $(TARGET) invoking ./$(TARGET)), with cr.sh reduced to make clean, make, make run. The executable name then genuinely lives in one place.
- A comment in
cr.sh noting that the name is duplicated and must be kept in step with TARGET.
Option 1 is preferred, but it modifies the Makefile, which is the build contract inherited by every project generated from this template, so it warrants review rather than autonomous change.
Note on validation: this was found by reading the two files, not by renaming TARGET and observing the break. The session in which it was found was able to compile the project but was not permitted to execute the produced binary, so the runtime half of the anchor could not be exercised. Whoever implements this should run ./cr.sh end to end.
This issue was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson
The
Makefiledeliberately names the executable in exactly one place:cr.sh, however, hardcodes the same name independently:# run ./testingThe stated intent of
TARGETis that the build and clean steps cannot disagree, and within theMakefilethat holds. It does not extend tocr.sh. ChangingTARGET— the first thing many users of a starter template will want to do, sincetestingis a placeholder name — leavescr.shinvoking a path that no longer exists. Becausecr.shsets-e, the failure is loud rather than silent, but it is still a break that the single-source-of-truth comment implies should not happen.Possible resolutions, in increasing order of intrusiveness:
runtarget in theMakefile(run: $(TARGET)invoking./$(TARGET)), withcr.shreduced tomake clean,make,make run. The executable name then genuinely lives in one place.cr.shnoting that the name is duplicated and must be kept in step withTARGET.Option 1 is preferred, but it modifies the
Makefile, which is the build contract inherited by every project generated from this template, so it warrants review rather than autonomous change.Note on validation: this was found by reading the two files, not by renaming
TARGETand observing the break. The session in which it was found was able to compile the project but was not permitted to execute the produced binary, so the runtime half of the anchor could not be exercised. Whoever implements this should run./cr.shend to end.This issue was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson