// mkzversion writes zversion.go:
//
// package sys
-// var DefaultGoroot = <goroot>
//
// const TheVersion = <version>
// const Goexperiment = <goexperiment>
fmt.Fprintln(&buf)
fmt.Fprintf(&buf, "package sys\n")
fmt.Fprintln(&buf)
- fmt.Fprintf(&buf, "var DefaultGoroot = `%s`\n", goroot_final)
- fmt.Fprintln(&buf)
fmt.Fprintf(&buf, "const TheVersion = `%s`\n", findgoversion())
fmt.Fprintf(&buf, "const Goexperiment = `%s`\n", os.Getenv("GOEXPERIMENT"))
fmt.Fprintf(&buf, "const StackGuardMultiplier = %d\n", stackGuardMultiplier())
fmt.Fprintln(&buf)
fmt.Fprintf(&buf, "import \"runtime\"\n")
fmt.Fprintln(&buf)
- fmt.Fprintf(&buf, "const defaultGOROOT = `%s`\n", goroot_final)
fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
return
}
- // we must unset GOROOT_FINAL before tests, because runtime/debug requires
+ // We must unset GOROOT_FINAL before tests, because runtime/debug requires
// correct access to source code, so if we have GOROOT_FINAL in effect,
// at least runtime/debug test will fail.
+ // If GOROOT_FINAL was set before, then now all the commands will appear stale.
+ // Nothing we can do about that other than not checking them below.
+ // (We call checkNotStale but only with "std" not "cmd".)
+ os.Setenv("GOROOT_FINAL_OLD", os.Getenv("GOROOT_FINAL")) // for cmd/link test
os.Unsetenv("GOROOT_FINAL")
for _, name := range t.runNames {
// running in parallel with earlier tests, or if it has some other reason
// for needing the earlier tests to be done.
func (t *tester) runPending(nextTest *distTest) {
- checkNotStale("go", "std", "cmd")
+ checkNotStale("go", "std")
worklist := t.worklist
t.worklist = nil
for _, w := range worklist {
log.Printf("Failed: %v", w.err)
t.failed = true
}
- checkNotStale("go", "std", "cmd")
+ checkNotStale("go", "std")
}
if t.failed && !t.keepGoing {
log.Fatal("FAILED")
fmt.Printf("SKIP\n")
return
}
+ os.Unsetenv("GOROOT_FINAL")
if canRun {
args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix}
newRoot := tg.path("new")
t.Run("RelocatedExe", func(t *testing.T) {
- t.Skip("TODO: skipping known broken test; see golang.org/issue/20284")
-
- // Should fall back to default location in binary.
- // No way to dig out other than look at source code.
- data, err := ioutil.ReadFile("../../runtime/internal/sys/zversion.go")
- if err != nil {
- t.Fatal(err)
- }
- m := regexp.MustCompile("var DefaultGoroot = `([^`]+)`").FindStringSubmatch(string(data))
- if m == nil {
- t.Fatal("cannot find DefaultGoroot in ../../runtime/internal/sys/zversion.go")
- }
- check(t, newGoTool, m[1])
+ // Should fall back to default location in binary,
+ // which is the GOROOT we used when building testgo.exe.
+ check(t, newGoTool, testGOROOT)
})
// If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT,
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.
+ // new tree when they call runtime.GOROOT.
t.Run("RuntimeGoroot", func(t *testing.T) {
// Build a working GOROOT the easy way, with symlinks.
testenv.MustHaveSymlink(t)
}
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)
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 {
}
fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc
- /*
- // TODO(rsc): Enable this code.
- // golang.org/issue/22475.
- goroot := cfg.BuildContext.GOROOT
- if final := os.Getenv("GOROOT_FINAL"); final != "" {
- goroot = final
- }
- fmt.Fprintf(h, "GOROOT=%s\n", goroot)
- */
+ // The linker writes source file paths that say GOROOT_FINAL.
+ fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL)
// TODO(rsc): Convince linker team not to add more magic environment variables,
// or perhaps restrict the environment variables passed to subprocesses.
ldflags = append(ldflags, "-pluginpath", pluginPath(root))
}
- // TODO(rsc): This is probably wrong - see golang.org/issue/22155.
- if cfg.GOROOT != runtime.GOROOT() {
- ldflags = append(ldflags, "-X=runtime/internal/sys.DefaultGoroot="+cfg.GOROOT)
- }
-
// Store BuildID inside toolchain binaries as a unique identifier of the
// tool being run, for use by content-based staleness determination.
if root.Package.Goroot && strings.HasPrefix(root.Package.ImportPath, "cmd/") {
}
var (
+ defaultGOROOT string // set by linker
+
GOROOT = envOr("GOROOT", defaultGOROOT)
GOARCH = envOr("GOARCH", defaultGOARCH)
GOOS = envOr("GOOS", defaultGOOS)
t.Fatalf("go list: %v\n%s", err, out)
}
if string(out) != "false\n" {
+ if os.Getenv("GOROOT_FINAL_OLD") != "" {
+ t.Skip("cmd/link is stale, but $GOROOT_FINAL_OLD is set")
+ }
t.Fatalf("cmd/link is stale - run go install cmd/link")
}
}
}
+ final := gorootFinal()
+ addstrdata1(ctxt, "runtime/internal/sys.DefaultGoroot="+final)
+ addstrdata1(ctxt, "cmd/internal/objabi.defaultGOROOT="+final)
+
// TODO(matloob): define these above and then check flag values here
if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table")
}
}
+func gorootFinal() string {
+ root := objabi.GOROOT
+ if final := os.Getenv("GOROOT_FINAL"); final != "" {
+ root = final
+ }
+ return root
+}
+
func expandGoroot(s string) string {
const n = len("$GOROOT")
if len(s) >= n+1 && s[:n] == "$GOROOT" && (s[n] == '/' || s[n] == '\\') {
- root := objabi.GOROOT
- if final := os.Getenv("GOROOT_FINAL"); final != "" {
- root = final
- }
- return filepath.ToSlash(filepath.Join(root, s[n:]))
+ return filepath.ToSlash(filepath.Join(gorootFinal(), s[n:]))
}
return s
}
const PtrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
const RegSize = 4 << (^Uintreg(0) >> 63) // unsafe.Sizeof(uintreg(0)) but an ideal const
const SpAlign = 1*(1-GoarchArm64) + 16*GoarchArm64 // SP alignment: 1 normally, 16 for ARM64
+
+var DefaultGoroot string // set at link time