Subject: dirstamp pattern rule kills buildability with FreeBSD make, NetBSD make, AIX make
From: Bruno Haible <[email-masked]>
To: [email-masked]
Cc: Mike Frysinger <[email-masked]>, Jim Meyering <[email-masked]>
Date: Tue, 28 Feb 2023 13:47:06 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

FreeBSD 13.1 'make', NetBSD 9.0 'make', AIX 7.1 and 7.2 'make' are perfectly
fine for building many GNU packages, even as VPATH builds.

Jim Meyering has now put out a tarball for testing, that uses bleeding-edge
Automake:
https://lists.gnu.org/archive/html/platform-testers/2023-02/msg00012.html

When I build this tarball on FreeBSD, NetBSD, or AIX — in srcdir or as a
VPATH build, does not matter —, the build fails, like this:

 ------------------------------------------------------
...
  CC       libgreputils_a-getopt1.o
  CC       libgreputils_a-getprogname.o
make: 1254-002 Cannot find a rule to create target malloc/.dirstamp from dependencies.
Stop.
make: 1254-004 The error code from the last command is 2.

Stop.
make: 1254-004 The error code from the last command is 1.

Stop.
make: 1254-004 The error code from the last command is 2.

Stop.
 ------------------------------------------------------

This is a regression, caused by the bleeding-edge Automake, because when I
unpack the tarball and then (with Automake 1.16.5 in $PATH) do
  aclocal -I m4
  automake
  touch configure
  touch config.hin
it does not exhibit this build failure any more.

Find attached the diff between lib/Makefile (that fails) and lib/Makefile
(that comes from Automake 1.16.5 and works fine). You can see that with
individual rules for malloc/$(am__dirstamp), glthread/$(am__dirstamp),
unistr/$(am__dirstamp), uniwidth/$(am__dirstamp) the build works fine,
whereas with the pattern rule
  %/$(am__dirstamp)
it fails.

I guess that the commit "dirstamp: switch to a pattern rule" is the culprit.
https://git.savannah.gnu.org/gitweb/?p=automake.git;a=commitdiff;h=55f8fcfd08cbf15d65d61dd2db934b6c3171cf06

Bruno

--- grep-3.8.35-c860/build/lib/Makefile	2023-02-28 10:01:18.623558000 +0100
+++ grep-3.8.35-c860-fixed/build/lib/Makefile	2023-02-28 13:26:12.610679000 +0100
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16i from Makefile.am.
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
 # lib/Makefile.  Generated from Makefile.in by configure.
 
-# Copyright (C) 1994-2023 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -203,8 +203,6 @@
   test $$has_opt = yes
 am__make_dryrun = (target_option=n; $(am__make_running_with_option))
 am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-am__rm_f = rm -f $(am__rm_f_notfound)
-am__rm_rf = rm -rf $(am__rm_f_notfound)
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
@@ -446,7 +444,6 @@
 am__v_AR_0 = @echo "  AR      " $@;
 am__v_AR_1 = 
 libgreputils_a_AR = $(AR) $(ARFLAGS)
-libgreputils_a_RANLIB = $(RANLIB)
 am__DEPENDENCIES_1 =
 LIBOBJDIR = ../gnulib-tests/
 am__dirstamp = $(am__leading_dot)dirstamp
@@ -951,7 +948,7 @@
 pkgincludedir = ${includedir}/${PACKAGE}
 pkglibdir = ${libdir}/${PACKAGE}
 pkglibexecdir = ${libexecdir}/${PACKAGE}
-ACLOCAL = ${SHELL} '/home/bruno/grep-3.8.35-c860/build-aux/missing' aclocal-1.16
+ACLOCAL = ${SHELL} '/home/bruno/grep-3.8.35-c860-fixed/build-aux/missing' aclocal-1.16
 ALLOCA = 
 ALLOCA_H = alloca.h
 AMTAR = $${TAR-tar}
@@ -960,9 +957,9 @@
 AR = ar
 ARFLAGS = cr
 ASSERT_H = assert.h
-AUTOCONF = ${SHELL} '/home/bruno/grep-3.8.35-c860/build-aux/missing' autoconf
-AUTOHEADER = ${SHELL} '/home/bruno/grep-3.8.35-c860/build-aux/missing' autoheader
-AUTOMAKE = ${SHELL} '/home/bruno/grep-3.8.35-c860/build-aux/missing' automake-1.16
+AUTOCONF = ${SHELL} '/home/bruno/grep-3.8.35-c860-fixed/build-aux/missing' autoconf
+AUTOHEADER = ${SHELL} '/home/bruno/grep-3.8.35-c860-fixed/build-aux/missing' autoheader
+AUTOMAKE = ${SHELL} '/home/bruno/grep-3.8.35-c860-fixed/build-aux/missing' automake-1.16
 AWK = nawk
 BITSIZEOF_PTRDIFF_T = 
 BITSIZEOF_SIG_ATOMIC_T = 
@@ -985,6 +982,7 @@
 ECHO_C = 
 ECHO_N = -n
 ECHO_T = 
+EGREP = @EGREP@
 EMULTIHOP_HIDDEN = 
 EMULTIHOP_VALUE = 
 ENOLINK_HIDDEN = 
@@ -1803,7 +1801,7 @@
 LTLIBOBJS = 
 LTLIBSIGSEGV = 
 LTLIBTHREAD = 
-MAKEINFO = ${SHELL} '/home/bruno/grep-3.8.35-c860/build-aux/missing' makeinfo
+MAKEINFO = ${SHELL} '/home/bruno/grep-3.8.35-c860-fixed/build-aux/missing' makeinfo
 MBRTOWC_LIB = 
 MKDIR_P = mkdir -p
 MSGFMT = /home/bruno/bin/msgfmt
@@ -2216,19 +2214,17 @@
 XGETTEXT = /home/bruno/bin/xgettext
 XGETTEXT_015 = /home/bruno/bin/xgettext
 XGETTEXT_EXTRA_OPTIONS =  --flag=error:3:c-format --flag=error_at_line:5:c-format --keyword='proper_name:1,"This is a proper name. See the gettext manual, section Names."' --keyword='proper_name_utf8:1,"This is a proper name. See the gettext manual, section Names."'
-abs_aux_dir = /home/bruno/grep-3.8.35-c860/build-aux
-abs_builddir = /home/bruno/grep-3.8.35-c860/build/lib
-abs_srcdir = /home/bruno/grep-3.8.35-c860/build/../lib
-abs_top_builddir = /home/bruno/grep-3.8.35-c860/build
-abs_top_srcdir = /home/bruno/grep-3.8.35-c860/build/..
+abs_aux_dir = /home/bruno/grep-3.8.35-c860-fixed/build-aux
+abs_builddir = /home/bruno/grep-3.8.35-c860-fixed/build/lib
+abs_srcdir = /home/bruno/grep-3.8.35-c860-fixed/build/../lib
+abs_top_builddir = /home/bruno/grep-3.8.35-c860-fixed/build
+abs_top_srcdir = /home/bruno/grep-3.8.35-c860-fixed/build/..
 ac_ct_CC = cc -ferror-limit=0
 am__include = include
 am__leading_dot = .
 am__quote = 
-am__rm_f_notfound = 
 am__tar = $${TAR-tar} chof - "$$tardir"
 am__untar = $${TAR-tar} xf -
-am__xargs_n = xargs -n
 bindir = ${exec_prefix}/bin
 bindir_c = "/home/bruno/bin"
 bindir_c_make = \"$(bindir)\"
@@ -2274,7 +2270,7 @@
 infodir = ${datarootdir}/info
 infodir_c = "/home/bruno/share/info"
 infodir_c_make = \"$(infodir)\"
-install_sh = ${SHELL} /home/bruno/grep-3.8.35-c860/build-aux/install-sh
+install_sh = ${SHELL} /home/bruno/grep-3.8.35-c860-fixed/build-aux/install-sh
 libdir = ${exec_prefix}/lib
 libdir_c = "/home/bruno/lib"
 libdir_c_make = \"$(libdir)\"
@@ -2564,11 +2560,17 @@
 $(am__aclocal_m4_deps):
 
 clean-noinstLIBRARIES:
-	-$(am__rm_f) $(noinst_LIBRARIES)
-%/$(am__dirstamp):
-	@$(MKDIR_P) $(@D)
-	@: >>$@
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+../gnulib-tests/$(am__dirstamp):
+	@$(MKDIR_P) ../gnulib-tests/
+	@: > ../gnulib-tests/$(am__dirstamp)
 ../gnulib-tests/alloca.$(OBJEXT): ../gnulib-tests/$(am__dirstamp)
+malloc/$(am__dirstamp):
+	@$(MKDIR_P) malloc
+	@: > malloc/$(am__dirstamp)
+malloc/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) malloc/$(DEPDIR)
+	@: > malloc/$(DEPDIR)/$(am__dirstamp)
 malloc/libgreputils_a-dynarray_at_failure.$(OBJEXT):  \
 	malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp)
 malloc/libgreputils_a-dynarray_emplace_enlarge.$(OBJEXT):  \
@@ -2579,16 +2581,34 @@
 	malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp)
 malloc/libgreputils_a-dynarray_resize_clear.$(OBJEXT):  \
 	malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp)
+glthread/$(am__dirstamp):
+	@$(MKDIR_P) glthread
+	@: > glthread/$(am__dirstamp)
+glthread/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) glthread/$(DEPDIR)
+	@: > glthread/$(DEPDIR)/$(am__dirstamp)
 glthread/libgreputils_a-lock.$(OBJEXT): glthread/$(am__dirstamp) \
 	glthread/$(DEPDIR)/$(am__dirstamp)
 glthread/libgreputils_a-threadlib.$(OBJEXT): glthread/$(am__dirstamp) \
 	glthread/$(DEPDIR)/$(am__dirstamp)
+unistr/$(am__dirstamp):
+	@$(MKDIR_P) unistr
+	@: > unistr/$(am__dirstamp)
+unistr/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) unistr/$(DEPDIR)
+	@: > unistr/$(DEPDIR)/$(am__dirstamp)
 unistr/libgreputils_a-u8-mbtoucr.$(OBJEXT): unistr/$(am__dirstamp) \
 	unistr/$(DEPDIR)/$(am__dirstamp)
 unistr/libgreputils_a-u8-uctomb.$(OBJEXT): unistr/$(am__dirstamp) \
 	unistr/$(DEPDIR)/$(am__dirstamp)
 unistr/libgreputils_a-u8-uctomb-aux.$(OBJEXT): unistr/$(am__dirstamp) \
 	unistr/$(DEPDIR)/$(am__dirstamp)
+uniwidth/$(am__dirstamp):
+	@$(MKDIR_P) uniwidth
+	@: > uniwidth/$(am__dirstamp)
+uniwidth/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) uniwidth/$(DEPDIR)
+	@: > uniwidth/$(DEPDIR)/$(am__dirstamp)
 uniwidth/libgreputils_a-width.$(OBJEXT): uniwidth/$(am__dirstamp) \
 	uniwidth/$(DEPDIR)/$(am__dirstamp)
 malloc/libgreputils_a-dynarray-skeleton.$(OBJEXT):  \
@@ -2597,7 +2617,7 @@
 libgreputils.a: $(libgreputils_a_OBJECTS) $(libgreputils_a_DEPENDENCIES) $(EXTRA_libgreputils_a_DEPENDENCIES) 
 	$(AM_V_at)-rm -f libgreputils.a
 	$(AM_V_AR)$(libgreputils_a_AR) libgreputils.a $(libgreputils_a_OBJECTS) $(libgreputils_a_LIBADD)
-	$(AM_V_at)$(libgreputils_a_RANLIB) libgreputils.a
+	$(AM_V_at)$(RANLIB) libgreputils.a
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -2789,7 +2809,7 @@
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
-	@: >>$@
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
 
 am--depfiles: $(am__depfiles_remade)
 
@@ -5384,36 +5404,36 @@
 	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
 	fi
 mostlyclean-generic:
-	-$(am__rm_f) $(MOSTLYCLEANFILES)
-	-$(am__rm_f) ../gnulib-tests/alloca.$(OBJEXT)
+	-rm -f ../gnulib-tests/alloca.$(OBJEXT)
+	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
-	-$(am__rm_f) $(CLEANFILES)
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-	-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
-	-$(am__rm_f) ../gnulib-tests/$(am__dirstamp)
-	-$(am__rm_f) glthread/$(DEPDIR)/$(am__dirstamp)
-	-$(am__rm_f) glthread/$(am__dirstamp)
-	-$(am__rm_f) malloc/$(DEPDIR)/$(am__dirstamp)
-	-$(am__rm_f) malloc/$(am__dirstamp)
-	-$(am__rm_f) unistr/$(DEPDIR)/$(am__dirstamp)
-	-$(am__rm_f) unistr/$(am__dirstamp)
-	-$(am__rm_f) uniwidth/$(DEPDIR)/$(am__dirstamp)
-	-$(am__rm_f) uniwidth/$(am__dirstamp)
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f ../gnulib-tests/$(am__dirstamp)
+	-rm -f glthread/$(DEPDIR)/$(am__dirstamp)
+	-rm -f glthread/$(am__dirstamp)
+	-rm -f malloc/$(DEPDIR)/$(am__dirstamp)
+	-rm -f malloc/$(am__dirstamp)
+	-rm -f unistr/$(DEPDIR)/$(am__dirstamp)
+	-rm -f unistr/$(am__dirstamp)
+	-rm -f uniwidth/$(DEPDIR)/$(am__dirstamp)
+	-rm -f uniwidth/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-	-$(am__rm_f) $(BUILT_SOURCES)
-	-$(am__rm_f) $(MAINTAINERCLEANFILES)
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
 clean: clean-am
 
 clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
 
 distclean: distclean-am
-	-rm -f ../gnulib-tests/$(DEPDIR)/alloca.Po
+		-rm -f ../gnulib-tests/$(DEPDIR)/alloca.Po
 	-rm -f ./$(DEPDIR)/libgreputils_a-argmatch.Po
 	-rm -f ./$(DEPDIR)/libgreputils_a-at-func.Po
 	-rm -f ./$(DEPDIR)/libgreputils_a-basename-lgpl.Po
@@ -5635,7 +5655,7 @@
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-	-rm -f ../gnulib-tests/$(DEPDIR)/alloca.Po
+		-rm -f ../gnulib-tests/$(DEPDIR)/alloca.Po
 	-rm -f ./$(DEPDIR)/libgreputils_a-argmatch.Po
 	-rm -f ./$(DEPDIR)/libgreputils_a-at-func.Po
 	-rm -f ./$(DEPDIR)/libgreputils_a-basename-lgpl.Po