[llvm] [Release] Pass -n to gzip so the release tarball is reproducible (PR #216533)
Larry Meadows via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 15 20:56:15 PDT 2026
https://github.com/lfmeadow created https://github.com/llvm/llvm-project/pull/216533
`test-release.sh -use-gzip` packages the release with
```sh
tar cf - $Package | gzip -9c > $BuildDir/$Package.tar.gz
```
and the gzip header carries a modification-time field. Whether it gets filled in depends on which `gzip` is on the path, which makes the tarball's bytes depend on the packaging machine rather than on the release:
| implementation | MTIME field, input from a pipe | two runs over identical input |
| --- | --- | --- |
| GNU gzip 1.10 | `00 00 00 00` | identical |
| busybox gzip 1.30.1 | `00 00 00 00` | identical |
| pigz 2.6 | current time | differ |
GNU gzip only records a timestamp when it can stat its input as a regular file, so the pipeline above is already reproducible with it. pigz records the current time regardless, and it is commonly installed in place of `gzip` for the parallelism, so a release built on such a machine produces a different `.tar.gz` on every run. Debian's lintian reports the result as [`package-contains-timestamped-gzip`](https://lintian.debian.org/tags/package-contains-timestamped-gzip.html), whose advice is to pass `-n`.
Passing `-n` zeroes the field explicitly rather than relying on the implementation's default. It costs nothing on GNU gzip or busybox, and with it pigz's output becomes byte-identical to GNU gzip's.
AMD has been carrying this two-line change downstream since August 2025, which is where it was found; the patch is Jonathan Luu's, and I'm sending it upstream so the divergence goes away.
## Test plan
Both call sites are the only `.tar.gz` producers in the script (lines 372 and 616); the third `use_gzip` reference, at line 769, is an `echo`.
- `bash -n llvm/utils/release/test-release.sh` parses.
- Reproducibility, measured on the pipeline the script uses (`tar cf - pkg | gzip -9c` versus `... | gzip -9c -n`, two runs two seconds apart):
- GNU gzip 1.10: identical before and after; MTIME was already zero.
- pigz 2.6: without `-n` the two runs differ (`2bf61f7c…` vs `c20e2b21…`) and the MTIME field holds the wall clock; with `-n` both runs are identical and match GNU gzip's output byte for byte.
- busybox gzip 1.30.1: accepts `-n`, output unchanged.
>From d7160696c953d315b21e01e39495528b8a81c89d Mon Sep 17 00:00:00 2001
From: Jonathan Luu <jonatluu at amd.com>
Date: Sat, 15 Aug 2026 22:55:45 -0500
Subject: [PATCH] [Release] Pass -n to gzip so the release tarball is
reproducible
test-release.sh -use-gzip packages the release with
tar cf - $Package | gzip -9c > $BuildDir/$Package.tar.gz
GNU gzip writes a zero timestamp into the gzip header when its input is a
pipe, so the tarball is already reproducible there. pigz, which is often
installed in place of gzip, writes the current time instead, and the
tarball then differs from run to run over identical input. Debian's
lintian reports that as package-contains-timestamped-gzip and recommends
-n.
Pass -n at both call sites so the field is zeroed explicitly. It is a
no-op for GNU gzip and busybox gzip, and it makes pigz's output
byte-identical to gzip's.
Co-authored-by: Cursor <cursoragent at cursor.com>
---
llvm/utils/release/test-release.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/utils/release/test-release.sh b/llvm/utils/release/test-release.sh
index 20fbf83ce90a9..3c1d7ef4c2091 100755
--- a/llvm/utils/release/test-release.sh
+++ b/llvm/utils/release/test-release.sh
@@ -369,7 +369,7 @@ function build_with_cmake_cache() {
pushd $BuildDir/Release
mv $InstallDir/usr/local $Package
if [ "$use_gzip" = "yes" ]; then
- tar cf - $Package | gzip -9c > $BuildDir/$Package.tar.gz
+ tar cf - $Package | gzip -9c -n > $BuildDir/$Package.tar.gz
else
tar cf - $Package | xz -9ce -T $NumJobs > $BuildDir/$Package.tar.xz
fi
@@ -613,7 +613,7 @@ function package_release() {
cd $BuildDir/Phase3/Release
mv llvmCore-$Release-$RC.install/usr/local $Package
if [ "$use_gzip" = "yes" ]; then
- tar cf - $Package | gzip -9c > $BuildDir/$Package.tar.gz
+ tar cf - $Package | gzip -9c -n > $BuildDir/$Package.tar.gz
else
tar cf - $Package | xz -9ce -T $NumJobs > $BuildDir/$Package.tar.xz
fi
More information about the llvm-commits
mailing list