cmd/go: adjust `PATH` when `go run`/`go generate` runs the built binary
Go version
go version go1.22.0 darwin/amd64
Output of go env in your module/workspace:
$ go env GOTOOLCHAIN
auto
$ GOTOOLCHAIN=local go version
go version go1.21.9 darwin/amd64
$ go version
go version go1.22.0 darwin/amd64
What did you do?
-- go.mod --
module example.com/m
go 1.22.0
-- main.go --
package main
import "os"
import "os/exec"
func main() {
println(os.Getenv("GOROOT"))
bin, _ := exec.LookPath("go")
println(bin)
}
What did you see happen?
$ go run .
/Users/hakim/go/pkg/mod/golang.org/[email protected]
/usr/local/go/bin/go
Since my local version is go1.21.9, but my go.mod requires go1.22.0+,
toolchain switch occurs when running go run .. During the toolchain switch
the go command sets GOROOT so the switched go command can choose
the toolchains correctly.
When go run executes the compiled binary, this GOROOT is left behind.
But the PATH is unchanged.
This can be potentially problematic, if the binary invokes go install mod@ver, or runs go build outside the current module.
In my specific case, /usr/local/go/bin/go is go1.21.9, but GOROOT is go1.22.0 root.
The go install or go generate program will fail to run due to this mismatched binary/GOROOT pair.
@rsc said 'go test' handles this problem by adjusting PATH, too.
The 'go test' docs explain:
The go command places $GOROOT/bin at the beginning of $PATH in the test's environment, so that tests that execute 'go' commands use the same 'go' as the parent 'go test' command.
We should do the same for go run, go generate, ...
What did you expect to see?
Subprocess can pick matching go binary and GOROOT.
Similar Issues
- cmd/go: `go test` and `go generate` add the wrong `go` to `$PATH` when the `go` command is run from the cross-compiled `bin` subdirectory #64963
- cmd/go: can only run "go env" in certain places #35409
- go/build: Passes bad $GOROOT to `go list` subprocess #35056
- go/build: tests use a non-hermetic "go" binary #39198
- run.bash: GOPATH should be set to a non-existent, non-empty string #19237
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
From a brief investigation looks like 'go generate' already adjusts the path accordingly since CL 404134. I'll push a fix for go run.
Change https://go.dev/cl/593255 mentions this issue: cmd/go: place GOROOT/bin at the beginning of PATH in 'go run'
This seems reasonable to me. Thanks for the CL!