Backport from mainline:

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.
    
    Reviewed-on: https://go-review.googlesource.com/21692


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-6-branch@239437 138bc75d-0d04-0410-961f-82ee72b054a4
This commit is contained in:
ian 2016-08-13 00:08:12 +00:00
parent d6b2dea603
commit 2547449979

View File

@ -2632,10 +2632,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
@ -2647,9 +2646,18 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions
if err != nil {
return err
}
const ldflagsPrefix = "_CGO_LDFLAGS="
for _, line := range strings.Split(string(flags), "\n") {
if strings.HasPrefix(line, "_CGO_LDFLAGS=") {
cgoldflags = append(cgoldflags, strings.Fields(line[13:])...)
if strings.HasPrefix(line, ldflagsPrefix) {
newFlags := strings.Fields(line[len(ldflagsPrefix):])
for _, flag := range newFlags {
// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
// but they don't mean anything to the linker so filter
// them out.
if flag != "-g" && !strings.HasPrefix(flag, "-O") {
cgoldflags = append(cgoldflags, flag)
}
}
}
}
return nil
@ -2714,10 +2722,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)
@ -2725,17 +2733,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") {
@ -2755,7 +2753,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.