1
0
mirror of https://github.com/golang/go synced 2024-11-20 06:44:40 -07:00

cmd/go: put computed GOROOT in built binaries

As of CL 42533, cmd/go will recompute its GOROOT based on the
location of its own executable. This CL plumbs that computed GOROOT
into every binary it builds using the linker -X flag. This
means binaries built with a moved cmd/go will report the GOROOT
they were built in from runtime.GOROOT().

Fixes #21313

Change-Id: I6c2c559f40f2a0c867ab60cf47c6dbc73ae5e28a
Reviewed-on: https://go-review.googlesource.com/61310
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
David Crawshaw 2017-09-03 12:33:56 -04:00
parent ffb4708d1b
commit 06f4d93699
4 changed files with 55 additions and 3 deletions

View File

@ -17,7 +17,8 @@ import (
// mkzversion writes zversion.go:
//
// package sys
// const DefaultGoroot = <goroot>
// var DefaultGoroot = <goroot>
//
// const TheVersion = <version>
// const Goexperiment = <goexperiment>
// const StackGuardMultiplier = <multiplier value>
@ -28,7 +29,7 @@ func mkzversion(dir, file string) {
"\n"+
"package sys\n"+
"\n"+
"const DefaultGoroot = `%s`\n"+
"var DefaultGoroot = `%s`\n\n"+
"const TheVersion = `%s`\n"+
"const Goexperiment = `%s`\n"+
"const StackGuardMultiplier = %d\n\n", goroot_final, findgoversion(), os.Getenv("GOEXPERIMENT"), stackGuardMultiplier())

View File

@ -4163,7 +4163,7 @@ func TestExecutableGOROOT(t *testing.T) {
if err != nil {
t.Fatal(err)
}
m := regexp.MustCompile("const DefaultGoroot = `([^`]+)`").FindStringSubmatch(string(data))
m := regexp.MustCompile("var DefaultGoroot = `([^`]+)`").FindStringSubmatch(string(data))
if m == nil {
t.Fatal("cannot find DefaultGoroot in ../../runtime/internal/sys/zversion.go")
}
@ -4188,6 +4188,43 @@ func TestExecutableGOROOT(t *testing.T) {
}
check(t, symGoTool, newRoot)
})
tg.must(os.RemoveAll(tg.path("new/pkg")))
// Binaries built in the new tree should report the
// new tree when they call runtime.GOROOT().
// This is implemented by having the go tool pass a -X option
// to the linker setting runtime/internal/sys.DefaultGoroot.
t.Run("RuntimeGoroot", func(t *testing.T) {
// Build a working GOROOT the easy way, with symlinks.
testenv.MustHaveSymlink(t)
if err := os.Symlink(filepath.Join(testGOROOT, "src"), tg.path("new/src")); err != nil {
t.Fatal(err)
}
if err := os.Symlink(filepath.Join(testGOROOT, "pkg"), tg.path("new/pkg")); err != nil {
t.Fatal(err)
}
cmd := exec.Command(newGoTool, "run", "testdata/print_goroot.go")
cmd.Env = env
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("%s run testdata/print_goroot.go: %v, %s", newGoTool, err, out)
}
goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
if err != nil {
t.Fatal(err)
}
want, err := filepath.EvalSymlinks(tg.path("new"))
if err != nil {
t.Fatal(err)
}
if !strings.EqualFold(goroot, want) {
t.Errorf("go run testdata/print_goroot.go:\nhave %s\nwant %s", goroot, want)
} else {
t.Logf("go run testdata/print_goroot.go: %s", goroot)
}
})
}
func TestNeedVersion(t *testing.T) {

View File

@ -2536,6 +2536,9 @@ func (gcToolchain) ld(b *Builder, root *Action, out string, allactions []*Action
if cfg.BuildBuildmode == "plugin" {
ldflags = append(ldflags, "-pluginpath", load.PluginPath(root.Package))
}
if cfg.GOROOT != runtime.GOROOT() {
ldflags = append(ldflags, "-X=runtime/internal/sys.DefaultGoroot="+cfg.GOROOT)
}
// If the user has not specified the -extld option, then specify the
// appropriate linker. In case of C++ code, use the compiler named

11
src/cmd/go/testdata/print_goroot.go vendored Normal file
View File

@ -0,0 +1,11 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "runtime"
func main() {
println(runtime.GOROOT())
}