From 0c54d91dd1d33235ae97566600e692edfb613642 Mon Sep 17 00:00:00 2001
From: f321x <f@f321x.com>
Date: Thu, 10 Jul 2025 17:45:20 +0200
Subject: [PATCH] make docker build reproducible

attempts to make the docker build more reproducible by:
* pinning the docker image (alpine:3.21) to a hash
* version pinning the apk packages in the dockerfile
* setting TZ, LC_ALL and SOURCE_DATE_EPOCH in the container
* only building single threaded (make -j1)
* use a fixed build directory in `build-runtime.sh` instead of mktemp
* prevent linker from adding build id (-Wl,--build-id=none)
* replace absolute build paths in debug info with relative paths
  (-fdebug-prefix-map=$(PWD)=.)
* replace absolute paths in all compiler output with relative paths
  (-ffile-prefix-map=$(PWD)=.)
* stop adding gnu-debuglink to runtime binary
---
 scripts/build-runtime.sh               | 18 +++++++++++----
 scripts/common/install-dependencies.sh |  2 +-
 scripts/docker/Dockerfile              | 32 ++++++++++++++++++++++----
 src/runtime/Makefile                   |  2 +-
 4 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/scripts/build-runtime.sh b/scripts/build-runtime.sh
index 3ce3b91..e11f082 100755
--- a/scripts/build-runtime.sh
+++ b/scripts/build-runtime.sh
@@ -8,8 +8,10 @@ set -euo pipefail
 out_dir="$(readlink -f "$(pwd)")"/out
 mkdir -p "$out_dir"

-# we create a temporary build directory
-build_dir="$(mktemp -d -t type2-runtime-build-XXXXXX)"
+# we create a temporary build directory with a fixed name for reproducibility
+build_dir="$(readlink -f "$(pwd)")"/build-runtime-temp
+rm -rf "$build_dir"
+mkdir -p "$build_dir"

 # since the plain ol' Makefile doesn't support out-of-source builds at all, we need to copy all the files
 cp -R src "$build_dir"/
@@ -17,13 +19,14 @@ cp -R src "$build_dir"/
 pushd "$build_dir"

 pushd src/runtime/
-make -j"$(nproc)" runtime
+make -j1 runtime

 file runtime

 objcopy --only-keep-debug runtime runtime.debug

-strip --strip-debug --strip-unneeded runtime
+# strip --strip-debug --strip-unneeded runtime
+strip --strip-all runtime

 ls -lh runtime runtime.debug

@@ -50,7 +53,7 @@ fi
 mv runtime runtime-"$architecture"
 mv runtime.debug runtime-"$architecture".debug

-objcopy --add-gnu-debuglink runtime-"$architecture".debug runtime-"$architecture"
+# objcopy --add-gnu-debuglink runtime-"$architecture".debug runtime-"$architecture"

 # "classic" magic bytes which cannot be embedded with compiler magic, always do AFTER strip
 # needs to be done after calls to objcopy, strip etc.
@@ -61,3 +64,8 @@ cp runtime-"$architecture" "$out_dir"/
 cp runtime-"$architecture".debug "$out_dir"/

 ls -al "$out_dir"
+
+# cleanup
+popd  # return to build_dir
+popd  # return to original working directory
+rm -rf "$build_dir"
diff --git a/scripts/common/install-dependencies.sh b/scripts/common/install-dependencies.sh
index 0e21cdb..5237079 100755
--- a/scripts/common/install-dependencies.sh
+++ b/scripts/common/install-dependencies.sh
@@ -39,7 +39,7 @@ tar xf 0.5.2.tar.gz
 pushd squashfuse-*/
 ./autogen.sh
 ./configure LDFLAGS="-static"
-make -j"$(nproc)"
+make -j1
 make install
 /usr/bin/install -c -m 644 ./*.h '/usr/local/include/squashfuse'
 popd
diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile
index 07b6533..fba9c6e 100644
--- a/scripts/docker/Dockerfile
+++ b/scripts/docker/Dockerfile
@@ -1,13 +1,35 @@
-FROM alpine:3.21
+FROM alpine:3.21@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c

 # includes dependencies from https://git.alpinelinux.org/aports/tree/main/fuse3/APKBUILD
 RUN apk add --no-cache \
-    bash alpine-sdk util-linux strace file autoconf automake libtool xz \
-    eudev-dev gettext-dev linux-headers meson \
-    zstd-dev zstd-static zlib-dev zlib-static clang musl-dev mimalloc-dev
+    bash=5.2.37-r0 \
+    alpine-sdk=1.1-r0 \
+    util-linux=2.40.4-r1 \
+    strace=6.12-r0 \
+    file=5.46-r2 \
+    autoconf=2.72-r0 \
+    automake=1.17-r0 \
+    libtool=2.4.7-r3 \
+    xz=5.6.3-r1 \
+    eudev-dev=3.2.14-r5 \
+    gettext-dev=0.22.5-r0 \
+    linux-headers=6.6-r1 \
+    meson=1.6.1-r0 \
+    zstd-dev=1.5.6-r2 \
+    zstd-static=1.5.6-r2 \
+    zlib-dev=1.3.2-r0 \
+    zlib-static=1.3.2-r0 \
+    clang19=19.1.4-r0 \
+    musl-dev=1.2.5-r11 \
+    mimalloc2-dev=2.1.7-r0

 COPY scripts/common/install-dependencies.sh /tmp/scripts/common/install-dependencies.sh
 COPY patches/ /tmp/patches/

+# Set environment variables for reproducible build
+ENV SOURCE_DATE_EPOCH=1640995200
+ENV TZ=UTC
+ENV LC_ALL=C
+
 WORKDIR /tmp
-RUN bash scripts/common/install-dependencies.sh
+RUN bash scripts/common/install-dependencies.sh
\ No newline at end of file
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index 9fd4165..3a3cbaa 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -1,6 +1,6 @@
 GIT_COMMIT := $(shell cat version)
 CC            = clang
-CFLAGS        = -std=gnu99 -Os -D_FILE_OFFSET_BITS=64 -DGIT_COMMIT=\"$(GIT_COMMIT)\" -T data_sections.ld -ffunction-sections -fdata-sections -Wl,--gc-sections -static -Wall -Werror -static-pie
+CFLAGS        = -std=gnu99 -Os -D_FILE_OFFSET_BITS=64 -DGIT_COMMIT=\"$(GIT_COMMIT)\" -T data_sections.ld -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--build-id=none -static -Wall -Werror -static-pie -fdebug-prefix-map=$(PWD)=. -ffile-prefix-map=$(PWD)=.
 LIBS          = -lsquashfuse -lsquashfuse_ll -lzstd -lz -lfuse3 -lmimalloc

 all: runtime
--
2.50.0
