texlive: create reproducible .fmt files

Without these changes, building this package twice does not produce the bit-by-bit identical result each time, making it harder to detect CI breaches. You can read more about this at https://reproducible-builds.org/ .

Fixing bit-by-bit reproducibility also has additional advantages, such as avoiding hard-to-reproduce bugs, making content-addressed storage more effective and reducing rebuilds in such systems.

Based on the work done in Debian and documented at
https://salsa.debian.org/live-team/live-build/-/blob/master/examples/hooks/reproducible/0139-reproducible-texlive-binaries-fmt-files.hook.chroot

Fixes #192736
This commit is contained in:
Arnout Engelen 2022-10-17 17:44:27 +02:00
parent b7a6fde153
commit a41ae443f6
No known key found for this signature in database
GPG key ID: 061107B0F74A6DAA
3 changed files with 30 additions and 2 deletions

View file

@ -169,6 +169,18 @@ core-big = stdenv.mkDerivation { #TODO: upmendex
inherit (common) src prePatch;
patches = [
# improves reproducibility of fmt files. This patch has been proposed upstream,
# but they are considering some other approaches as well. This is fairly
# conservative so we can safely apply it until they make a decision
# https://mailman.ntg.nl/pipermail/dev-luatex/2022-April/006650.html
(fetchpatch {
name = "reproducible_exception_strings.patch";
url = "https://bugs.debian.org/cgi-bin/bugreport.cgi?att=1;bug=1009196;filename=reproducible_exception_strings.patch;msg=5";
sha256 = "sha256-RNZoEeTcWnrLaltcYrhNIORh42fFdwMzBfxMRWVurbk=";
})
];
hardeningDisable = [ "format" ];
inherit (core) nativeBuildInputs;

View file

@ -50,7 +50,7 @@ in (buildEnv {
"/tex/generic/config" # make it a real directory for scheme-infraonly
];
nativeBuildInputs = [ makeWrapper ];
nativeBuildInputs = [ makeWrapper libfaketime ];
buildInputs = pkgList.extraInputs;
# This is set primarily to help find-tarballs.nix to do its job
@ -228,6 +228,21 @@ in (buildEnv {
FORCE_SOURCE_DATE=1 perl `type -P fmtutil.pl` --sys --all | grep '^fmtutil' # too verbose
#${bin.texlinks}/bin/texlinks "$out/bin" && wrapBin # do we need to regenerate format links?
# tex intentionally ignores SOURCE_DATE_EPOCH even when FORCE_SOURCE_DATE=1
# https://salsa.debian.org/live-team/live-build/-/blob/master/examples/hooks/reproducible/0139-reproducible-texlive-binaries-fmt-files.hook.chroot#L52
if [[ -d share/texmf-var/web2c/tex ]]
then
cd share/texmf-var/web2c/tex
faketime $(date --utc -d@$SOURCE_DATE_EPOCH --iso-8601=seconds) tex -ini -jobname=tex -progname=tex tex.ini
cd -
fi
if [[ -d share/texmf-var/web2c/luahbtex ]]
then
cd share/texmf-var/web2c/luahbtex
faketime $(date --utc -d@$SOURCE_DATE_EPOCH --iso-8601=seconds) luahbtex -ini -jobname=lualatex -progname=lualatex lualatex.ini
cd -
fi
# Disable unavailable map files
echo y | perl `type -P updmap.pl` --sys --syncwithtrees --force
# Regenerate the map files (this is optional)

View file

@ -5,6 +5,7 @@
{ stdenv, lib, fetchurl, runCommand, writeText, buildEnv
, callPackage, ghostscriptX, harfbuzz
, makeWrapper, python3, ruby, perl, gnused, gnugrep, coreutils
, libfaketime
, useFixedHashes ? true
, recurseIntoAttrs
}:
@ -23,7 +24,7 @@ let
# function for creating a working environment from a set of TL packages
combine = import ./combine.nix {
inherit bin combinePkgs buildEnv lib makeWrapper writeText
stdenv python3 ruby perl gnused gnugrep coreutils;
stdenv python3 ruby perl gnused gnugrep coreutils libfaketime;
ghostscript = ghostscriptX; # could be without X, probably, but we use X above
};