Skip to content

Commit 5d9789b

Browse files
authored
Merge pull request #6268 from larsewi/repro
Made the source tarball reproducible
2 parents 6f3abfd + a83bad3 commit 5d9789b

3 files changed

Lines changed: 42 additions & 5 deletions

File tree

Makefile.am

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,43 @@ SUBDIRS = \
5454
contrib/vagrant-ci/centos-9s-x64
5555

5656

57-
# Hide the buildsystem's username, at least with GNU tar.
58-
TAR_OPTIONS = --owner=0 --group=0
57+
# Normalize tar header fields so two builds of the same source tree produce a
58+
# byte-identical tarball, following the GNU tar reproducibility guidance:
59+
# https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html
60+
# --format=posix stable, version-independent header encoding (configure.ac
61+
# selects tar-pax so $(am__tar) emits posix)
62+
# --pax-option=... keep tar's PID out of extended-header names and omit
63+
# atime/ctime, leaving the archive in the ustar subset
64+
# --sort=name stable member order
65+
# --numeric-owner do not record buildslave user/group names
66+
# --owner=0 --group=0 deterministic ownership
67+
# --mode=go+u,go-w deterministic permissions
68+
# mtime clamping (the manual's --clamp-mtime --mtime) is handled by the
69+
# touch -d @$$SOURCE_DATE_EPOCH call in dist-hook below.
70+
TAR_OPTIONS = \
71+
--format=posix \
72+
--pax-option=exthdr.name=%d/PaxHeaders/%f \
73+
--pax-option=delete=atime,delete=ctime \
74+
--sort=name \
75+
--numeric-owner --owner=0 --group=0 \
76+
--mode=go+u,go-w
5977
export TAR_OPTIONS
6078

79+
# The same guidance says to "run GNU tar in the C locale" alongside the options
80+
# above; its example invokes "LC_ALL=C tar ...".
81+
LC_ALL = C
82+
export LC_ALL
83+
84+
# --no-name strips the mtime from the gzip header. --best is automake's default
85+
GZIP_ENV = "--best --no-name"
86+
87+
# Clamp every mtime in the source tarball to SOURCE_DATE_EPOCH, so that it
88+
# follows the commit the tarball was made from rather than the time it was built.
89+
dist-hook:
90+
if [ -n "$$SOURCE_DATE_EPOCH" ]; then \
91+
find $(distdir) -exec touch -d @$$SOURCE_DATE_EPOCH {} + ; \
92+
fi
93+
6194

6295
EXTRA_DIST = CHANGELOG.md INSTALL README.md LICENSE CFVERSION
6396

configure.ac

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ m4_define(SERIAL_TESTS, m4_bmatch(AUTOMAKE_VERSION, [^1\.\([0-9]\|1[0-1]\)\(\.\|
6969
AC_MSG_RESULT(AUTOMAKE_VERSION)
7070

7171

72-
AM_INIT_AUTOMAKE([tar-ustar] SERIAL_TESTS)
72+
dnl tar-pax rather than tar-ustar so that $(am__tar) emits the posix format the
73+
dnl reproducibility options in Makefile.am ask for, as in masterfiles.
74+
AM_INIT_AUTOMAKE([tar-pax] SERIAL_TESTS)
7375
AM_MAINTAINER_MODE([enable])
7476

7577
m4_divert_text([DEFAULTS], [: "${AR_FLAGS=cr}"])

tests/unit/tar_portability_test.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ then
66
exit 77
77
fi
88

9-
cd "$(dirname $0)/../.."
9+
cd "$(dirname "$0")"/../.. || exit 1
1010

11-
tar --exclude="tests/acceptance/workdir" --format=ustar -cf /dev/null *
11+
# Clear TAR_OPTIONS: Makefile.am sets it for "make dist", and the --pax-option
12+
# in there only works on posix archives, not on the ustar one made here.
13+
TAR_OPTIONS='' tar --exclude="tests/acceptance/workdir" --format=ustar -cf /dev/null *
1214

1315
exit $?

0 commit comments

Comments
 (0)