]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: clean up implicit compiler and linker dependencies
authorRuss Cox <rsc@golang.org>
Thu, 5 Oct 2017 13:22:04 +0000 (09:22 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 5 Oct 2017 18:17:57 +0000 (18:17 +0000)
Telling the truth about these will be important for
content-based staleness checks.

Change-Id: Iaed6ca6c945eb805d815156753a3e5dc48c6f0b9
Reviewed-on: https://go-review.googlesource.com/68336
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/test/test.go
src/cmd/go/internal/work/build.go

index dace766aed894e66f2cd3bb2e0f146864ca6f514..ae73c92e946be649f6d26a1a26844e5cbefc3fa1 100644 (file)
@@ -829,15 +829,6 @@ var GoTools = map[string]targetDir{
        "code.google.com/p/go.tools/cmd/vet":   StalePath,
 }
 
-var raceExclude = map[string]bool{
-       "runtime/race": true,
-       "runtime/msan": true,
-       "runtime/cgo":  true,
-       "cmd/cgo":      true,
-       "syscall":      true,
-       "errors":       true,
-}
-
 var cgoExclude = map[string]bool{
        "runtime/cgo": true,
 }
@@ -934,47 +925,52 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
                }
        }
 
+       // Build augmented import list to add implicit dependencies.
+       // Be careful not to add imports twice, just to avoid confusion.
        importPaths := p.Imports
-       // Packages that use cgo import runtime/cgo implicitly.
-       // Packages that use cgo also import syscall implicitly,
-       // to wrap errno.
-       // Exclude certain packages to avoid circular dependencies.
+       addImport := func(path string) {
+               for _, p := range importPaths {
+                       if path == p {
+                               return
+                       }
+               }
+               importPaths = append(importPaths, path)
+       }
+
+       // Cgo translation adds imports of "runtime/cgo" and "syscall",
+       // except for certain packages, to avoid circular dependencies.
        if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) {
-               importPaths = append(importPaths, "runtime/cgo")
+               addImport("runtime/cgo")
        }
        if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
-               importPaths = append(importPaths, "syscall")
-       }
-
-       if p.Name == "main" && cfg.ExternalLinkingForced(p.Goroot) {
-               importPaths = append(importPaths, "runtime/cgo")
+               addImport("syscall")
        }
 
-       // Everything depends on runtime, except runtime, its internal
-       // subpackages, and unsafe.
-       if !p.Standard || (p.ImportPath != "runtime" && !strings.HasPrefix(p.ImportPath, "runtime/internal/") && p.ImportPath != "unsafe") {
-               importPaths = append(importPaths, "runtime")
-               // When race detection enabled everything depends on runtime/race.
-               // Exclude certain packages to avoid circular dependencies.
-               if cfg.BuildRace && (!p.Standard || !raceExclude[p.ImportPath]) {
-                       importPaths = append(importPaths, "runtime/race")
-               }
-               // MSan uses runtime/msan.
-               if cfg.BuildMSan && (!p.Standard || !raceExclude[p.ImportPath]) {
-                       importPaths = append(importPaths, "runtime/msan")
-               }
-               // On ARM with GOARM=5, everything depends on math for the link.
-               if p.Name == "main" && cfg.Goarch == "arm" {
-                       importPaths = append(importPaths, "math")
+       // The linker loads implicit dependencies.
+       if p.Name == "main" && !p.Internal.ForceLibrary {
+               for _, dep := range LinkerDeps(p) {
+                       addImport(dep)
                }
        }
 
-       // Runtime and its internal packages depend on runtime/internal/sys,
-       // so that they pick up the generated zversion.go file.
-       // This can be an issue particularly for runtime/internal/atomic;
-       // see issue 13655.
-       if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal/")) && p.ImportPath != "runtime/internal/sys" {
-               importPaths = append(importPaths, "runtime/internal/sys")
+       // If runtime/internal/sys/zversion.go changes, it very likely means the
+       // compiler has been recompiled with that new version, so all existing
+       // archives are now stale. Make everything appear to import runtime/internal/sys,
+       // so that in this situation everything will appear stale and get recompiled.
+       // Due to the rules for visibility of internal packages, things outside runtime
+       // must import runtime, and runtime imports runtime/internal/sys.
+       // Content-based staleness that includes a check of the compiler version
+       // will make this hack unnecessary; once that lands, this whole comment
+       // and switch statement should be removed.
+       switch {
+       case p.Standard && p.ImportPath == "runtime/internal/sys":
+               // nothing
+       case p.Standard && p.ImportPath == "unsafe":
+               // nothing - not a real package, and used by runtime
+       case p.Standard && strings.HasPrefix(p.ImportPath, "runtime"):
+               addImport("runtime/internal/sys")
+       default:
+               addImport("runtime")
        }
 
        // Check for case-insensitive collision of input files.
@@ -1123,6 +1119,30 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
        }
 }
 
+// LinkerDeps returns the list of linker-induced dependencies for p.
+func LinkerDeps(p *Package) []string {
+       var deps []string
+
+       // External linking mode forces an import of runtime/cgo.
+       if cfg.ExternalLinkingForced(p.Goroot) {
+               deps = append(deps, "runtime/cgo")
+       }
+       // On ARM with GOARM=5, it forces an import of math, for soft floating point.
+       if cfg.Goarch == "arm" {
+               deps = append(deps, "math")
+       }
+       // Using the race detector forces an import of runtime/race.
+       if cfg.BuildRace {
+               deps = append(deps, "runtime/race")
+       }
+       // Using memory sanitizer forces an import of runtime/msan.
+       if cfg.BuildMSan {
+               deps = append(deps, "runtime/msan")
+       }
+
+       return deps
+}
+
 // mkAbs rewrites list, which must be paths relative to p.Dir,
 // into a sorted list of absolute paths. It edits list in place but for
 // convenience also returns list back to its caller.
index c3810feb0d1b19586511ae66524e51eee5a1774e..96dced830ccaf73cd6e095543b7a0f4853c61335 100644 (file)
@@ -816,10 +816,11 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
        }
 
        // The generated main also imports testing, regexp, and os.
+       // Also the linker introduces implicit dependencies reported by LinkerDeps.
        stk.Push("testmain")
-       deps := testMainDeps
-       if cfg.ExternalLinkingForced(pmain.Goroot) {
-               deps = str.StringList(deps, "runtime/cgo")
+       deps := testMainDeps // cap==len, so safe for append
+       for _, d := range load.LinkerDeps(p) {
+               deps = append(deps, d)
        }
        for _, dep := range deps {
                if dep == ptest.ImportPath {
index 2cc1682b150fbb90fc239f22bf715cacd06a02ad..c62735d0aa4c91a1258d12f8245ee62971624952 100644 (file)
@@ -1406,10 +1406,6 @@ func (b *Builder) build(a *Action) (err error) {
                        // This happens for gccgo-internal packages like runtime.
                        continue
                }
-               // TODO(rsc): runtime/internal/sys appears twice sometimes,
-               // because of the blind append in ../load/pkg.go that
-               // claims to fix issue 13655. That's probably not the right fix.
-               // Look into that.
                fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, p1.Internal.Pkgfile)
        }