Re: FreeBSD make fails on BUILT_SOURCES file

Jan Engelhardt <[email protected]> Thu, 25 Sep 2025 20:40:21 +0200 (CEST)
Newsgroups gmane.comp.sysutils.automake.general
Message-ID <[email protected]>
On Thursday 2025-09-25 19:31, Nate Bargmann wrote:
>> >hamlibdatetime.h: FORCE
>> >	@if test -x $(top_srcdir)/.git ; then \
>> >		echo "/* This date time is from the last non-merge commit to Hamlib. */" > $(builddir)/$(@F).tmp ;\
>> >		echo "#define HAMLIBDATETIME "\"$$(TZ=UTC git --git-dir=$(top_srcdir)/.git log --no-merges --date='format-local:%Y-%m-%dT%H:%M:%SZ SHA=' --format='%cd' -n 1)$$(git --git-dir=$(top_srcdir)/.git log --no-merges -n 1 | head -n 1 | cut -c8-13)\"  >> $(builddir)/$(@F).tmp ;\
>> >		diff -qN $(builddir)/$(@F).tmp $(builddir)/$(@F) ; test $$? -eq 0 || { echo "Generating SCS header \"$(builddir)/$(@F)\"" ; mv -f $(builddir)/$(@F).tmp $(builddir)/$(@F) ; } ;\
>> >		rm -f $(builddir)/$(@F).tmp ;\
>> >		touch -c $(top_srcdir)/src/version_dll.rc ;\
>> >	else \
>> >		test -f $(srcdir)/$(@F) || cp $(srcdir)/$(@F).in $(srcdir)/$(@F) ;\
>> >	fi
>
>I'll check that out.  This isn't my code.
>
>
>The reporter of the issue did remark about the differences of return
>values between GNU diff and FreeBSD diff in the issue, but GNU make
>completes this rule without complaint, ostensibly with FreeBSD diff, so
>there is probably a need to hide the return value from FreeBSD make.

The original hamlibdatetime.h recipe is one big if..fi block.
"if/fi" does not set $?, so any failure exit code comes from the
last statement in the positive or negative branch of the condition,
in other words, `touch -c`.


>At least the recipe is now partly processed as I get to this point:
>
>Making all in src
>Files ./hamlibdatetime.h.tmp and ./hamlibdatetime.h differ

* diff produces a "line-by-line comparison" (terminology from the manpage).
  This is highly wasteful, because in the context of Makefile, we are only
  interested in a byte-by-byte comparison and stopping at the first mismatch.
  Use cmp.

* It is odd to see that they properly used --format=%cd for the first part,
  but then completely forget that there is --format=%h for the second part and
  instead did... barbershop nonsense with | head | cut .

Anyway. Altogether, something like

hamlibdatetime.h: hamlibdatetime.h.in FORCE
	${AM_V_at}if test -d $(top_srcdir)/.git; then \
		echo "/* This date time is from the last non-merge commit to Hamlib. */" >[email protected]; \
		echo "#define HAMLIBDATETIME "\"$$(TZ=UTC git --git-dir=$(top_srcdir)/.git log --no-merges --date='format-local:%Y-%m-%dT%H:%M:%SZ SHA=' --format='%cd' -n 1)$$(git --git-dir=$(top_srcdir)/.git log --no-merges -n 1 --format='%h'\" >[email protected]; \
	else \
 		cp ${srcdir}/hamlibdatetime.h.in [email protected]; \
	fi
	${AM_V_at}if ! cmp $@ [email protected] >/dev/null 2>/dev/null; then mv [email protected] $@; fi; rm -f [email protected]

might just fix it for good.