Source: glibc
Version: 2.19-18
Severity: wishlist
Tags: patch
User: reproducible-builds@lists.alioth.debian.org
Usertags: timestamps fileordering umask username uname
Hi!
While working on the “reproducible builds” effort [1], we have noticed
that glibc could not be built reproducibly.
The attached patch addresses several issues:
1. The source tarball will now stay identical despite variations of
the time of the build, user, group, umask and file ordering.
2. version-info.h currently captures the build time and the current
kernel version. In the context of Debian this is not really useful
and a new patch simply removes it. The behavior is now the same
if built under Linux or not.
3. nscd uses the date and time of the build as a version marker. So a
patch is added to allow the build date to be set externally. The date
of the latest debian/changelog entry will be used instead of the
current time for Debian.
Once applied, glibc can be built reproducibly in our current
experimental framework.
[1]: https://wiki.debian.org/ReproducibleBuilds
--
Lunar .''`.
lunar@debian.org : :Ⓐ : # apt-get install anarchism
`. `'`
`-
diff --git a/debian/changelog b/debian/changelog
index a06fc11..fbb6d32 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+glibc (2.19-18.0~reproducible1) UNRELEASED; urgency=low
+
+ * Make the package build reproducibly:
+ - any/local-reproducible-version-info.diff: new patch to remove build
+ system information and build date from version-info.h.
+ - any/unsubmitted-allow-to-set-build-date.diff: allow to set the
+ build date through an environment variable when running ./configure.
+ This is then used in nscd.
+ - Set the previously mentioned build date to the latest debian/changelog
+ entry.
+ - Create source tarball in a deterministic manner: adjust file
+ modification time, user, group, permissions, and file order.
+
+ -- Jérémy Bobbio <lunar@debian.org> Thu, 23 Apr 2015 11:18:59 +0200
+
glibc (2.19-18) unstable; urgency=medium
[ Aurelien Jarno ]
diff --git a/debian/patches/any/local-reproducible-version-info.diff b/debian/patches/any/local-reproducible-version-info.diff
new file mode 100644
index 0000000..06012ea
--- /dev/null
+++ b/debian/patches/any/local-reproducible-version-info.diff
@@ -0,0 +1,49 @@
+To enable glibc to build reproducibly, we remove build system information
+and build date from version-info.h.
+
+diff --git a/csu/Makefile b/csu/Makefile
+index b5afea0..211c2e6 100644
+--- a/csu/Makefile
++++ b/csu/Makefile
+@@ -133,40 +133,7 @@ all-Banner-files = $(wildcard $(addsuffix /Banner,\
+ $(sysdeps-srcdirs))))
+ $(objpfx)version-info.h: $(common-objpfx)config.make $(all-Banner-files)
+ $(make-target-directory)
+- (case $(config-os) in \
+- linux*) version=`(printf '%s\n%s\n' \
+- '#include <linux/version.h>' \
+- UTS_RELEASE \
+- | $(CC) $(CPPFLAGS) -O -E -P - -DNOT_IN_libc=1 | \
+- sed -e 's/"\([^"]*\)".*/\1/p' -e d) 2>/dev/null`;\
+- if [ -z "$$version" ]; then \
+- version=`(printf '%s\n%s\n' \
+- '#include <linux/version.h>' \
+- LINUX_VERSION_CODE \
+- | $(CC) $(CPPFLAGS) -O -E -P - -DNOT_IN_libc=1 \
+- | sed -n -e '/^[123456789].*/p' \
+- | awk '{v=$$1; \
+- printf("%d.%d.%d\n", \
+- v/65535, v/256%256, v%256)}') \
+- 2>/dev/null`; \
+- fi; \
+- if [ -z "$$version" ]; then \
+- if [ -r /proc/version ]; then \
+- version=`sed 's/.*Linux version \([^ ]*\) .*/>>\1<</' \
+- < /proc/version`; \
+- else \
+- version=`uname -r`; \
+- fi; \
+- fi; \
+- os=`uname -s 2> /dev/null`; \
+- if [ -z "$$os" ]; then \
+- os=Linux; \
+- fi; \
+- printf '"Compiled on a %s %s system on %s.\\n"\n' \
+- "$$os" "$$version" "`date +%Y-%m-%d`";; \
+- *) ;; \
+- esac; \
+- files="$(all-Banner-files)"; \
++ (files="$(all-Banner-files)"; \
+ if test -n "$$files"; then \
+ printf '"Available extensions:\\n"\n'; \
+ sed -e '/^#/d' -e 's/^[[:space:]]*/ /' \
diff --git a/debian/patches/any/unsubmitted-allow-to-set-build-date.diff b/debian/patches/any/unsubmitted-allow-to-set-build-date.diff
new file mode 100644
index 0000000..df7662a
--- /dev/null
+++ b/debian/patches/any/unsubmitted-allow-to-set-build-date.diff
@@ -0,0 +1,75 @@
+nscd uses the date and time of the build as a version marker. In order to allow
+builds to be reproducible, we now allow the date to be set by the environment
+variable BUILD_DATE when running ./configure.
+
+diff --git a/config.h.in b/config.h.in
+index 40797e7..02ccb2d 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -246,3 +246,6 @@
+ #undef HAVE_MIPS_NAN2008
+
+ #endif
++
++/* Date and time of the build. */
++#undef BUILD_DATE
+diff --git a/configure.ac b/configure.ac
+index f3dd87d..aa0b30d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -2173,6 +2173,11 @@ RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
+ AC_SUBST(VERSION)
+ AC_SUBST(RELEASE)
+
++if "x$BUILD_DATE" = x; then
++ BUILD_DATE=`LC_ALL=C date -u '+%b %_d %Y %H:%M:%S'`
++fi
++AC_DEFINE_UNQUOTED([BUILD_DATE], ["$BUILD_DATE"], "Date and time of the build.")
++
+ AC_CONFIG_FILES([config.make Makefile])
+ AC_CONFIG_COMMANDS([default],[[
+ case $CONFIG_FILES in *config.make*)
+diff --git a/configure b/configure
+index fc023d0..b03be3f 100755
+--- a/configure
++++ b/configure
+@@ -7387,6 +7394,15 @@
+
+
+
++if "x$BUILD_DATE" = x; then
++ BUILD_DATE=`LC_ALL=C date -u '+%b %_d %Y %H:%M:%S'`
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define BUILD_DATE "$BUILD_DATE"
++_ACEOF
++
++
+ ac_config_files="$ac_config_files config.make Makefile"
+
+ ac_config_commands="$ac_config_commands default"
+diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
+index 997ff46..1e75b84 100644
+--- a/nscd/nscd_stat.c
++++ b/nscd/nscd_stat.c
+@@ -28,6 +28,7 @@
+ #include <libintl.h>
+
+ #include "nscd.h"
++#include "config.h"
+ #include "dbg_log.h"
+ #include "selinux.h"
+ #ifdef HAVE_SELINUX
+@@ -37,7 +38,11 @@
+
+
+ /* We use this to make sure the receiver is the same. */
++#ifdef BUILD_DATE
++static const char compilation[21] = BUILD_DATE;
++#else
+ static const char compilation[21] = __DATE__ " " __TIME__;
++#endif
+
+ /* Statistic data for one database. */
+ struct dbstat
diff --git a/debian/patches/series b/debian/patches/series
index a5f9cac..5a95f62 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -272,3 +272,5 @@ any/cvs-getnetbyname.diff
any/cvs-vfprintf.diff
any/cvs-wscanf.diff
any/cvs-ldconfig-aux-cache.diff
+any/local-reproducible-version-info.diff
+any/unsubmitted-allow-to-set-build-date.diff
diff --git a/debian/rules b/debian/rules
index 24167cd..e483a4e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -58,6 +58,11 @@ DEB_SOURCE_PACKAGE := $(strip $(shell egrep '^Source: ' debian/control | cut -f
DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ')
GLIBC_VERSION = $(shell echo $(DEB_VERSION) | sed -e 's/.*://' -e 's/-.*//')
+DEB_BUILD_DATE := $(shell dpkg-parsechangelog -S Date)
+# this one will be picked by configure script
+BUILD_DATE = $(shell date -u +'%b %_d %Y %H:%M:%S' -d '$(DEB_BUILD_DATE)')
+export BUILD_DATE
+
DEB_BUILDDIR ?= $(build-tree)/$(DEB_HOST_ARCH)-$(curpass)
GLIBC_SOURCES = $(addprefix $(shell basename $(CURDIR))/, \
diff --git a/debian/rules.d/build.mk b/debian/rules.d/build.mk
index 4df383c..91b8cab 100644
--- a/debian/rules.d/build.mk
+++ b/debian/rules.d/build.mk
@@ -275,9 +275,17 @@ endif
$(stamp)source: $(stamp)patch
mkdir -p $(build-tree)
- tar -c -J -C .. \
- -f $(build-tree)/glibc-$(GLIBC_VERSION).tar.xz \
- $(GLIBC_SOURCES)
+ cd .. && \
+ find $(GLIBC_SOURCES) -depth -newermt '$(DEB_BUILD_DATE)' \
+ -print0 | \
+ xargs -0r touch --no-dereference --date='$(DEB_BUILD_DATE)'
+ cd .. && \
+ find $(GLIBC_SOURCES) -print0 | \
+ LC_ALL=C sort -z | \
+ tar -c -J --null -T - --no-recursion \
+ --mode=go=rX,u+rw,a-s \
+ --owner=root --group=root --numeric-owner \
+ -f $(CURDIR)/$(build-tree)/glibc-$(GLIBC_VERSION).tar.xz
mkdir -p debian/glibc-source/usr/src/glibc
tar cf - --files-from debian/glibc-source.filelist \
| tar -x -C debian/glibc-source/usr/src/glibc -f -
Attachment:
signature.asc
Description: Digital signature