aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/cfg/cfg.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2018-01-08 11:59:29 -0500
committerRuss Cox <rsc@golang.org>2018-01-09 21:46:18 +0000
commit8396015e80afa4ddd4ea3c3f00373d22c3b45d6c (patch)
tree692f255ede9aa9d8b4d7ed4522ebe2dd86b2020a /src/cmd/go/internal/cfg/cfg.go
parent28639df158a19b2bbceda43fb67ca7cb685d8e34 (diff)
downloadgo-8396015e80afa4ddd4ea3c3f00373d22c3b45d6c.tar.gz
go-8396015e80afa4ddd4ea3c3f00373d22c3b45d6c.zip
cmd/link: set runtime.GOROOT default during link
Suppose you build the Go toolchain in directory A, move the whole thing to directory B, and then use it from B to build a new program hello.exe, and then run hello.exe, and hello.exe crashes with a stack trace into the standard library. Long ago, you'd have seen hello.exe print file names in the A directory tree, even though the files had moved to the B directory tree. About two years ago we changed the compiler to write down these files with the name "$GOROOT" (that literal string) instead of A, so that the final link from B could replace "$GOROOT" with B, so that hello.exe's crash would show the correct source file paths in the stack trace. (golang.org/cl/18200) Now suppose that you do the same thing but hello.exe doesn't crash: it prints fmt.Println(runtime.GOROOT()). And you run hello.exe after clearing $GOROOT from the environment. Long ago, you'd have seen hello.exe print A instead of B. Before this CL, you'd still see hello.exe print A instead of B. This case is the one instance where a moved toolchain still divulges its origin. Not anymore. After this CL, hello.exe will print B, because the linker sets runtime/internal/sys.DefaultGoroot with the effective GOROOT from link time. This makes the default result of runtime.GOROOT once again match the file names recorded in the binary, after two years of divergence. With that cleared up, we can reintroduce GOROOT into the link action ID and also reenable TestExecutableGOROOT/RelocatedExe. When $GOROOT_FINAL is set during link, it is used in preference to $GOROOT, as always, but it was easier to explain the behavior above without introducing that complication. Fixes #22155. Fixes #20284. Fixes #22475. Change-Id: Ifdaeb77fd4678fdb337cf59ee25b2cd873ec1016 Reviewed-on: https://go-review.googlesource.com/86835 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/cmd/go/internal/cfg/cfg.go')
-rw-r--r--src/cmd/go/internal/cfg/cfg.go19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index dfab20a8de..1de4f0dc79 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -76,11 +76,12 @@ func init() {
}
var (
- GOROOT = findGOROOT()
- GOBIN = os.Getenv("GOBIN")
- GOROOTbin = filepath.Join(GOROOT, "bin")
- GOROOTpkg = filepath.Join(GOROOT, "pkg")
- GOROOTsrc = filepath.Join(GOROOT, "src")
+ GOROOT = findGOROOT()
+ GOBIN = os.Getenv("GOBIN")
+ GOROOTbin = filepath.Join(GOROOT, "bin")
+ GOROOTpkg = filepath.Join(GOROOT, "pkg")
+ GOROOTsrc = filepath.Join(GOROOT, "src")
+ GOROOT_FINAL = findGOROOT_FINAL()
// Used in envcmd.MkEnv and build ID computations.
GOARM = fmt.Sprint(objabi.GOARM)
@@ -129,6 +130,14 @@ func findGOROOT() string {
return def
}
+func findGOROOT_FINAL() string {
+ def := GOROOT
+ if env := os.Getenv("GOROOT_FINAL"); env != "" {
+ def = filepath.Clean(env)
+ }
+ return def
+}
+
// isSameDir reports whether dir1 and dir2 are the same directory.
func isSameDir(dir1, dir2 string) bool {
if dir1 == dir2 {