-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Prior to Go 1.21, setting the GOROOT_FINAL variable during the make scripts changed the GOROOT value embedded in the tools installed in $GOROOT/bin and $GOROOT/pkg/tool. That allowed those tools (primarily cmd/go) to locate GOROOT even if it (or just its binaries) was symlinked or copied to a different install location.
In Go 1.9 (#18678), to reduce confusion and boilerplate from explicit GOROOT settings, cmd/go was changed to use os.Executable to locate its own binary and then derive GOROOT from the fact that cmd/go is normally installed in $GOROOT/bin. cmd/go then passes that path to other tools explicitly as needed. As long as the go command invoked by the user is actually resolved in $GOROOT/bin (possibly via a symlink), it will infer the correct GOROOT regardless of what value may happen to be baked in.
As of Go 1.21, in order to provide reproducible builds of the Go toolchain (#57120), cmd/dist started building releases with the -trimpath flag set, which incidentally caused GOROOT_FINAL to have no effect (#61921). (Development versions of toolchains are still built without -trimpath by default, so GOROOT_FINAL may affect those builds somewhat.)
So GOROOT_FINAL is only really helpful if all of the following occur:
- The toolchain is being built only for a non-release version,
GOROOTis moved after themakescript is run,- the
cmd/gobinary is copied or hard-linked (not symlinked!) to some location outside ofGOROOT/bin, and - the copied
cmd/gobinary is invoked without settingGOROOTexplicitly.
I believe that the intersection of those conditions is “basically never”:
- Third-party distributions of the Go toolchain aren't likely to build non-release versions.
- Go contributors aren't likely to move
GOROOT. - Distributions that resolve
cmd/gofrom some other location (like/usr/bin/go) are likely to use symlinks or wrapper scripts instead of hard-links or copies.- Copying binaries results in a significantly larger install footprint.
- Using hard-links is more likely to confuse users, and less likely to be supported by packaging systems.
- Exceptions we are aware of (from cmd/dist: tools built with
GOROOT_FINALcannot locate it when copied to another location #61921) are Void Linux and Guix, which were both using copies, but it appears that they are likely to switch to symlinks instead:
- Third-party build tools like Bazel are likely to set
GOROOTexplicitly.
On the other hand, GOROOT_FINAL has long been a source of bugs and complexity in the Go project (see https://github.com/golang/go/issues?q=is%3Aissue+GOROOT_FINAL+in%3Atitle). In particular, tests of the toolchain itself may need to take GOROOT_FINAL into account when they inspect or run artifacts built during the test.
I propose that we:
- Drop support for custom
GOROOT_FINALsettings incmd/dist,cmd/go, and themakescripts. - Either replace the use of
GOROOT_FINALincmd/linkwith an explict flag (--trimgoroot?), or changecmd/goto always setGOROOT_FINALto be equal to eitherGOROOT(if-trimpathis off) or the literal string"$GOROOT"(if-trimpathis on). - Remove public-facing documentation that refers to
GOROOT_FINAL.- (Note that the documentation for
cmd/linkalready does not mention its use ofGOROOT_FINAL.)
- (Note that the documentation for