Repository navigation
build: tools are built for the host, only the product follows the target - #653
Merged
Merged
Conversation
This was referenced Aug 24, 2026
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.
GOOS/GOARCHare ambient, so they reached everygoinvocation in the build — including the onesthat build and run the generators. Cross-compiling the product cross-compiled the toolchain that
generates its sources, and the host then tried to execute a foreign binary.
Closes #639. Unblocks #598.
The fix
HOST_GOpinsGOOS/GOARCHtogo env GOHOSTOS/GOHOSTARCH. Explicit rather than clearing thevariables, so a recipe using it says why it differs from a plain
go. When the target is the hostthese expand to the ambient values, so a native build is byte-for-byte what it was.
Three tool sites, not the two the issue named:
star(Makefile:141) — the generator every codegen recipe invokes as$(STAR).inventory(Makefile:549-550) —go runbuilds and executes in one step.gocyclo(Makefile:246) — found while fixing this.go installunder a cross-GOOS lands thebinary in
GOPATH/bin/<goos>_<goarch>/, so the-xprobe fails andmake complexitybreaks. Samedefect class, and it would have outlived the fix.
A second defect underneath it
With the tools pinned, codegen completed and the build failed further along — at the version-stamp
check, which executes the freshly built
build/writto confirm-Xbound. That guard existsbecause
-Xagainst a non-existent symbol is silently ignored, and every release before 2026-08-16shipped unstamped, unnoticed.
It cannot run a foreign binary, so it is now skipped when
CROSSis non-empty — and says so:A skipped guard that prints nothing reads exactly like a passing one. It still runs, unchanged, on
every native build.
The path collision, and why it is not a bug
buildwrites the product star tobuild/star$(GOEXE)— on a non-Windows target, the same path asthe host tool. A cross-build therefore leaves a target-architecture binary at
build/star.That self-heals:
build/star: FORCEdelegates tomake staron every run, so the next codegenrebuilds it host-side before invoking it. Verified, not assumed — cross-built for linux (leaving an
ELF at
build/star), forced codegen, and watched 25 star invocations succeed withbuild/starback toMach-O. Recorded in the Makefile comment; #598's
build/<goos>-<goarch>/layout removes the collisionoutright.
Verification
make build(native)GOOS=linux make buildexec format errorGOOS=windows GOARCH=arm64 make buildexec format errormake testmake vetdarwin / linux / windowsmake complexity,make shell-lintgofmt -lNot fixed here, and correct as-is:
make installruns the built binaries, so it fails under across-compile. Installing a foreign binary on this host is not a meaningful request.