Reproducible builds - #300
Open
roxell wants to merge 4 commits into
Open
Conversation
bhcopeland
reviewed
Aug 14, 2026
| dotgit = directory / ".git" | ||
| if not dotgit.is_file(): | ||
| return None | ||
| gitdir = Path(dotgit.read_text().partition("gitdir:")[2].strip()) |
Member
There was a problem hiding this comment.
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.
bhcopeland
reviewed
Aug 14, 2026
| 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) |
Member
There was a problem hiding this comment.
so git in container will find empty_dir (on my comment above) and an empty gitdir / version metadata gets lost
bhcopeland
reviewed
Aug 14, 2026
| assert "Decompressing" in print_call | ||
|
|
||
|
|
||
| class TestGetGitDir: |
Member
There was a problem hiding this comment.
I'd add test_relative_gitdir as both cases use absloute paths
bhcopeland
reviewed
Aug 14, 2026
| # 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 = ( |
Member
There was a problem hiding this comment.
I'd put the source map first here (or I guess skip build_dir when is under source tree)
bhcopeland
reviewed
Aug 14, 2026
|
|
||
| # 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"] |
bhcopeland
reviewed
Aug 14, 2026
| 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. | ||
|
|
||
|
|
Member
There was a problem hiding this comment.
reproducible_builds.md is untouched.
bhcopeland
reviewed
Aug 14, 2026
| (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): |
Member
There was a problem hiding this comment.
ro=True is untrested due to the call[0][0]
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
force-pushed
the
reproducible-builds
branch
from
August 20, 2026 07:39
aa5c160 to
38c8862
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.