Source: perl
Version: 5.20.1-4
Severity: wishlist
Tags: patch
User: reproducible-bui...@lists.alioth.debian.org
Usertags: timestamps fileordering

Hi!

While working on the “reproducible builds” effort [1], we have noticed
that perl could not be built reproducibly.

The attached patches will fix that with our current experimental
framework. I hope the description of each patch is enough to understand
their purpose.

 [1]: https://wiki.debian.org/ReproducibleBuilds

-- 
Lunar                                .''`. 
lu...@debian.org                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-   
From 29c04aca659d9b4a5bbd0bd2a4a36020ca2d1676 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 08:44:33 +0100
Subject: [PATCH] Fix mtimes before building binary packages

To enable perl to build reproducibly, mtimes of any files created
after the date of the latest debian/changelog entry will be changed to
that date.
---
 debian/rules | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/debian/rules b/debian/rules
index cd6b952..1a5459e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -23,6 +23,7 @@ strip	    := $(shell /bin/bash debian/config.debian --strip)
 archtriplet := $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
 srcdir      := $(shell pwd)
 packages    := $(shell sed -n 's/^Package: *\(.*\)/\1/p' debian/control)
+build_date  := $(shell dpkg-parsechangelog | sed -n -e 's/^Date: //p')
 tmp	    = debian/tmp
 bin         = $(tmp)/usr/bin
 man         = $(tmp)/usr/share/man
@@ -426,6 +427,8 @@ binary-indep: build-stamp install-stamp
 		>$(build)/$$p/DEBIAN/md5sums; \
 	    chmod 644 $(build)/$$p/DEBIAN/md5sums; \
 	    dpkg-gencontrol -p$$p -isp -P$(build)/$$p $(subst_upstream) $(subst_next_upstream); \
+	    find $(build)/$$p -depth -newermt '$(build_date)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(build_date)'; \
 	    dpkg --build $(build)/$$p ..; \
 	done
 
@@ -472,6 +475,8 @@ endif
 		                        -S$(srcdir)/$(build)/perl-base 2>&1 | \
 		fgrep -v 'File format not recognized'; # scripts \
 	    dpkg-gencontrol -p$$p -isp -P$(build)/$$p $(subst_perlapi) $(subst_upstream); \
+	    find $(build)/$$p -depth -newermt '$(build_date)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(build_date)'; \
 	    dpkg --build $(build)/$$p ..; \
 	done
 
-- 
2.1.4

From b7a914d615c9b34f4ca60219463dc952c3357108 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 10:26:17 +0100
Subject: [PATCH] Stop recording build date and time

In order to make the package build reproducibly, we remove the
recording of the build date and time. This was already optional
in case the __DATE__ C pre-processor macro was not available.

Patch-Name: debian/do-no-record-build-date.diff
---
 perl.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/perl.c b/perl.c
index b9d0ce1..3ba83fc 100644
--- a/perl.c
+++ b/perl.c
@@ -1776,18 +1776,7 @@ S_Internals_V(pTHX_ CV *cv)
     PUSHs(Perl_newSVpvn_flags(aTHX_ non_bincompat_options,
 			      sizeof(non_bincompat_options) - 1, SVs_TEMP));
 
-#ifdef __DATE__
-#  ifdef __TIME__
-    PUSHs(Perl_newSVpvn_flags(aTHX_
-			      STR_WITH_LEN("Compiled at " __DATE__ " " __TIME__),
-			      SVs_TEMP));
-#  else
-    PUSHs(Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN("Compiled on " __DATE__),
-			      SVs_TEMP));
-#  endif
-#else
     PUSHs(&PL_sv_undef);
-#endif
 
     for (i = 1; i <= local_patch_count; i++) {
 	/* This will be an undef, if PL_localpatches[i] is NULL.  */
-- 
2.1.4

From d1a466db8650bfd01e372470950701a008c66f69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 11:52:40 +0100
Subject: [PATCH] Allow cf_time to be set externally

In order to allow Perl to be built reproducibly, it is worthwhile
to allow the configuration time to be set externally.

Patch-Name: fixes/allow-external-cf_time.diff
---
 Configure | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Configure b/Configure
index 883ac4c..5f118cf 100755
--- a/Configure
+++ b/Configure
@@ -3766,7 +3766,10 @@ esac
 . ./posthint.sh
 
 : who configured the system
-cf_time=`LC_ALL=C; LANGUAGE=C; export LC_ALL; export LANGUAGE; $date 2>&1`
+case "$cf_time" in
+"")
+	cf_time=`LC_ALL=C; LANGUAGE=C; export LC_ALL; export LANGUAGE; $date 2>&1` ;;
+esac
 case "$cf_by" in
 "")
 	cf_by=`(logname) 2>/dev/null`
-- 
2.1.4

From 3bd08bd5f6395d002b9f4fa46a551f21300fd240 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 12:17:58 +0100
Subject: [PATCH] Set a deterministic configuration time

To enable Perl to build reproducibly, we set the configuration time to
the time of the latest debian/changelog entry.
---
 debian/config.over | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/debian/config.over b/debian/config.over
index d66e479..8089694 100644
--- a/debian/config.over
+++ b/debian/config.over
@@ -46,6 +46,8 @@ then
     libpth="$libpth $multiarch_dir"
 fi
 
+# set configuration time to latest debian/changelog entry
+cf_time=$(sed -n '/^ -- /{s/.*> \(.*\)/\1/p;q}' debian/changelog)
 # set generic email addresses, host/domain names
 cf_by='Debian Project'
 cf_email=p...@packages.debian.org
-- 
2.1.4

From 91d18d084e722b82f9b910110d7b5aaa76214c96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 12:27:49 +0100
Subject: [PATCH] Create libperl.a using deterministic mode

In order to make Perl builds reproducible, create libperl.a using ar
in deterministic mode.

Patch-Name: fixes/create-libperl-using-deterministic-mode.diff
---
 Makefile.SH | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.SH b/Makefile.SH
index 13f79eb..819b4f3 100755
--- a/Makefile.SH
+++ b/Makefile.SH
@@ -850,7 +850,7 @@ $(LIBPERL): $& $(obj) $(DYNALOADER) $(LIBPERLEXPORT)
 	*)
 		$spitshell >>$Makefile <<'!NO!SUBS!'
 	rm -f $(LIBPERL)
-	$(AR) rcu $(LIBPERL) $(obj) $(DYNALOADER)
+	$(AR) Drcu $(LIBPERL) $(obj) $(DYNALOADER)
 	@$(ranlib) $(LIBPERL)
 !NO!SUBS!
 		;;
-- 
2.1.4

From 79ea8f0b61891654aa17353f7c5e22c5ff37e566 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 12:27:49 +0100
Subject: [PATCH] Create libperl.a using deterministic mode

In order to make Perl builds reproducible, create libperl.a using ar
in deterministic mode.

Patch-Name: fixes/create-libperl-using-deterministic-mode.diff
---
 Makefile.SH | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.SH b/Makefile.SH
index 13f79eb..2564935 100755
--- a/Makefile.SH
+++ b/Makefile.SH
@@ -850,7 +850,7 @@ $(LIBPERL): $& $(obj) $(DYNALOADER) $(LIBPERLEXPORT)
 	*)
 		$spitshell >>$Makefile <<'!NO!SUBS!'
 	rm -f $(LIBPERL)
-	$(AR) rcu $(LIBPERL) $(obj) $(DYNALOADER)
+	$(AR) Drc $(LIBPERL) $(obj) $(DYNALOADER)
 	@$(ranlib) $(LIBPERL)
 !NO!SUBS!
 		;;
-- 
2.1.4

From 398b4e3e5b9894439867dc61ffa99df030211e1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 13:18:23 +0100
Subject: [PATCH] Sort file list when generating md5sums

In order to make Perl builds reproducible, the list in md5sums must be
in a stable order. Sorting is the easiest way to achieve this.
---
 debian/rules | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/debian/rules b/debian/rules
index 1a5459e..f020a79 100755
--- a/debian/rules
+++ b/debian/rules
@@ -423,7 +423,7 @@ binary-indep: build-stamp install-stamp
 	    test -d $(build)/$$p/etc && find $(build)/$$p/etc -type f \
 		-printf '/etc/%P\n' >$(build)/$$p/DEBIAN/conffiles; \
 	    chmod 644 $(build)/$$p/DEBIAN/conffiles; \
-	    (cd $(build)/$$p; find usr -type f -print | xargs -r md5sum) \
+	    (cd $(build)/$$p; find usr -type f -print | LC_ALL=C sort | xargs -r md5sum) \
 		>$(build)/$$p/DEBIAN/md5sums; \
 	    chmod 644 $(build)/$$p/DEBIAN/md5sums; \
 	    dpkg-gencontrol -p$$p -isp -P$(build)/$$p $(subst_upstream) $(subst_next_upstream); \
@@ -460,7 +460,7 @@ endif
 		chmod 755 $(build)/$$p/DEBIAN/$$c; \
 	    done; \
 	    ! test -f $(build)/$$p/DEBIAN/shlibs || chmod 644 $(build)/$$p/DEBIAN/shlibs; \
-	    (cd $(build)/$$p; find usr -type f -print | xargs -r md5sum) \
+	    (cd $(build)/$$p; find usr -type f -print | LC_ALL=C sort | xargs -r md5sum) \
 		>$(build)/$$p/DEBIAN/md5sums; \
 	    chmod 644 $(build)/$$p/DEBIAN/md5sums; \
 	done
-- 
2.1.4

From efba66ef5db0ceec3ab946cda28d6f24b9911754 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Fri, 2 Jan 2015 13:33:02 +0100
Subject: [PATCH] Set mtime of patchlevel.h to highest mtime of Debian patches

$patchlevel_date in perlbug is determined by looking at patchlevel.h mtime.
In order to make Perl builds reproducible, we thus set this value to
the highest mtime of all the Debian patches.
---
 debian/gen-patchlevel | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/debian/gen-patchlevel b/debian/gen-patchlevel
index 1d454ef..1e730e6 100755
--- a/debian/gen-patchlevel
+++ b/debian/gen-patchlevel
@@ -32,8 +32,14 @@ if [ -n "$version" ]; then
     version=" for $version"
 fi
 
+newest_mtime=0
 while read patch strip
 do
+    mtime=$(stat --format='%Y' $patchdir/$patch)
+    if [ "$mtime" -gt "$newest_mtime" ]; then
+        newest_mtime="$mtime"
+    fi
+
     patchname=$(echo $patch | sed 's/\.diff$//')
     < $patchdir/$patch sed -e '/^Subject:/ { N; s/\n / / }' | sed -n -e '
 
@@ -67,3 +73,7 @@ do
     :prepend x; H; d;
     '
 done < $in
+
+# $patchlevel_date in perlbug is extracted from patchlevel.h mtime, let's set
+# it to highest mtime of Debian patches for build reproducibility
+touch --date="@$newest_mtime" patchlevel.h
-- 
2.1.4

Attachment: signature.asc
Description: Digital signature

Reply via email to