go/cmd/go: always link external test packages first

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
This commit is contained in:
Ian Lance Taylor 2015-03-31 17:54:07 +00:00
parent 397ad54db1
commit 9f5059b275
3 changed files with 14 additions and 5 deletions

View 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 {

View 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

View 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)