go/cmd/go: always link external test packages first
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 31 Mar 2015 17:54:07 +0000 (17:54 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 31 Mar 2015 17:54:07 +0000 (17:54 +0000)
When linking complex packages that use both internal and external tests as well as many dependencies it is critical that the link order be external test package, internal test package, everything else.

This change is a back (forward?) port of the same change that canonical have been maintaining on their fork of the go tool for gccgo. Now that gccgo uses the go tool from upstream, this patch should be applied both to the gofrontend and golang/go repos.

From-SVN: r221800

libgo/go/cmd/go/build.go
libgo/go/cmd/go/pkg.go
libgo/go/cmd/go/test.go

index 22d37f3fa3b3fe2e2fc56254d88ed4d2f9c9cfc9..781a43b5d995c4f43597e1351d16a32df5ed6f03 100644 (file)
@@ -1921,6 +1921,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
        // and all LDFLAGS from cgo dependencies.
        apackagesSeen := make(map[*Package]bool)
        afiles := []string{}
+       xfiles := []string{}
        ldflags := b.gccArchArgs()
        cgoldflags := []string{}
        usesCgo := false
@@ -1936,7 +1937,12 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
                if !a.p.Standard {
                        if a.p != nil && !apackagesSeen[a.p] {
                                apackagesSeen[a.p] = true
-                               if a.p.fake {
+                               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 {
@@ -1945,6 +1951,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
                        }
                }
        }
+       afiles = append(xfiles, afiles...)
 
        for _, a := range allactions {
                if a.p != nil {
index 62f6b4adf57222ad50858a464079168bf523d202..ef440dd3b743a09d9d33805d7cee5a8dfc91a9a6 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 cc0a9acf45dfbcf7b4d92c56298afe2e15fdb1bc..5cf7aaf0716c2cc727330706a1a94cc8065a0e47 100644 (file)
@@ -692,10 +692,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)