Conversation
PR #699 made @gnumake hermetic by downloading the full Zig toolchain (~80 MB, hzeller measured >10 min) and bootstrapping make with zig cc -static -target x86_64-linux-musl. hzeller's review: ahem, this downloads a huge zig compiler (gmake is written in C, not zig) (it takes > 10 minutes to download). Why not just compile gmake with the regular c compiler? With that, you get the hermeticity guarantees. Whipping out a BUILD file shoud be simple. Then upstreaming it to BZR will also make it useful for others. He's right that the project already registers a hermetic clang (@llvm_toolchain from toolchains_llvm, used to build OpenROAD/yosys), so zig is redundant for fetching a C compiler. Convert @gnumake to a thin repo rule that downloads the gmake source and overlays a checked-in cc_binary BUILD file plus a vendored config.h. Hermeticity for the make binary itself comes from: - Bazel sandbox -> execroot-relative paths in __FILE__ (no host paths leak into the binary). - linkopts = ["-Wl,--build-id=none", "-Wl,-s"] strip the random ELF build-id and symbols/debug info. - Same hermetic clang the rest of the project uses. Verified two clean output_bases on this host produce identical sha256 c678430fbbd1cff14b8b22e67080187fa49c762fbc7d45b8481a71e5d34770a9 (290 KB, stripped, dynamically linked). `make --version` reports GNU Make 4.4.1. A trivial Makefile recipe runs end-to-end. What this does not attempt: vendoring a sysroot to make the binary byte-identical across host glibc versions. cc_binary outputs are currently tied to host glibc symbol versions -- the same caveat that already applies to cc_binary-built yosys/openroad in this project. Project-wide cross-distro hermeticity is a separate, larger effort. Linux x86_64 only -- the registered LLVM tarball (LLVM-20.1.8-Linux-X64.tar.xz) doesn't support other hosts today, so the previous gnumake.bzl support for macOS/aarch64 was already dead. config.h is the autoconf output of `./configure --without-guile --disable-nls` against gmake 4.4.1, captured once and committed verbatim. HAVE_DECL_BSD_SIGNAL is patched to 0 because bsd_signal was removed from glibc 2.27+; the original config.h captured under musl had it set to 1. Signed-off-by: Øyvind Harboe <[email protected]>
Collaborator
Author
|
@hzeller This is what Claude did... |
hzeller
reviewed
May 7, 2026
| # gmake's remake.c / read.c reference these as install-prefix paths | ||
| # (.LIBPATTERNS, dlopen search). Match autotools' default --prefix | ||
| # so behavior is identical to a stock distro build. | ||
| '-DLIBDIR=\\"/usr/local/lib\\"', |
There was a problem hiding this comment.
thes paths don't really make sense. What happens if you set them empty or not at all ?
hzeller
reviewed
May 7, 2026
| """ | ||
|
|
||
| _MAKE_VERSION = "4.4.1" | ||
| _MAKE_SHA256 = "dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3" |
There was a problem hiding this comment.
where is this hash used to verify the download ?
Two inline review comments:
* gnumake.bzl:21 -- "where is this hash used to verify the download?"
Inline _MAKE_SHA256 directly into the download_and_extract call so the
hash sits next to the URL list and the verification is visible at a
glance.
* tools/gnumake/BUILD.gnumake:53 -- "thes paths don't really make sense.
What happens if you set them empty or not at all?" The bazel-built make
is never `make install`-ed, so /usr/local/{lib,share/locale,include} is
fiction. Set the three install-prefix -D values to empty strings so we
don't lie about where files live. Build, --version, and a trivial
Makefile recipe still work.
The make binary's sha256 changes (different preprocessor input -> different
object code), but determinism on a fixed host is preserved.
Signed-off-by: Øyvind Harboe <[email protected]>
On macOS (and any host where the registered LLVM toolchain isn't
applicable) the bazel-built @gnumake//:make won't compile. Document the
stock Bazel mechanism for swapping it out: --override_repository against
a tiny per-host overlay (BUILD.bazel + sh_binary wrapper + empty
REPO.bazel marker). No bazel-orfs helper, no new repo rule -- pure Bazel
idiom that any user can replicate in their own project.
Two pitfalls the docstring calls out, both verified locally:
* The override key must be the canonical repo name
`+orfs_repositories+gnumake`, not the apparent name `gnumake`.
Bazel silently ignores the apparent-name form for repos created by
a module extension.
* The override directory needs an empty REPO.bazel marker; without
it Bazel errors with "No MODULE.bazel, REPO.bazel, or WORKSPACE
file found".
Verified end-to-end: `bazelisk run --override_repository=... @gnumake//:make
-- --version` invokes the host's /usr/bin/make and prints its version.
Docs only -- no change to the build path. Default behavior on Linux
x86_64 is unchanged.
Signed-off-by: Øyvind Harboe <[email protected]>
Collaborator
Author
|
Pushed two follow-up commits:
Verified end-to-end here: |
Collaborator
Author
|
@hzeller OK now? |
Collaborator
Author
|
@hzeller Ok? |
|
the extension stuff still looks a bit complicated, but maybe that is what needed with bazel 8 ? Anyway, I think this is a good start; from there we should get it on bzr, then we don't need any *.bzl files. |
oharboe
added a commit
that referenced
this pull request
May 10, 2026
Two inline review comments:
* gnumake.bzl:21 -- "where is this hash used to verify the download?"
Inline _MAKE_SHA256 directly into the download_and_extract call so the
hash sits next to the URL list and the verification is visible at a
glance.
* tools/gnumake/BUILD.gnumake:53 -- "thes paths don't really make sense.
What happens if you set them empty or not at all?" The bazel-built make
is never `make install`-ed, so /usr/local/{lib,share/locale,include} is
fiction. Set the three install-prefix -D values to empty strings so we
don't lie about where files live. Build, --version, and a trivial
Makefile recipe still work.
The make binary's sha256 changes (different preprocessor input -> different
object code), but determinism on a fixed host is preserved.
Signed-off-by: Øyvind Harboe <[email protected]>
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.
PR #699 made @gnumake hermetic by downloading the full Zig toolchain (~80 MB, hzeller measured >10 min) and bootstrapping make with zig cc -static -target x86_64-linux-musl. hzeller's review:
ahem, this downloads a huge zig compiler (gmake is written in C, not
zig) (it takes > 10 minutes to download). Why not just compile gmake
with the regular c compiler? With that, you get the hermeticity
guarantees. Whipping out a BUILD file shoud be simple. Then upstreaming
it to BZR will also make it useful for others.
He's right that the project already registers a hermetic clang (@llvm_toolchain from toolchains_llvm, used to build OpenROAD/yosys), so zig is redundant for fetching a C compiler. Convert @gnumake to a thin repo rule that downloads the gmake source and overlays a checked-in cc_binary BUILD file plus a vendored config.h.
Hermeticity for the make binary itself comes from:
Verified two clean output_bases on this host produce identical sha256 c678430fbbd1cff14b8b22e67080187fa49c762fbc7d45b8481a71e5d34770a9 (290 KB, stripped, dynamically linked).
make --versionreports GNU Make 4.4.1. A trivial Makefile recipe runs end-to-end.What this does not attempt: vendoring a sysroot to make the binary byte-identical across host glibc versions. cc_binary outputs are currently tied to host glibc symbol versions -- the same caveat that already applies to cc_binary-built yosys/openroad in this project. Project-wide cross-distro hermeticity is a separate, larger effort.
Linux x86_64 only -- the registered LLVM tarball
(LLVM-20.1.8-Linux-X64.tar.xz) doesn't support other hosts today, so the previous gnumake.bzl support for macOS/aarch64 was already dead.
config.h is the autoconf output of
./configure --without-guile --disable-nlsagainst gmake 4.4.1, captured once and committed verbatim. HAVE_DECL_BSD_SIGNAL is patched to 0 because bsd_signal was removed from glibc 2.27+; the original config.h captured under musl had it set to 1.