]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: break a few dependencies
authorRuss Cox <rsc@golang.org>
Fri, 13 Jan 2017 16:49:16 +0000 (11:49 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 3 Feb 2017 20:30:27 +0000 (20:30 +0000)
This CL makes a few naming changes to break dependencies
between different parts of the go command, to make it easier
to split into different packages.

This is the first CL in a long sequence of changes to break up the
go command from one package into a plausible group of packages.

This sequence is concerned only with moving code, not changing
or cleaning up code. There will still be more cleanup after this sequence.

The entire sequence will be submitted together: it is not a goal
for the tree to build at every step.

For #18653.

Change-Id: I69a98b9ea48e61b1e1cda95273d29860b525415f
Reviewed-on: https://go-review.googlesource.com/36129
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/go/build.go
src/cmd/go/main.go
src/cmd/go/pkg.go
src/cmd/go/test.go

index 98a650918a30d7d6ae80ff78551b4ad93fa32d33..d00090cf191c743812dc0d9daea7f65c79ea89ea 100644 (file)
@@ -143,6 +143,7 @@ func init() {
        cmdInstall.Run = runInstall
 
        cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
+       cmdBuild.Flag.StringVar(&buildO, "o", "", "output file")
 
        addBuildFlags(cmdBuild)
        addBuildFlags(cmdInstall)
@@ -155,21 +156,24 @@ var buildP = runtime.NumCPU() // -p flag
 var buildV bool               // -v flag
 var buildX bool               // -x flag
 var buildI bool               // -i flag
-var buildO = cmdBuild.Flag.String("o", "", "output file")
-var buildWork bool           // -work flag
-var buildAsmflags []string   // -asmflags flag
-var buildGcflags []string    // -gcflags flag
-var buildLdflags []string    // -ldflags flag
-var buildGccgoflags []string // -gccgoflags flag
-var buildRace bool           // -race flag
-var buildMSan bool           // -msan flag
-var buildToolExec []string   // -toolexec flag
-var buildBuildmode string    // -buildmode flag
-var buildLinkshared bool     // -linkshared flag
-var buildPkgdir string       // -pkgdir flag
+var buildO string             // -o flag
+var buildWork bool            // -work flag
+var buildAsmflags []string    // -asmflags flag
+var buildGcflags []string     // -gcflags flag
+var buildLdflags []string     // -ldflags flag
+var buildGccgoflags []string  // -gccgoflags flag
+var buildRace bool            // -race flag
+var buildMSan bool            // -msan flag
+var buildToolExec []string    // -toolexec flag
+var buildBuildmode string     // -buildmode flag
+var buildLinkshared bool      // -linkshared flag
+var buildPkgdir string        // -pkgdir flag
 
 var buildContext = build.Default
 var buildToolchain toolchain = noToolchain{}
+var buildToolchainName string
+var buildToolchainCompiler string
+var buildToolchainLinker string
 var ldBuildmode string
 
 // buildCompiler implements flag.Var.
@@ -186,6 +190,9 @@ func (c buildCompiler) Set(value string) error {
        default:
                return fmt.Errorf("unknown compiler %q", value)
        }
+       buildToolchainName = value
+       buildToolchainCompiler = buildToolchain.compiler()
+       buildToolchainLinker = buildToolchain.linker()
        buildContext.Compiler = value
        return nil
 }
@@ -196,10 +203,8 @@ func (c buildCompiler) String() string {
 
 func init() {
        switch build.Default.Compiler {
-       case "gc":
-               buildToolchain = gcToolchain{}
-       case "gccgo":
-               buildToolchain = gccgoToolchain{}
+       case "gc", "gccgo":
+               buildCompiler{}.Set(build.Default.Compiler)
        }
 }
 
@@ -321,7 +326,7 @@ func pkgsNotMain(pkgs []*Package) (res []*Package) {
 var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
 
 func buildModeInit() {
-       _, gccgo := buildToolchain.(gccgoToolchain)
+       gccgo := buildToolchainName == "gccgo"
        var codegenArg string
        platform := goos + "/" + goarch
        switch buildBuildmode {
@@ -402,7 +407,7 @@ func buildModeInit() {
                        }
                        codegenArg = "-dynlink"
                }
-               if *buildO != "" {
+               if buildO != "" {
                        fatalf("-buildmode=shared and -o not supported together")
                }
                ldBuildmode = "shared"
@@ -464,14 +469,14 @@ func runBuild(cmd *Command, args []string) {
 
        pkgs := packagesForBuild(args)
 
-       if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
-               _, *buildO = path.Split(pkgs[0].ImportPath)
-               *buildO += exeSuffix
+       if len(pkgs) == 1 && pkgs[0].Name == "main" && buildO == "" {
+               _, buildO = path.Split(pkgs[0].ImportPath)
+               buildO += exeSuffix
        }
 
        // Special case -o /dev/null by not writing at all.
-       if *buildO == os.DevNull {
-               *buildO = ""
+       if buildO == os.DevNull {
+               buildO = ""
        }
 
        // sanity check some often mis-used options
@@ -494,14 +499,14 @@ func runBuild(cmd *Command, args []string) {
                depMode = modeInstall
        }
 
-       if *buildO != "" {
+       if buildO != "" {
                if len(pkgs) > 1 {
                        fatalf("go build: cannot use -o with multiple packages")
                } else if len(pkgs) == 0 {
                        fatalf("no packages to build")
                }
                p := pkgs[0]
-               p.target = *buildO
+               p.target = buildO
                p.Stale = true // must build - not up to date
                p.StaleReason = "build -o flag in use"
                a := b.action(modeInstall, depMode, p)
@@ -874,8 +879,8 @@ func goFilesPackage(gofiles []string) *Package {
        if pkg.Name == "main" {
                _, elem := filepath.Split(gofiles[0])
                exe := elem[:len(elem)-len(".go")] + exeSuffix
-               if *buildO == "" {
-                       *buildO = exe
+               if buildO == "" {
+                       buildO = exe
                }
                if gobin != "" {
                        pkg.target = filepath.Join(gobin, exe)
@@ -896,7 +901,7 @@ func goFilesPackage(gofiles []string) *Package {
 // .go_export section.
 func readpkglist(shlibpath string) (pkgs []*Package) {
        var stk importStack
-       if _, gccgo := buildToolchain.(gccgoToolchain); gccgo {
+       if buildToolchainName == "gccgo" {
                f, _ := elf.Open(shlibpath)
                sect := f.Section(".go_export")
                data, _ := sect.Data()
@@ -1010,7 +1015,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha
                        return a
                }
                // gccgo standard library is "fake" too.
-               if _, ok := buildToolchain.(gccgoToolchain); ok {
+               if buildToolchainName == "gccgo" {
                        // the target name is needed for cgo.
                        a.target = p.target
                        return a
@@ -1114,7 +1119,7 @@ func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode build
                // external linking mode forces an import of runtime/cgo (and
                // math on arm). So if it was not passed on the command line and
                // it is not present in another shared library, add it here.
-               _, gccgo := buildToolchain.(gccgoToolchain)
+               gccgo := buildToolchainName == "gccgo"
                if !gccgo {
                        seencgo := false
                        for _, p := range pkgs {
@@ -1490,7 +1495,7 @@ func (b *builder) build(a *action) (err error) {
                if err != nil {
                        return err
                }
-               if _, ok := buildToolchain.(gccgoToolchain); ok {
+               if buildToolchainName == "gccgo" {
                        cgoObjects = append(cgoObjects, filepath.Join(a.objdir, "_cgo_flags"))
                }
                cgoObjects = append(cgoObjects, outObj...)
@@ -3324,7 +3329,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
                cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
        }
 
-       if _, ok := buildToolchain.(gccgoToolchain); ok {
+       if buildToolchainName == "gccgo" {
                switch goarch {
                case "386", "amd64":
                        cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
@@ -3396,8 +3401,8 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
                outObj = append(outObj, ofile)
        }
 
-       switch buildToolchain.(type) {
-       case gcToolchain:
+       switch buildToolchainName {
+       case "gc":
                importGo := obj + "_cgo_import.go"
                if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
                        return nil, nil, err
@@ -3410,7 +3415,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
                }
                outObj = []string{ofile}
 
-       case gccgoToolchain:
+       case "gccgo":
                defunC := obj + "_cgo_defun.c"
                defunObj := obj + "_cgo_defun.o"
                if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
@@ -3684,7 +3689,7 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b
                gccExt = "cxx"
        }
 
-       _, gccgo := buildToolchain.(gccgoToolchain)
+       gccgo := buildToolchainName == "gccgo"
 
        // swig
        args := []string{
index 07fc4e2a9050d836efba2df98be15d40218ed29f..dfd0e9aa1fbb563f92563c0f493ae55e59e66dca 100644 (file)
@@ -74,33 +74,37 @@ func (c *Command) Runnable() bool {
 
 // Commands lists the available commands and help topics.
 // The order here is the order in which they are printed by 'go help'.
-var commands = []*Command{
-       cmdBuild,
-       cmdClean,
-       cmdDoc,
-       cmdEnv,
-       cmdBug,
-       cmdFix,
-       cmdFmt,
-       cmdGenerate,
-       cmdGet,
-       cmdInstall,
-       cmdList,
-       cmdRun,
-       cmdTest,
-       cmdTool,
-       cmdVersion,
-       cmdVet,
-
-       helpC,
-       helpBuildmode,
-       helpFileType,
-       helpGopath,
-       helpEnvironment,
-       helpImportPath,
-       helpPackages,
-       helpTestflag,
-       helpTestfunc,
+var commands []*Command
+
+func init() {
+       commands = []*Command{
+               cmdBuild,
+               cmdClean,
+               cmdDoc,
+               cmdEnv,
+               cmdBug,
+               cmdFix,
+               cmdFmt,
+               cmdGenerate,
+               cmdGet,
+               cmdInstall,
+               cmdList,
+               cmdRun,
+               cmdTest,
+               cmdTool,
+               cmdVersion,
+               cmdVet,
+
+               helpC,
+               helpBuildmode,
+               helpFileType,
+               helpGopath,
+               helpEnvironment,
+               helpImportPath,
+               helpPackages,
+               helpTestflag,
+               helpTestfunc,
+       }
 }
 
 var exitStatus = 0
@@ -307,7 +311,13 @@ func printUsage(w io.Writer) {
        bw.Flush()
 }
 
-func usage() {
+var usage func()
+
+func init() {
+       usage = mainUsage
+}
+
+func mainUsage() {
        // special case "go test -h"
        if len(os.Args) > 1 && os.Args[1] == "test" {
                os.Stderr.WriteString(testUsage + "\n\n" +
index e40f9420c7e2217f9e126cf5f636c282c532d959..8fb6bddde1388ccc54370d0f03cc69d7a33e316a 100644 (file)
@@ -1124,7 +1124,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 
        if p.BinaryOnly {
                // For binary-only package, use build ID from supplied package binary.
-               buildID, err := readBuildID(p)
+               buildID, err := readBuildID(p.Name, p.Target)
                if err == nil {
                        p.buildID = buildID
                }
@@ -1495,7 +1495,7 @@ func isStale(p *Package) (bool, string) {
        // It also catches changes in toolchain, like when flipping between
        // two versions of Go compiling a single GOPATH.
        // See issue 8290 and issue 10702.
-       targetBuildID, err := readBuildID(p)
+       targetBuildID, err := readBuildID(p.Name, p.Target)
        if err == nil && targetBuildID != p.buildID {
                return true, "build ID mismatch"
        }
@@ -1559,10 +1559,10 @@ func isStale(p *Package) (bool, string) {
        // Excluding $GOROOT used to also fix issue 4106, but that's now
        // taken care of above (at least when the installed Go is a released version).
        if p.Root != goroot {
-               if olderThan(buildToolchain.compiler()) {
+               if olderThan(buildToolchainCompiler) {
                        return true, "newer compiler"
                }
-               if p.build.IsCommand() && olderThan(buildToolchain.linker()) {
+               if p.build.IsCommand() && olderThan(buildToolchainLinker) {
                        return true, "newer linker"
                }
        }
@@ -1865,20 +1865,20 @@ var (
 // readBuildID reads the build ID from an archive or binary.
 // It only supports the gc toolchain.
 // Other toolchain maintainers should adjust this function.
-func readBuildID(p *Package) (id string, err error) {
-       if buildToolchain != (gcToolchain{}) {
+func readBuildID(name, target string) (id string, err error) {
+       if buildToolchainName != "gc" {
                return "", errBuildIDToolchain
        }
 
        // For commands, read build ID directly from binary.
-       if p.Name == "main" {
-               return ReadBuildIDFromBinary(p.Target)
+       if name == "main" {
+               return ReadBuildIDFromBinary(target)
        }
 
        // Otherwise, we expect to have an archive (.a) file,
        // and we can read the build ID from the Go export data.
-       if !strings.HasSuffix(p.Target, ".a") {
-               return "", &os.PathError{Op: "parse", Path: p.Target, Err: errBuildIDUnknown}
+       if !strings.HasSuffix(target, ".a") {
+               return "", &os.PathError{Op: "parse", Path: target, Err: errBuildIDUnknown}
        }
 
        // Read just enough of the target to fetch the build ID.
@@ -1891,7 +1891,7 @@ func readBuildID(p *Package) (id string, err error) {
        //
        // The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none).
        // Reading the first 1024 bytes should be plenty.
-       f, err := os.Open(p.Target)
+       f, err := os.Open(target)
        if err != nil {
                return "", err
        }
@@ -1904,7 +1904,7 @@ func readBuildID(p *Package) (id string, err error) {
        }
 
        bad := func() (string, error) {
-               return "", &os.PathError{Op: "parse", Path: p.Target, Err: errBuildIDMalformed}
+               return "", &os.PathError{Op: "parse", Path: target, Err: errBuildIDMalformed}
        }
 
        // Archive header.
index 6482f0fd32301a83a0bb9174170705b204587ef7..1445e9f3958ed38223535c6efcfd58ebb4437b5c 100644 (file)
@@ -545,7 +545,7 @@ func runTest(cmd *Command, args []string) {
 
        // Prepare build + run + print actions for all packages being tested.
        for _, p := range pkgs {
-               buildTest, runTest, printTest, err := b.test(p)
+               buildTest, runTest, printTest, err := builderTest(&b, p)
                if err != nil {
                        str := err.Error()
                        if strings.HasPrefix(str, "\n") {
@@ -652,11 +652,11 @@ var windowsBadWords = []string{
        "update",
 }
 
-func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, err error) {
+func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *action, err error) {
        if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
                build := b.action(modeBuild, modeBuild, p)
                run := &action{p: p, deps: []*action{build}}
-               print := &action{f: (*builder).notest, p: p, deps: []*action{run}}
+               print := &action{f: builderNoTest, p: p, deps: []*action{run}}
                return build, run, print, nil
        }
 
@@ -991,18 +991,18 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
        } else {
                // run test
                runAction = &action{
-                       f:          (*builder).runTest,
+                       f:          builderRunTest,
                        deps:       []*action{buildAction},
                        p:          p,
                        ignoreFail: true,
                }
                cleanAction := &action{
-                       f:    (*builder).cleanTest,
+                       f:    builderCleanTest,
                        deps: []*action{runAction},
                        p:    p,
                }
                printAction = &action{
-                       f:    (*builder).printTest,
+                       f:    builderPrintTest,
                        deps: []*action{cleanAction},
                        p:    p,
                }
@@ -1101,8 +1101,8 @@ func declareCoverVars(importPath string, files ...string) map[string]*CoverVar {
 
 var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
 
-// runTest is the action for running a test binary.
-func (b *builder) runTest(a *action) error {
+// builderRunTest is the action for running a test binary.
+func builderRunTest(b *builder, a *action) error {
        args := stringList(findExecCmd(), a.deps[0].target, testArgs)
        a.testOutput = new(bytes.Buffer)
 
@@ -1233,8 +1233,8 @@ func coveragePercentage(out []byte) string {
        return fmt.Sprintf("\tcoverage: %s", matches[1])
 }
 
-// cleanTest is the action for cleaning up after a test.
-func (b *builder) cleanTest(a *action) error {
+// builderCleanTest is the action for cleaning up after a test.
+func builderCleanTest(b *builder, a *action) error {
        if buildWork {
                return nil
        }
@@ -1244,8 +1244,8 @@ func (b *builder) cleanTest(a *action) error {
        return nil
 }
 
-// printTest is the action for printing a test result.
-func (b *builder) printTest(a *action) error {
+// builderPrintTest is the action for printing a test result.
+func builderPrintTest(b *builder, a *action) error {
        clean := a.deps[0]
        run := clean.deps[0]
        os.Stdout.Write(run.testOutput.Bytes())
@@ -1253,8 +1253,8 @@ func (b *builder) printTest(a *action) error {
        return nil
 }
 
-// notest is the action for testing a package with no test files.
-func (b *builder) notest(a *action) error {
+// builderNoTest is the action for testing a package with no test files.
+func builderNoTest(b *builder, a *action) error {
        fmt.Printf("?   \t%s\t[no test files]\n", a.p.ImportPath)
        return nil
 }