]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: always link external test packages first when using gccgo
authorDave Cheney <dave@cheney.net>
Mon, 30 Mar 2015 05:13:39 +0000 (16:13 +1100)
committerDave Cheney <dave@cheney.net>
Wed, 1 Apr 2015 09:10:59 +0000 (09:10 +0000)
This CL is an amagamation of several fixes Canonical have made on their
fork of the cmd/go tool (packaged as gccgo-go.deb on Ubuntu 14.04+).

Additionally this CL brings gccgoToolchain.ldi() up to date with the version
that will ship in gccgo-5.0. As gccgo is most likely to be used with its
own version of the go tool that it supples it makes good sense that the libgo
version should dictate the contents of gccgotoolchain.ld()

Please see https://codereview.appspot.com/222890043/ for more details on the
issues fixed.

Change-Id: Icf7deb43f8e80b424757f1673e6bca7a0aa2a1ac
Reviewed-on: https://go-review.googlesource.com/8250
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/build.go
src/cmd/go/pkg.go
src/cmd/go/test.go

index 32a9f73ed59ca9ad6ffe9dc768884c39479d9b30..61453c7e2bb11ad0729c2b817b311cc547bcedcc 100644 (file)
@@ -1968,35 +1968,39 @@ func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles
 func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
        // gccgo needs explicit linking with all package dependencies,
        // and all LDFLAGS from cgo dependencies.
+       apackagesSeen := make(map[*Package]bool)
        afiles := []string{}
+       xfiles := []string{}
        ldflags := b.gccArchArgs()
        cgoldflags := []string{}
        usesCgo := false
        cxx := len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0
        objc := len(p.MFiles) > 0
 
-       // For a given package import path:
-       //   1) prefer a test package (created by (*builder).test) to a non-test package
-       //   2) prefer the output of an install action to the output of a build action
-       //      because the install action will delete the output of the build
-       //      action
-       // Iterating over the list backwards (reverse dependency order) ensures that we
-       // always see an install before a build.
-       importPathsSeen := make(map[string]bool)
+       // Prefer the output of an install action to the output of a build action,
+       // because the install action will delete the output of the build action.
+       // Iterate over the list backward (reverse dependency order) so that we
+       // always see the install before the build.
        for i := len(allactions) - 1; i >= 0; i-- {
                a := allactions[i]
-               if a.p.fake && !importPathsSeen[a.p.ImportPath] {
-                       importPathsSeen[a.p.ImportPath] = true
-                       afiles = append(afiles, a.target)
-               }
-       }
-       for i := len(allactions) - 1; i >= 0; i-- {
-               a := allactions[i]
-               if !a.p.Standard && !importPathsSeen[a.p.ImportPath] {
-                       importPathsSeen[a.p.ImportPath] = true
-                       afiles = append(afiles, a.target)
+               if !a.p.Standard {
+                       if a.p != nil && !apackagesSeen[a.p] {
+                               apackagesSeen[a.p] = true
+                               if a.p.fake && a.p.external {
+                                       // external _tests, if present must come before
+                                       // internal _tests. Store these on a seperate list
+                                       // and place them at the head after this loop.
+                                       xfiles = append(xfiles, a.target)
+                               } else if a.p.fake {
+                                       // move _test files to the top of the link order
+                                       afiles = append([]string{a.target}, afiles...)
+                               } else {
+                                       afiles = append(afiles, a.target)
+                               }
+                       }
                }
        }
+       afiles = append(xfiles, afiles...)
 
        for _, a := range allactions {
                cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
index 6c157932fbab95df796212e5633481f0bbde6456..8bf0f568f792041a5581b1dd1d352e415d0e9035 100644 (file)
@@ -83,6 +83,7 @@ type Package struct {
        allgofiles   []string             // gofiles + IgnoredGoFiles, absolute paths
        target       string               // installed file for this package (may be executable)
        fake         bool                 // synthesized package
+       external     bool                 // synthesized external test package
        forceBuild   bool                 // this package must be rebuilt
        forceLibrary bool                 // this package is a library (even if named "main")
        cmdline      bool                 // defined by files listed on command line
index c44a2199dc2a34cdd4ffe5e8148eabad7838503d..e96ed22361b3e0aeb94671d2e176a3d6ace7e4ef 100644 (file)
@@ -687,10 +687,11 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
                        build: &build.Package{
                                ImportPos: p.build.XTestImportPos,
                        },
-                       imports: ximports,
-                       pkgdir:  testDir,
-                       fake:    true,
-                       Stale:   true,
+                       imports:  ximports,
+                       pkgdir:   testDir,
+                       fake:     true,
+                       external: true,
+                       Stale:    true,
                }
                if pxtestNeedsPtest {
                        pxtest.imports = append(pxtest.imports, ptest)