Skip to content

build: refine reproducibility artifacts (relative paths, bzImage guard, busybox compiler, hashes.txt in zip, doc fixes) - #2181

Merged
tlaurion merged 5 commits into
linuxboot:masterfrom
tlaurion:build-artifact-refinements
Aug 7, 2026
Merged

build: refine reproducibility artifacts (relative paths, bzImage guard, busybox compiler, hashes.txt in zip, doc fixes)#2181
tlaurion merged 5 commits into
linuxboot:masterfrom
tlaurion:build-artifact-refinements

Conversation

@tlaurion

@tlaurion tlaurion commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Small refinements on top of the already-merged #2179.

Changes

  1. doc/reproducible-builds.md: fix misleading SOURCE_DATE_EPOCH wording; document hashes.txt/sha256sum.txt/sizes.txt output files

  2. modules/linux: improve bzImage UNCHANGED guard - plain cp -a instead of do-copy (no tmp hash noise); [ ! -f "$@" ] guard on first-build cmp

  3. modules/busybox: use HOSTCC="$(heads_cc)" (musl-cross compiler) instead of host gcc for busybox.mkll - only runs the preprocessor (-E), so no target binaries are produced; using the cross-compiler keeps the build chain self-contained (no host tools assumed)

  4. all: use relative paths in all hashes.txt/sizes.txt entries - $(build) = $(pwd)/build/... produced absolute paths, creating path-prefix noise in CI-vs-local diffs. Fix do-cpio, bzImage rule, all: ROM recipe, and all payload: recipe.

  5. Makefile: include hashes.txt in update zip - enables future introspection: hash files in the running firmware against the update's hashes.txt, instantly showing which files are identical and which differ. The update's hashes.txt copy also gets the ROM entry appended before zipping (the main HASHES file receives it only after the zip is assembled). Only makes the file available; the tool is deferred.

Verification

Local warm build (earlier head of this stack): ./docker_repro.sh make BOARD=EOL_t480-hotp-maximized - success, ROM 9547e87, 0 errors. x230 split-board build with the current zip/hashes changes: update-zip hashes.txt contains the ROM entry exactly once, main hashes.txt unaffected.

CI cross-check:


cd /tmp/ci-t480 && L=/home/user/heads/build/x86/EOL_t480-hotp-maximized; echo "=== zip-internal hashes.txt: CI vs LOCAL (sorted, minus header) ==="; diff <(unzip -p ci.zip hashes.txt | sort | tail -n +1 | grep -v '^2026-') <(unzip -p "$L/heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.zip" hashes.txt | sort | grep -v '^2026-') && echo "ALL 444 ENTRIES IDENTICAL (excluding build-time header)"; echo; echo "=== zip headers ==="; unzip -p ci.zip hashes.txt | head -1; unzip -p "$L/heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.zip" hashes.txt | head -1; echo; echo "=== zip ROM entries count ==="; unzip -p ci.zip hashes.txt | grep -c '\.rom'; unzip -p "$L/heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.zip" hashes.txt | grep -c '\.rom'; echo; echo "=== sha256sum.txt ==="; unzip -p ci.zip sha256sum.txt; unzip -p "$L/heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.zip" sha256sum.txt; echo; echo "=== whole-zip hash ==="; sha256sum ci.zip "$L/heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.zip"
=== zip-internal hashes.txt: CI vs LOCAL (sorted, minus header) ===
ALL 444 ENTRIES IDENTICAL (excluding build-time header)

=== zip headers ===
2026-08-07 18:35:41+00:00 9547e87095f8c0fc00c145d8c99d6f5dbb11c23f clean
2026-08-07 19:03:27+00:00 9547e87095f8c0fc00c145d8c99d6f5dbb11c23f clean

=== zip ROM entries count ===
1
1

=== sha256sum.txt ===
d6b5cdb376844b619abfc71b24c40332344a48088045730b1c1449aa9a816c07  heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.rom
d6b5cdb376844b619abfc71b24c40332344a48088045730b1c1449aa9a816c07  heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.rom

=== whole-zip hash ===
e209d08a946a48add45bd69ad1f6a2413b652caf4c738e31ec1b2c1bbe77ddc7  ci.zip
1726cac033ebbdb73c8e59e5f423081f7af799171c011d6ac9ace9e3bce89cea  /home/user/heads/build/x86/EOL_t480-hotp-maximized/heads-EOL_t480-hotp-maximized-202608071425-v0.2.1-3124-g9547e87.zip

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refines the project’s reproducible-build artifacts and packaging so that hash manifests are less environment-dependent (path normalization) and more useful for later verification/introspection.

Changes:

  • Normalize hashes.txt/sizes.txt entries to use relative paths (avoid absolute $(pwd) prefixes).
  • Refine kernel bzImage copy/unchanged-guard behavior and reduce first-build noise.
  • Package hashes.txt into the coreboot update ZIP and update reproducibility documentation accordingly.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
modules/linux Adjusts bzImage copy/UNCHANGED guard and switches hash/size logging to relative paths.
modules/busybox Uses HOSTCC="$(heads_cc)" for busybox.mkll generation to avoid depending on host gcc.
Makefile Adds hashes.txt to the update ZIP; converts ROM/payload and cpio hash/size output to relative paths.
doc/reproducible-builds.md Clarifies SOURCE_DATE_EPOCH behavior and documents generated hash-related output files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread modules/linux Outdated
Comment thread modules/linux
@tlaurion
tlaurion force-pushed the build-artifact-refinements branch from 1fd635a to 43e3173 Compare August 7, 2026 16:43
…t output files

The prior wording "git log always falls back to 0" is misleading --
git log does not fall back; it fails when .git is missing, and the
|| echo 0 shell construct in modules/musl-cross-make sets the value.
Describe the actual mechanism: the build system cannot derive a commit
timestamp from extracted tarballs, so modules/musl-cross-make falls
back to echo 0 when git log fails.

Also add a new 'Output files' section in doc/reproducible-builds.md
describing what each hash-related file (hashes.txt, sizes.txt,
sha256sum.txt) contains and how they relate to reproducibility
verification.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
… cmp stderr)

The FORCE prerequisite (already in master) ensures the rule always
runs, but the do-copy call produced sha256sum/stat noise for the
temporary file, and cmp emitted stderr on first build when the target
did not exist.

- Replace do-copy with plain cp -a + INSTALL progress line (no tmp
  hash/stat noise in build log)
- Guard cmp with [ ! -f "$@" ] || so the first build takes the
  "changed" branch without invoking cmp at all

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
@tlaurion
tlaurion force-pushed the build-artifact-refinements branch from 7d1e598 to d0a757f Compare August 7, 2026 18:00
@tlaurion
tlaurion requested a lite review from Copilot August 7, 2026 18:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (2)

modules/busybox:39

  • The new comment claims the cross-compiler preprocessor is “identical to host gcc” for header parsing. Even with -E, GCC defines target-/sysroot-specific builtins and searches different default include paths, so the output is not necessarily identical. This is a factual inaccuracy in the comment and could confuse future debugging if busybox.links generation ever diverges across environments.
	# mkll only runs the preprocessor (-E): cross-compiler is
	# identical to host gcc for text-only header parsing and keeps
	# the build chain self-contained (no host tools assumed)

Makefile:291

  • hashes.txt is copied into update_pkg/ before the final ROM hash/size lines are appended to $(HASHES) (via the later all payload: rule). As a result, the hashes.txt inside the update ZIP can be missing the ROM entry, which undermines the stated goal of using it for offline verification/introspection.
	cp "$<" "$(board_build)/update_pkg/"
	cp "$(HASHES)" "$(board_build)/update_pkg/"
	cd "$(board_build)/update_pkg" && sha256sum "$(CB_OUTPUT_FILE)" >sha256sum.txt
	cd "$(board_build)/update_pkg" && zip -9 "$@" "$(CB_OUTPUT_FILE)" sha256sum.txt "$(notdir $(HASHES))"

mkll only runs the preprocessor (-E) on already-generated config
headers, producing a text-only applet list -- no binaries, no
cross-compilation needed.

Replace HOSTCC="$(busybox_hostcc)" (host gcc via variable) with
HOSTCC="$(heads_cc)" (musl-cross compiler used by every other build
step).  The variable was unnecessary indirection; the cross-compiler
keeps the build chain self-contained with no host tool assumptions.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
All hashes.txt and sizes.txt writers now use consistent relative
paths.  initrd.cpio.xz already stripped the $(pwd)/ prefix; the
remaining writers did not, producing path-prefix diffs between CI and
local builds.

- modules/linux: bzImage sha256sum/stat stripped $(pwd)/ prefix from $@
- Makefile do-cpio: strip $(pwd)/ prefix from $1
- Makefile all: ROM hash/size: strip $(pwd)/ prefix from $(board_build)
- Makefile all payload: hash/size: strip $(pwd)/ prefix from $<

Now every hashes.txt and sizes.txt entry uses a consistent relative
path format, eliminating path-prefix diffs between CI and local builds.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Including hashes.txt in the update ZIP enables future work: a tool
that hashes files in the running firmware and compares them against
the update's hashes.txt, instantly showing which files are identical
and which differ.  For the same commit, all files match, confirming
the same ROM is already installed.  This commit only makes
hashes.txt available in the ZIP; the tool itself is deferred.

The ZIP copy gets the ROM entry appended before zipping: the main
HASHES file receives it only after the ZIP was assembled, so the
update's hashes.txt would otherwise miss the ROM hash.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
@tlaurion
tlaurion force-pushed the build-artifact-refinements branch from d0a757f to 9547e87 Compare August 7, 2026 18:29
@tlaurion tlaurion added this to the measuredboot milestone Aug 7, 2026
@tlaurion
tlaurion merged commit 514ef67 into linuxboot:master Aug 7, 2026
52 of 55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants