Dear Recipients,

The bug#10975 has been fixed.  The change has been pushed to Savannah.
The patch is attached to this e-mail.  Thank you for reporting.

--
With Valediction,
Kamila Szewczyk (https://iczelia.net)
From d55d2a2e0ff20fbeb71cee607b285873bd3b68d6 Mon Sep 17 00:00:00 2001
From: Kamila Szewczyk <[email protected]>
Date: Mon, 24 Aug 2026 20:12:48 +0200
Subject: [PATCH] dist: fix automake bug #10975

From https://bugs.gnu.org/10975 (Olaf Lenz).

`make dist-bzip2 dist-xz' now succeeds.  They share the intermediate
uncompressed tarball as a result of another fix.  The first goal used
to delete it, so every later goal failed with ENOENT.  Under GNU make
the tarball is now an .INTERMEDIATE file, built once and removed once the
last goal is done with it; other make implementations rebuild it per
goal.  (bug #10975)

Non-zero exit codes of compressors for the dist tarballs no longer abort
the job in a state where the empty files are left behind.  The shell
redirection truncates the archive before the initial invocation, so a
zero-length archive could be mistook for a distribution; $(distdir).tar was
left too.  Both are now removed.  This is a natural follow-up fix to
bug#19614, also closely related to #10975.

A regression test has been added alongside the change.

* lib/am/distdir.am: Preserve intermediate tarballs across targets, or re-build
  on non-GNU makes (e.g. bmake).
* NEWS: Mention this patch.
* t/dist-multiple-formats.sh: Add a regression test.
* t/dist-compressor-fails.sh: Add a regression test.
* t/list-of-tests.mk: Register the test above.
---
 NEWS                       | 14 +++++++++
 lib/am/distdir.am          | 43 ++++++++++++++++++++-----
 t/dist-compressor-fails.sh | 52 +++++++++++++++++++++++++++++++
 t/dist-multiple-formats.sh | 64 ++++++++++++++++++++++++++++++++++++++
 t/list-of-tests.mk         |  2 ++
 5 files changed, 167 insertions(+), 8 deletions(-)
 create mode 100755 t/dist-compressor-fails.sh
 create mode 100755 t/dist-multiple-formats.sh

diff --git a/NEWS b/NEWS
index e5d9c35a8..31b885627 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,20 @@ New in 1.18.2 (????-??-??):
 
 * Bugs fixed
 
+  - `make dist-bzip2 dist-xz' now succeeds.  They share the intermediate
+    uncompressed tarball as a result of another fix.  The first goal used
+    to delete it, so every later goal failed with ENOENT.  Under GNU make
+    the tarball is now an .INTERMEDIATE file, built once and removed once the
+    last goal is done with it; other make implementations rebuild it per
+    goal.  (bug #10975)
+
+  - Non-zero exit codes of compressors for the dist tarballs no longer abort
+    the job in a state where the empty files are left behind.  The shell
+    redirection truncates the archive before the initial invocation, so a
+    zero-length archive could be mistook for a distribution; $(distdir).tar was
+    left too.  Both are now removed.  This is a natural follow-up fix to
+    bug#19614.
+
   - Busybox tar no longer assumed to be GNU tar just because it
     supports --version.
 
diff --git a/lib/am/distdir.am b/lib/am/distdir.am
index b817779ad..82ed5b72b 100644
--- a/lib/am/distdir.am
+++ b/lib/am/distdir.am
@@ -34,8 +34,12 @@ am__remove_distdir = \
       || { sleep 5 && rm -rf "$(distdir)"; }; \
   else :; fi
 am__post_remove_distdir = \
-  rm -f $(distdir).tar; \
+  $(am__is_gnu_make) || rm -f $(distdir).tar; \
   $(am__remove_distdir)
+am__ensure_distdir_tar = \
+  test -f $(distdir).tar || $(MAKE) $(AM_MAKEFLAGS) $(distdir).tar
+am__dist_compress_failed = \
+  am__rc=$$?; rm -f $$am__archive $(distdir).tar; exit $$am__rc
 endif %?TOPDIR_P%
 
 if %?SUBDIRS%
@@ -357,51 +361,74 @@ $(distdir).tar: distdir
 	test $$am__tar_rc -eq 0 || { rm -f $(distdir).tar; \
 	  echo "$(distdir).tar: cannot create the distribution archive" >&2; exit 1; }
 
+.INTERMEDIATE: $(distdir).tar
+
 ?GZIP?DIST_ARCHIVES += $(distdir).tar.gz
 GZIP_ENV = -9
 .PHONY: dist-gzip
 dist-gzip: $(distdir).tar
-	eval GZIP= gzip $(GZIP_ENV) -c <$(distdir).tar >$(distdir).tar.gz
+	@$(am__ensure_distdir_tar)
+	am__archive=$(distdir).tar.gz; \
+	eval GZIP= gzip $(GZIP_ENV) -c <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?BZIP2?DIST_ARCHIVES += $(distdir).tar.bz2
 .PHONY: dist-bzip2
 dist-bzip2: $(distdir).tar
-	BZIP2=$${BZIP2--9} bzip2 -c <$(distdir).tar >$(distdir).tar.bz2
+	@$(am__ensure_distdir_tar)
+	am__archive=$(distdir).tar.bz2; \
+	BZIP2=$${BZIP2--9} bzip2 -c <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?BZIP3?DIST_ARCHIVES += $(distdir).tar.bz3
 .PHONY: dist-bzip3
 ## bzip3 does not read any envvars.
 dist-bzip3: $(distdir).tar
-	bzip3 -c <$(distdir).tar >$(distdir).tar.bz3
+	@$(am__ensure_distdir_tar)
+	am__archive=$(distdir).tar.bz3; \
+	bzip3 -c <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?LZIP?DIST_ARCHIVES += $(distdir).tar.lz
 .PHONY: dist-lzip
 dist-lzip: $(distdir).tar
-	lzip -c $${LZIP_OPT--9} <$(distdir).tar >$(distdir).tar.lz
+	@$(am__ensure_distdir_tar)
+	am__archive=$(distdir).tar.lz; \
+	lzip -c $${LZIP_OPT--9} <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?XZ?DIST_ARCHIVES += $(distdir).tar.xz
 .PHONY: dist-xz
 dist-xz: $(distdir).tar
-	XZ_OPT=$${XZ_OPT--e} xz -c <$(distdir).tar >$(distdir).tar.xz
+	@$(am__ensure_distdir_tar)
+	am__archive=$(distdir).tar.xz; \
+	XZ_OPT=$${XZ_OPT--e} xz -c <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?ZSTD?DIST_ARCHIVES += $(distdir).tar.zst
 .PHONY: dist-zstd
 dist-zstd: $(distdir).tar
-	zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} <$(distdir).tar >$(distdir).tar.zst
+	@$(am__ensure_distdir_tar)
+	am__archive=$(distdir).tar.zst; \
+	zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?COMPRESS?DIST_ARCHIVES += $(distdir).tar.Z
 .PHONY: dist-tarZ
 dist-tarZ: $(distdir).tar
+	@$(am__ensure_distdir_tar)
 	@echo WARNING: "Support for distribution archives compressed with" \
 		       "legacy program 'compress' is deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
-	compress -c <$(distdir).tar >$(distdir).tar.Z
+	am__archive=$(distdir).tar.Z; \
+	compress -c <$(distdir).tar >$$am__archive \
+	  || { $(am__dist_compress_failed); }
 	$(am__post_remove_distdir)
 
 ?SHAR?DIST_ARCHIVES += $(distdir).shar.gz
diff --git a/t/dist-compressor-fails.sh b/t/dist-compressor-fails.sh
new file mode 100755
index 000000000..1b2cbbc34
--- /dev/null
+++ b/t/dist-compressor-fails.sh
@@ -0,0 +1,52 @@
+#! /bin/sh
+# Copyright (C) 2026 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. test-init.sh
+
+cat > configure.ac << END
+AC_INIT([$me], [1.0])
+AM_INIT_AUTOMAKE([foreign dist-xz])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+: > Makefile.am
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+./configure
+
+# stub
+mkdir bin
+cat > bin/xz << 'END'
+#! /bin/sh
+echo "fake xz: cannot compress that" >&2
+exit 1
+END
+chmod a+x bin/xz
+
+saved_PATH=$PATH
+PATH=$(pwd)/bin$PATH_SEPARATOR$PATH; export PATH
+run_make -M -e FAIL dist-xz
+PATH=$saved_PATH; export PATH
+
+grep 'cannot compress that' output
+# No truncated archive, and no leftover shared tarball.
+test ! -e $distdir.tar.xz
+test ! -e $distdir.tar
+
+:
diff --git a/t/dist-multiple-formats.sh b/t/dist-multiple-formats.sh
new file mode 100755
index 000000000..bf46a73e5
--- /dev/null
+++ b/t/dist-multiple-formats.sh
@@ -0,0 +1,64 @@
+#! /bin/sh
+# Copyright (C) 2026 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# Regression test for bug#10975
+
+required='xz'
+. test-init.sh
+
+cat > configure.ac << END
+AC_INIT([$me], [1.0])
+AM_INIT_AUTOMAKE([foreign dist-xz])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+END
+
+: > Makefile.am
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+./configure
+
+run_make -O dist-gzip dist-xz
+test -f $distdir.tar.gz
+test -f $distdir.tar.xz
+xz -t $distdir.tar.xz
+test ! -e $distdir.tar
+test ! -d $distdir
+
+tar_runs=$(grep -c "tardir=$distdir &&" stdout) || tar_runs=0
+echo "tar runs: $tar_runs" # For debugging.
+if using_gmake; then
+  test $tar_runs -eq 1
+else
+  test $tar_runs -ge 1
+fi
+
+rm -f $distdir.tar.*
+run_make -O dist-xz
+test -f $distdir.tar.xz
+test ! -e $distdir.tar
+test ! -d $distdir
+
+rm -f $distdir.tar.*
+run_make -O dist
+test -f $distdir.tar.gz
+test -f $distdir.tar.xz
+test ! -e $distdir.tar
+test ! -d $distdir
+
+:
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index f4910f0fa..ae8b7079c 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -415,6 +415,7 @@ t/dist-auxdir-many-subdirs.sh \
 t/dist-auxfile-2.sh \
 t/dist-auxfile.sh \
 t/dist-bzip3.sh \
+t/dist-compressor-fails.sh \
 t/dist-formats.tap \
 t/dist-included-parent-dir.sh \
 t/dist-install-sh.sh \
@@ -422,6 +423,7 @@ t/dist-lzma.sh \
 t/dist-missing-am.sh \
 t/dist-missing-included-m4.sh \
 t/dist-missing-m4.sh \
+t/dist-multiple-formats.sh \
 t/dist-no-built-sources.sh \
 t/dist-pr109765.sh \
 t/dist-readonly.sh \
-- 
2.53.0

Attachment: OpenPGP_0xC868F0B6DE38409D.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to