From: Michael Hudson-Doyle Date: Fri, 8 Apr 2016 03:06:04 +0000 (+1200) Subject: cmd/go: deduplicate gccgo afiles by package path, not *Package X-Git-Tag: go1.7beta1~672 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=12e3b184f0fe15787be7f0837d2b168a4fbe60be;p=gostls13.git cmd/go: deduplicate gccgo afiles by package path, not *Package This code was fixed a while ago to ensure that xtest and fake packages came first on the link line, but golang.org/cl/16775 added --whole-archive ... --no-whole-archive around all the .a files and rendered this fix useless. So, take a different approach and only put one .a file on the linker command line for each ImportPath we see while traversing the action graph, not for each *Package we see. The way we walk the graph ensures that we'll see the .a files that need to be first first. Change-Id: I137f00f129ccc9fc99f40eee885cc04cc358a62e Reviewed-on: https://go-review.googlesource.com/21692 Reviewed-by: Ian Lance Taylor --- diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index 6b9da26ae8..c0de2e0695 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -2602,10 +2602,9 @@ func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles func (tools gccgoToolchain) ld(b *builder, root *action, 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) + apackagePathsSeen := make(map[string]bool) afiles := []string{} shlibs := []string{} - xfiles := []string{} ldflags := b.gccArchArgs() cgoldflags := []string{} usesCgo := false @@ -2694,10 +2693,10 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions // rather than the 'build' location (which may not exist any // more). We still need to traverse the dependencies of the // build action though so saying - // if apackagesSeen[a.p] { return } + // if apackagePathsSeen[a.p.ImportPath] { return } // doesn't work. - if !apackagesSeen[a.p] { - apackagesSeen[a.p] = true + if !apackagePathsSeen[a.p.ImportPath] { + apackagePathsSeen[a.p.ImportPath] = true target := a.target if len(a.p.CgoFiles) > 0 { target, err = readAndRemoveCgoFlags(target) @@ -2705,17 +2704,7 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions return } } - if a.p.fake && a.p.external { - // external _tests, if present must come before - // internal _tests. Store these on a separate list - // and place them at the head after this loop. - xfiles = append(xfiles, target) - } else if a.p.fake { - // move _test files to the top of the link order - afiles = append([]string{target}, afiles...) - } else { - afiles = append(afiles, target) - } + afiles = append(afiles, target) } } if strings.HasSuffix(a.target, ".so") { @@ -2735,7 +2724,6 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions return err } } - afiles = append(xfiles, afiles...) for _, a := range allactions { // Gather CgoLDFLAGS, but not from standard packages.