From f3c46355d7a4c794228e4d8cd6bbaabbef23a345 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 5 Nov 2017 16:22:02 -0500 Subject: [PATCH] cmd/go: drop runtime, runtime/internal/sys, runtime/internal/atomic, unsafe as deps of everything This was a hack to make a new make.bash avoid reusing installed packages. The new content-based staleness is precise enough not to need this hack; now it's just causing unnecessary rebuilds: if a package doesn't import "runtime", for example, it doesn't need to be recompiled when runtime changes. (It does need to be relinked, and we still arrange that.) Change-Id: I4ddf6e16d754cf21b16e9db1ed52bddbf82e96c6 Reviewed-on: https://go-review.googlesource.com/76015 Run-TryBot: Russ Cox Reviewed-by: David Crawshaw --- src/cmd/go/go_test.go | 29 +++++++++++---------------- src/cmd/go/internal/load/pkg.go | 25 +++-------------------- src/cmd/go/internal/work/action.go | 32 ++++++++++++++++++------------ 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 1c06ad0afb..6c87ce83f8 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -3295,12 +3295,12 @@ func TestGoInstallPkgdir(t *testing.T) { defer tg.cleanup() tg.makeTempdir() pkg := tg.path(".") - tg.run("install", "-pkgdir", pkg, "errors") - tg.mustExist(filepath.Join(pkg, "errors.a")) - tg.mustNotExist(filepath.Join(pkg, "runtime.a")) - tg.run("install", "-i", "-pkgdir", pkg, "errors") - tg.mustExist(filepath.Join(pkg, "errors.a")) - tg.mustExist(filepath.Join(pkg, "runtime.a")) + tg.run("install", "-pkgdir", pkg, "sync") + tg.mustExist(filepath.Join(pkg, "sync.a")) + tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a")) + tg.run("install", "-i", "-pkgdir", pkg, "sync") + tg.mustExist(filepath.Join(pkg, "sync.a")) + tg.mustExist(filepath.Join(pkg, "sync/atomic.a")) } func TestGoTestRaceInstallCgo(t *testing.T) { @@ -3611,15 +3611,6 @@ func TestGoBuildARM(t *testing.T) { tg.grepStderrNot("unable to find math.a", "did not build math.a correctly") } -func TestIssue13655(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - for _, pkg := range []string{"runtime", "runtime/internal/atomic"} { - tg.run("list", "-f", "{{.Deps}}", pkg) - tg.grepStdout("runtime/internal/sys", "did not find required dependency of "+pkg+" on runtime/internal/sys") - } -} - // For issue 14337. func TestParallelTest(t *testing.T) { tg := testgo(t) @@ -4726,12 +4717,16 @@ func TestBuildCache(t *testing.T) { tg.makeTempdir() tg.setenv("GOCACHE", tg.tempdir) - // complex/x is a trivial non-main package. + // complex/w is a trivial non-main package. + // It imports nothing, so there should be no Deps. + tg.run("list", "-f={{join .Deps \" \"}}", "complex/w") + tg.grepStdoutNot(".+", "complex/w depends on unexpected packages") + tg.run("build", "-x", "complex/w") tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler") tg.run("build", "-x", "complex/w") - tg.grepStderrNot(`[\\/]compile|gccgo`, "did not run compiler") + tg.grepStderrNot(`[\\/]compile|gccgo`, "ran compiler incorrectly") // complex is a non-trivial main package. // the link step should not be cached. diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index a2c3d8e893..dfc5fa51f4 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -946,26 +946,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { } } - // 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. // To avoid problems on case-insensitive files, we reject any package // where two different input files have equal names under a case-insensitive @@ -1117,9 +1097,10 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { } } -// LinkerDeps returns the list of linker-induced dependencies for p. +// LinkerDeps returns the list of linker-induced dependencies for main package p. func LinkerDeps(p *Package) []string { - var deps []string + // Everything links runtime. + deps := []string{"runtime"} // External linking mode forces an import of runtime/cgo. if cfg.ExternalLinkingForced() { diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go index 93f41e749d..ea4afab354 100644 --- a/src/cmd/go/internal/work/action.go +++ b/src/cmd/go/internal/work/action.go @@ -627,10 +627,18 @@ func (b *Builder) linkSharedAction(mode, depMode BuildMode, shlib string, a1 *Ac // TODO(rsc): Find out and explain here why gccgo is excluded. // If the answer is that gccgo is different in implicit linker deps, maybe // load.LinkerDeps should be used and updated. + // Link packages into a shared library. + a := &Action{ + Mode: "go build -buildmode=shared", + Objdir: b.NewObjdir(), + Func: (*Builder).linkShared, + Deps: []*Action{a1}, + } + a.Target = filepath.Join(a.Objdir, shlib) if cfg.BuildToolchainName != "gccgo" { - add := func(pkg string) { + add := func(a1 *Action, pkg string, force bool) { for _, a2 := range a1.Deps { - if a2.Package.ImportPath == pkg { + if a2.Package != nil && a2.Package.ImportPath == pkg { return } } @@ -644,23 +652,21 @@ func (b *Builder) linkSharedAction(mode, depMode BuildMode, shlib string, a1 *Ac // then that shared library also contains runtime, // so that anything we do will depend on that library, // so we don't need to include pkg in our shared library. - if p.Shlib == "" || filepath.Base(p.Shlib) == pkg { + if force || p.Shlib == "" || filepath.Base(p.Shlib) == pkg { a1.Deps = append(a1.Deps, b.CompileAction(depMode, depMode, p)) } } - add("runtime/cgo") + add(a1, "runtime/cgo", false) if cfg.Goarch == "arm" { - add("math") + add(a1, "math", false) + } + + // The linker step still needs all the usual linker deps. + // (For example, the linker always opens runtime.a.) + for _, dep := range load.LinkerDeps(nil) { + add(a, dep, true) } } - // Link packages into a shared library. - a := &Action{ - Mode: "go build -buildmode=shared", - Objdir: b.NewObjdir(), - Func: (*Builder).linkShared, - Deps: []*Action{a1}, - } - a.Target = filepath.Join(a.Objdir, shlib) b.addTransitiveLinkDeps(a, a1, shlib) return a })