Skip to content

Reproducible builds - #300

Open
roxell wants to merge 4 commits into
kernelci:masterfrom
roxell:reproducible-builds
Open

Reproducible builds#300
roxell wants to merge 4 commits into
kernelci:masterfrom
roxell:reproducible-builds

Conversation

@roxell

@roxell roxell commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Two builds of the same tree did not give the same artifacts. The build
dir and the source tree ended up in the debug info, the modules tarball
had a symlink to the build dir, and a build from a git worktree lost the
git part of the kernel version.

Two arm64 defconfig builds now give the same seven artifacts, vmlinux
byte for byte.

The compat vDSO needs a kernel patch too. Will send separately.

@roxell
roxell requested a review from bhcopeland August 6, 2026 13:43
Comment thread tuxmake/utils.py Outdated
dotgit = directory / ".git"
if not dotgit.is_file():
return None
gitdir = Path(dotgit.read_text().partition("gitdir:")[2].strip())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this assume gitdir is absolute.. the problem I was able to reproduce is submodules has no commondir. So I think a bit further down it wont get saved.

Comment thread tuxmake/build.py
self.runtime.add_volume(self.build_dir)
git_dir = get_git_dir(self.source_tree)
if git_dir:
self.runtime.add_volume(git_dir, ro=True)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

so git in container will find empty_dir (on my comment above) and an empty gitdir / version metadata gets lost

Comment thread test/test_utils.py
assert "Decompressing" in print_call


class TestGetGitDir:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd add test_relative_gitdir as both cases use absloute paths

Comment thread tuxmake/build.py
# The build dir has no trailing slash: the compilation directory is
# the build dir itself, and a map with a slash does not match it. The
# source tree has one, so the file names come out relative to it.
prefix_map = (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd put the source map first here (or I guess skip build_dir when is under source tree)

Comment thread tuxmake/build.py Outdated

# Set from the local build dir, so they are left out of the reproducer
# command line. The next build sets its own.
LOCAL_ENVIRONMENT = ["KCFLAGS", "KAFLAGS"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No KRUSTFLAGS?

Comment thread docs/targets.md
of the tarball. They point at the local build and source directories, so they
are broken anywhere else, and they made the tarball different on every build.


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

reproducible_builds.md is untouched.

Comment thread test/test_build.py
(linux_rw / ".git").write_text(f"gitdir: {git_dir}/worktrees/wt\n")
return linux_rw, git_dir

def test_mounts_the_git_dir(self, worktree, mocker, Popen):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ro=True is untrested due to the call[0][0]

roxell added 4 commits August 15, 2026 09:36
We set -ffile-prefix-map=<build dir>/= to hide the build path. The
trailing slash misses the compilation directory, which is the build dir
itself, so DW_AT_comp_dir keeps the full path. Two builds in different
build dirs are then not bit by bit identical.

Drop the slash and map the build dir to /tuxmake. Set the same in
KAFLAGS for the .S files, and keep both out of the reproducer.

Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
modules_install creates lib/modules/<ver>/build and source. They point
at the local build and source dirs. The build dir is new for every
build, so the tarball is never the same twice, even when the modules
are identical.

The links are broken outside the build machine anyway. Leave them out.

Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
We map the build dir, but not the source tree. Kbuild passes the source
files with an absolute path, so DW_AT_name keeps it. Two builds of the
same tree in different dirs are then not bit by bit identical.

Map the source tree too, with a trailing slash, so the file names come
out relative to the tree, like an in tree build. It comes first: the
last map that matches wins, and --build-dir can put the build dir
inside the source tree.

Rust needs its own, rustc does not take the gcc spelling. It also needs
the scope, the kernel sets --remap-path-scope=macro for out of tree
builds and rustc takes that once only. That needs a kernel patch, sent
separately.

Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
In a git worktree .git is a file that points at a dir outside the tree.
We only mount the source tree, so git does not work in the container.
setlocalversion finds nothing, and the kernel version loses the git
part. A worktree build gets 7.2.0-rc5 where the main tree gets
7.2.0-rc5-00001-gd000866da13d, and that string ends up in the kernel.

Mount the git dir read only, setlocalversion does not write.

The gitdir is not always absolute. worktree.useRelativePaths and
submodules write it relative to the tree, so resolve it there. Against
the current dir it gives a path that does not exist, and docker mounts
that as an empty dir without saying anything.

Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
@roxell
roxell force-pushed the reproducible-builds branch from aa5c160 to 38c8862 Compare August 20, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants