From d68615f64b0d7c1e886f4b8c1267ecc1c4da76ad Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Thu, 10 Mar 2022 23:38:25 -0500 Subject: [PATCH] cmd/go/internal/test: ensure that build.ToolDir is accurate in tests This fixes a build failure due to inability to locate the "vet" tool when the test binary is built with -trimpath. Updates #51461 Change-Id: I81838cc8842e4ff7900cab81af60501ebba86ff1 Reviewed-on: https://go-review.googlesource.com/c/go/+/391808 Trust: Bryan Mills Run-TryBot: Bryan Mills Reviewed-by: Russ Cox TryBot-Result: Gopher Robot --- src/cmd/go/internal/cfg/cfg.go | 50 +++++++++++++++-------- src/cmd/go/internal/test/flagdefs_test.go | 6 +++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index 77c0e229e5e4e..61fd3ce4ef1af 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -87,16 +87,6 @@ func defaultContext() build.Context { ctxt.JoinPath = filepath.Join // back door to say "do not use go command" - ctxt.GOROOT = findGOROOT() - if runtime.Compiler != "gccgo" { - // Note that we must use runtime.GOOS and runtime.GOARCH here, - // as the tool directory does not move based on environment - // variables. This matches the initialization of ToolDir in - // go/build, except for using ctxt.GOROOT rather than - // runtime.GOROOT. - build.ToolDir = filepath.Join(ctxt.GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) - } - // Override defaults computed in go/build with defaults // from go environment configuration file, if known. ctxt.GOPATH = envOr("GOPATH", gopath(ctxt)) @@ -146,10 +136,36 @@ func defaultContext() build.Context { } func init() { + SetGOROOT(findGOROOT()) BuildToolchainCompiler = func() string { return "missing-compiler" } BuildToolchainLinker = func() string { return "missing-linker" } } +func SetGOROOT(goroot string) { + BuildContext.GOROOT = goroot + + GOROOT = goroot + if goroot == "" { + GOROOTbin = "" + GOROOTpkg = "" + GOROOTsrc = "" + } else { + GOROOTbin = filepath.Join(goroot, "bin") + GOROOTpkg = filepath.Join(goroot, "pkg") + GOROOTsrc = filepath.Join(goroot, "src") + } + GOROOT_FINAL = findGOROOT_FINAL(goroot) + + if runtime.Compiler != "gccgo" && goroot != "" { + // Note that we must use runtime.GOOS and runtime.GOARCH here, + // as the tool directory does not move based on environment + // variables. This matches the initialization of ToolDir in + // go/build, except for using BuildContext.GOROOT rather than + // runtime.GOROOT. + build.ToolDir = filepath.Join(goroot, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) + } +} + // Experiment configuration. var ( // RawGOEXPERIMENT is the GOEXPERIMENT value set by the user. @@ -279,12 +295,12 @@ func CanGetenv(key string) bool { } var ( - GOROOT = BuildContext.GOROOT + GOROOT string + GOROOTbin string + GOROOTpkg string + GOROOTsrc string + GOROOT_FINAL string GOBIN = Getenv("GOBIN") - GOROOTbin = filepath.Join(GOROOT, "bin") - GOROOTpkg = filepath.Join(GOROOT, "pkg") - GOROOTsrc = filepath.Join(GOROOT, "src") - GOROOT_FINAL = findGOROOT_FINAL() GOMODCACHE = envOr("GOMODCACHE", gopathDir("pkg/mod")) // Used in envcmd.MkEnv and build ID computations. @@ -386,10 +402,10 @@ func findGOROOT() string { return def } -func findGOROOT_FINAL() string { +func findGOROOT_FINAL(goroot string) string { // $GOROOT_FINAL is only for use during make.bash // so it is not settable using go/env, so we use os.Getenv here. - def := GOROOT + def := goroot if env := os.Getenv("GOROOT_FINAL"); env != "" { def = filepath.Clean(env) } diff --git a/src/cmd/go/internal/test/flagdefs_test.go b/src/cmd/go/internal/test/flagdefs_test.go index 40dc558e9080c..f74f3c18f7785 100644 --- a/src/cmd/go/internal/test/flagdefs_test.go +++ b/src/cmd/go/internal/test/flagdefs_test.go @@ -5,13 +5,19 @@ package test import ( + "cmd/go/internal/cfg" "cmd/go/internal/test/internal/genflags" "flag" + "internal/testenv" "reflect" "strings" "testing" ) +func TestMain(m *testing.M) { + cfg.SetGOROOT(testenv.GOROOT(nil)) +} + func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) { flag.VisitAll(func(f *flag.Flag) { if !strings.HasPrefix(f.Name, "test.") {