Source: binutils
Version: 2.25-3
Severity: wishlist
Tags: patch
User: reproducible-builds@lists.alioth.debian.org
Usertags: timestamps fileordering

Hi!

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

The attached patch contains multiple fixes to debian/rules to fix this
with our current experimental framework.

Ideally, using strip-nondeterminism should not be required, but I did
not find an easy way to pass the `D` flag to `ar`.

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

-- 
Lunar                                .''`. 
lu...@debian.org                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-   
diff -u binutils-2.25/debian/changelog binutils-2.25/debian/changelog
--- binutils-2.25/debian/changelog
+++ binutils-2.25/debian/changelog
@@ -1,3 +1,15 @@
+binutils (2.25-3.0~reproducible1) UNRELEASED; urgency=low
+
+  * Make the package build reproducibly:
+    - Fix mtimes before building binary packages.
+    - Stop recording the current time when creating gzip files.
+    - Sort file list in md5sums.
+    - Fix mtimes before building source tarball.
+    - Sort file list in binutils source tarball.
+    - Call strip-nondeterminism on static libraries.
+
+ -- Jérémy Bobbio <lu...@debian.org>  Fri, 02 Jan 2015 16:33:56 +0100
+
 binutils (2.25-3) unstable; urgency=medium
 
   * Don't build as a release candidate, fixing the upper shlibs dependency.
diff -u binutils-2.25/debian/control binutils-2.25/debian/control
--- binutils-2.25/debian/control
+++ binutils-2.25/debian/control
@@ -6,7 +6,8 @@
 Standards-Version: 3.9.6
 Build-Depends: autoconf (>= 2.64), dpkg-dev (>= 1.17.11),
   bison, flex, gettext, texinfo, dejagnu, quilt,
-  python3:any, file, xz-utils, lsb-release, zlib1g-dev
+  python3:any, file, xz-utils, lsb-release, zlib1g-dev,
+  strip-nondeterminism
 Vcs-Browser: https://code.launchpad.net/~doko/binutils/pkg-2.25-debian
 Vcs-Bzr: http://bazaar.launchpad.net/~doko/binutils/pkg-2.25-debian
 XS-Testsuite: autopkgtest
diff -u binutils-2.25/debian/rules binutils-2.25/debian/rules
--- binutils-2.25/debian/rules
+++ binutils-2.25/debian/rules
@@ -146,6 +146,7 @@
 ifneq (,$(DATE))
 #  DATE_EXT	:= .$(DATE)
 endif
+BUILD_DATE := $(shell dpkg-parsechangelog | sed -n -e 's/^Date: //p')
 
 is_rc = yes
 is_rc =
@@ -745,6 +746,8 @@
 	$(call strip_package, $(p_mul), $(d_mul))
 endif
 
+	find $(d_dev) -name '*.a' -print0 | xargs -0r strip-nondeterminism --type ar
+
 	: # Don't want /usr/<arch>-linux to exist in any package
 	rm -rf $(d_bin)/$(PF)/$(DEB_HOST_GNU_TYPE)
 
@@ -915,24 +918,28 @@
 	for i in bfd gas gprof ld; do \
 	  ln -sf ../$(p_bin)/$$i $(d_doc)/$(PF)/share/doc/$(p_doc)/$$i; \
 	done
-	find $(d_doc)/$(PF)/share/doc/$(p_doc) -maxdepth 1 -type f ! -name copyright | xargs gzip -9
-	gzip -9 $(d_doc)/$(PF)/share/info/*
+	find $(d_doc)/$(PF)/share/doc/$(p_doc) -maxdepth 1 -type f ! -name copyright | xargs gzip -9n
+	gzip -9n $(d_doc)/$(PF)/share/info/*
 
 	dpkg-gencontrol -isp -P$(d_doc) -p$(p_doc)
 	chown -R root:root $(d_doc)
 	chmod -R go=rX  $(d_doc)
+	find $(d_doc) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_doc) ..
 
 	$(install_dir) $(d_src)/$(PF)/share/doc/$(p_src)/
 	$(install_file)	debian/changelog $(d_src)/$(PF)/share/doc/$(p_src)/changelog.Debian
 	$(install_file)	debian/copyright $(d_src)/$(PF)/share/doc/$(p_src)/
-	find $(d_src)/$(PF)/share/doc/$(p_src) -maxdepth 1 -type f ! -name copyright | xargs gzip -9
+	find $(d_src)/$(PF)/share/doc/$(p_src) -maxdepth 1 -type f ! -name copyright | xargs gzip -9n
 endif # ifndef BACKPORT
 
 	$(install_dir) $(d_src)/DEBIAN
 	$(install_dir) $(d_src)/$(PF)/src/binutils/patches
 	$(install_file) debian/patches/* $(d_src)/$(PF)/src/binutils/patches/
-	tar -c --xz -C .. --exclude=CVS \
+	cd .. && find $(sources_files) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)' && \
+		find $(source_files) -type f -print0 | LC_ALL=C sort -z | tar --null -T - -c --xz --exclude=CVS \
 		-f $(pwd)/$(d_src)/$(PF)/src/binutils/binutils-$(VERSION).tar.xz \
 		$(source_files)
 
@@ -950,6 +957,8 @@
 	dpkg-gencontrol -isp -P$(d_src) -p$(p_src)
 	chown -R root:root $(d_src)
 	chmod -R go=rX  $(d_src)
+	find $(d_src) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_src) ..
 
 endif
@@ -975,7 +984,7 @@
 	$(install_dir) $(d_cross)/$(PF)/share/doc/$(p_cross)/
 	$(install_file)	debian/changelog $(d_cross)/$(PF)/share/doc/$(p_cross)/changelog.Debian
 	$(install_file)	debian/copyright debian/README.cross $(d_cross)/$(PF)/share/doc/$(p_cross)/
-	gzip -9f $(d_cross)/$(PF)/share/doc/$(p_cross)/changelog.Debian
+	gzip -9nf $(d_cross)/$(PF)/share/doc/$(p_cross)/changelog.Debian
 
 	for pkg in bfd gas gprof ld; do \
 	  ln -sf ../binutils/$$pkg $(d_cross)/$(PF)/share/doc/$(p_cross)/$$pkg; \
@@ -985,6 +994,8 @@
 	dpkg-shlibdeps $(d_cross)/$(PF)/bin/*
 	dpkg-gencontrol -isp -P$(d_cross) -p$(p_cross) \
 		-VBuilt-Using="$(shell dpkg-query -f '$${source:Package} (= $${source:Version}), ' -W binutils-source)"
+	find $(d_cross) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_cross) ..
 
 else
@@ -1111,53 +1122,63 @@
 	$(install_file) gprof/bbconv.pl $(d_bin)/$(PF)/share/doc/$(p_bin)/gprof/.
 
 	: # Compress stuff that needs it
-	gzip -9 $(d_bin)/$(PF)/share/man/man1/*.1
-	find $(d_bin)/$(PF)/share/doc/$(p_bin)/ -type f ! -name copyright -a ! -name bbconv.pl | xargs gzip -9
+	gzip -9n $(d_bin)/$(PF)/share/man/man1/*.1
+	find $(d_bin)/$(PF)/share/doc/$(p_bin)/ -type f ! -name copyright -a ! -name bbconv.pl | xargs gzip -9n
 
 	: # Finish it all up
 	find $(d_bin) -type f | xargs file | grep ELF | cut -d: -f 1 | xargs dpkg-shlibdeps
 	dpkg-gencontrol -isp -P$(d_bin) -p$(p_bin) $(CONFLICTS) $(gold_provides)
-	cd $(d_bin) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | xargs md5sum > DEBIAN/md5sums
+	cd $(d_bin) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | LC_ALL=C sort | xargs md5sum > DEBIAN/md5sums
 
 	rm -f debian/substvars
 	dpkg-gencontrol -isp -P$(d_dev) -p$(p_dev)
-	cd $(d_dev) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | xargs md5sum > DEBIAN/md5sums
+	cd $(d_dev) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | LC_ALL=C sort | xargs md5sum > DEBIAN/md5sums
 
 ifeq ($(with_multiarch),yes)
 	rm -f debian/substvars
 	find $(d_mul) -type f | xargs file | grep ELF | cut -d: -f 1 | xargs dpkg-shlibdeps
 	dpkg-gencontrol -isp -P$(d_mul) -p$(p_mul)
-	cd $(d_mul) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | xargs md5sum > DEBIAN/md5sums
+	cd $(d_mul) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | LC_ALL=C sort | xargs md5sum > DEBIAN/md5sums
 
 	rm -f debian/substvars
 	mkdir -p $(d_mdev)/DEBIAN
 	dpkg-gencontrol -isp -P$(d_mdev) -p$(p_mdev)
-	cd $(d_mdev) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | xargs -r md5sum > DEBIAN/md5sums
+	cd $(d_mdev) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | LC_ALL=C sort | xargs -r md5sum > DEBIAN/md5sums
 endif
 
 ifeq ($(DEB_HOST_ARCH),hppa)
 	rm -f debian/substvars
 	find $(d_hppa64) -type f | xargs file | grep ELF | cut -d: -f 1 | xargs dpkg-shlibdeps
 	dpkg-gencontrol -isp -P$(d_hppa64) -p$(p_hppa64)
-	cd $(d_hppa64) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | xargs md5sum > DEBIAN/md5sums
+	cd $(d_hppa64) && find -type f  ! -regex './DEBIAN/.*' -printf '%P\n' | LC_ALL=C sort | xargs md5sum > DEBIAN/md5sums
 endif
 
 	chown -R root:root $(d_bin) $(d_dev)
 	chmod -R go=rX  $(d_bin) $(d_dev)
+	find $(d_bin) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_bin) ..
+	find $(d_dev) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_dev) ..
 ifeq ($(with_multiarch),yes)
 	chown -R root:root $(d_mul)
 	chmod -R go=rX  $(d_mul)
+	find $(d_mul) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_mul) ..
 
 	chown -R root:root $(d_mdev)
 	chmod -R go=rX  $(d_mdev)
+	find $(d_mdev) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_mdev) ..
 endif
 ifeq ($(DEB_HOST_ARCH),hppa)
 	chown -R root:root $(d_hppa64)
 	chmod -R go=rX  $(d_hppa64)
+	find $(d_hppa64) -depth -newermt '$(BUILD_DATE)' -print0 | \
+		xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
 	dpkg --build $(d_hppa64) ..
 endif
 
@@ -1225,7 +1246,7 @@
 	: # Get rid of .la files since libtool obviously has no idea about transient paths
 	rm -f $(d_cross)/$(PF)/$(DEB_HOST_GNU_TYPE)/$(TARGET)/lib/*.la
 
-	gzip -9 $(d_cross)/$(PF)/share/man/man1/*
+	gzip -9n $(d_cross)/$(PF)/share/man/man1/*
 	touch $@
 
 configure-host-cross-stamp: configure-cross-stamp

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Reproducible-builds mailing list
Reproducible-builds@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds

Reply via email to