Source: nethack
Version: 3.6.0-1
Severity: wishlist
Tags: patch
User: reproducible-bui...@lists.alioth.debian.org
Usertags: timestamps locale cpu
X-Debbugs-Cc: reproducible-bui...@lists.alioth.debian.org

Hi!

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

There are three issues that prevent building it reproducibly:
- the nhdat file is not reproducible, because the order of archive
  members varies depending on the locale. Setting LC_ALL to C expands
  the files in DATDLB always in the same way.
- makedefs uses the current date/time for the build date that gets
  embedded. By using $SOURCE_DATE_EPOCH, the date from the latest
  changelog entry is used instead.
- parallel building causes that src/objects.o and src/monst.o are build
  either from within src/ or from util/ (as those files are used by
  nethack and by makedefs), which results in a different build path
  embedded into the binary. This is solved by building makedefs
  explicitely before nethack.

Regards,
 Reiner

[1]: https://wiki.debian.org/ReproducibleBuilds
diff --git a/debian/patches/0025-reproducible-build.patch b/debian/patches/0025-reproducible-build.patch
new file mode 100644
index 0000000..50f959f
--- /dev/null
+++ b/debian/patches/0025-reproducible-build.patch
@@ -0,0 +1,50 @@
+Author: Reiner Herrmann <rei...@reiner-h.de>
+Description: enable reproducible building
+ - set LC_ALL to C so the shell sorts files in DATDLB after
+   wildcard expansion independent of the configured locale
+ - read timestamp for the build date from environment.
+   https://reproducible-builds.org/specs/source-date-epoch/
+
+--- a/sys/unix/Makefile.top
++++ b/sys/unix/Makefile.top
+@@ -186,7 +186,7 @@
+ 
+ dlb:
+ 	( cd util ; $(MAKE) dlb )
+-	( cd dat ; ../util/dlb cf nhdat $(DATDLB) )
++	( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) )
+ 
+ # recover can be used when INSURANCE is defined in include/config.h
+ # and the checkpoint option is true
+--- a/util/makedefs.c
++++ b/util/makedefs.c
+@@ -1222,7 +1222,7 @@
+ #else
+     time_t clocktim = 0;
+ #endif
+-    char *c, cbuf[60], buf[BUFSZ];
++    char *c, cbuf[60], buf[BUFSZ], *source_date_epoch;
+     const char *ul_sfx;
+ 
+     /* before creating date.h, make sure that xxx_GRAPHICS and
+@@ -1244,7 +1244,10 @@
+     Fprintf(ofp, "%s", Dont_Edit_Code);
+ 
+     (void) time(&clocktim);
+-    Strcpy(cbuf, ctime(&clocktim));
++    source_date_epoch = getenv("SOURCE_DATE_EPOCH");
++    if (source_date_epoch)
++        clocktim = strtoull(source_date_epoch, NULL, 10);
++    Strcpy(cbuf, asctime(gmtime(&clocktim)));
+ 
+     for (c = cbuf; *c; c++)
+         if (*c == '\n')
+@@ -1281,7 +1284,7 @@
+     Fprintf(ofp, "\n");
+ #ifdef AMIGA
+     {
+-        struct tm *tm = localtime((time_t *) &clocktim);
++        struct tm *tm = asctime(gmtime((time_t *) &clocktim));
+         Fprintf(ofp, "#define AMIGA_VERSION_STRING ");
+         Fprintf(ofp, "\"\\0$VER: NetHack %d.%d.%d (%d.%d.%d)\"\n",
+                 VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, tm->tm_mday,
diff --git a/debian/patches/series b/debian/patches/series
index ea58e42..4a93708 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@
 0021-fix-kfreebsd-ftbfs.patch
 0023-gcc-warning-fixes.patch
 0024-lisp-3.6.patch
+0025-reproducible-build.patch
diff --git a/debian/rules b/debian/rules
index 18f4b05..b7251c2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -30,6 +30,7 @@ define build_target
 	$(MAKE) clean
 	touch include/config.h
 	sleep 2
+	$(MAKE) LFLAGS='$(LFLAGS)' CFLAGS='$(CFLAGS)' LINK='$$(CC)' -C util makedefs
 	$(MAKE) LFLAGS='$(LFLAGS)' CFLAGS='$(CFLAGS) $(EXTRACPP_$1)' \
 		WINSRC='$(SRC_$1)' WINOBJ='$(OBJ_$1)' WINLIB='$(LIB_$1)' \
 		LINK='$$(CC)' $(EXTRA_$1) GAME='nethack-$1' \

Attachment: signature.asc
Description: PGP signature

Reply via email to