bazel-contrib / bazel-contrib/rules_go
Go 1.25: `go tool` fails under rules_go stdlib GOROOT
- Dominant language
- Go
- Stars
- 1.5k
- Forks
- 760
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 12
Description
### Summary
Under rules_go, action environments may set `GOROOT` to the stdlib output tree
(e.g. `bazel-out/.../external/rules_go+/stdlib_`), which is sufficient for
compilation (`GOROOT/pkg` contains stdlib archives) but is not a full SDK GOROOT.
In particular, it may not contain the `go tool` binaries (like objdump) under
`GOROOT/pkg/tool/$GOHOSTOS_$GOHOSTARCH`, and it does not contain sources under
`GOROOT/src`.
With Go 1.25, `go tool ` may build tools on-demand and requires access
to cmd/* sources and a writable build cache. See:
https://go.dev/issue/71867
As a result, running `go tool` from an analyzer/tool inside an action sandbox
can fail when it inherits the stdlib-output-tree GOROOT.
### Reproduction
When GOROOT points at the stdlib output tree, `go tool objdump` fails:
1. Identify the stdlib output GOROOT in a rules_go build (example value):
`GOROOT=bazel-out/.../external/rules_go+/stdlib_`
2. Run (using the Go binary from the hermetic SDK):
`GOROOT= /bin/go tool objdump`
Expected: objdump runs (or is built on demand)
Actual: `go: no such tool "objdump"`
This is observable in practice via analyzers (e.g. nogo analyzers) that shell
out to `go tool objdump` to disassemble archives and improve results.
Why this is a problem
- The stdlib-output-tree GOROOT is not a real Go distribution layout, but it
is placed in the environment, so downstream tools reasonably assume `go tool`
should work.
- Go 1.25 increases the likelihood that `go tool` needs either:
- a prebuilt tool binary under GOROOT/pkg/tool/... or
- sources under GOROOT/src/cmd/... plus a writable cache (https://go.dev/issue/71867).
### Request / proposed direction
Provide a supported mechanism for action tools/analyzers to invoke Go SDK tools
under Bazel, for example:
- a "tooling env" that points GOROOT at the SDK root (with src/) and sets an
explicit writable GOCACHE, or
- a first-class way to depend on and locate specific SDK tools (e.g. objdump),
so analyzers can run them without relying on `go tool` behavior under a
non-SDK GOROOT, or
- document that invoking `go tool` inside actions is unsupported when GOROOT is
the stdlib output tree, and provide recommended workarounds.
### Additional context
We attempted to force GOROOT to the SDK root for analysis, but analysis also
relies on the stdlib output tree GOROOT/pkg/.../*.a layout, so a single global
GOROOT value doesn't satisfy both compilation/analysis and SDK-tool execution.
A per-subprocess or explicit "SDK tool context" seems necessary.
I discovered all this in https://github.com/google/gvisor/pull/12365 and this issue was written with the help of an LLM.
Contributor guide
Research direction
Start with the GOROOT handling in Bazel action environments and reproduce the failure using the hermetic SDK's bin/go tool objdump with GOROOT set to the stdlib output tree. Compare that environment with the SDK root and its sources and cache requirements. Done means a supported SDK-tool mechanism or documented workaround that lets analyzers invoke tools without breaking the stdlib archive layout.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- build-system, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100