From: Michael Hudson-Doyle Date: Tue, 31 May 2016 08:48:42 +0000 (+1200) Subject: cmd/go: combine gccgo's ld and ldShared methods X-Git-Tag: go1.7beta1~23 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1846c632ee37681eb92fb27f7071a58bdf6d7a3c;p=gostls13.git cmd/go: combine gccgo's ld and ldShared methods This fixes handling of cgo flags and makes sure packages that are only implicitly included in the shared library are passed to the link. Fixes #15885 Change-Id: I1e8a72b5314261973ca903c78834700fb113dde9 Reviewed-on: https://go-review.googlesource.com/23537 Reviewed-by: Ian Lance Taylor Run-TryBot: Michael Hudson-Doyle TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index 340fcd767b..5327fb9e4a 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -2625,7 +2625,7 @@ func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objDir, afile), absOfiles) } -func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error { +func (tools gccgoToolchain) link(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string, buildmode, desc string) error { // gccgo needs explicit linking with all package dependencies, // and all LDFLAGS from cgo dependencies. apackagePathsSeen := make(map[string]bool) @@ -2634,9 +2634,14 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions ldflags := b.gccArchArgs() cgoldflags := []string{} usesCgo := false - cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0 - objc := len(root.p.MFiles) > 0 - fortran := len(root.p.FFiles) > 0 + cxx := false + objc := false + fortran := false + if root.p != nil { + cxx = len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0 + objc = len(root.p.MFiles) > 0 + fortran = len(root.p.FFiles) > 0 + } readCgoFlags := func(flagsFile string) error { flags, err := ioutil.ReadFile(flagsFile) @@ -2683,11 +2688,11 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions } newarchive := newa.Name() - err = b.run(b.work, root.p.ImportPath, nil, "ar", "x", newarchive, "_cgo_flags") + err = b.run(b.work, desc, nil, "ar", "x", newarchive, "_cgo_flags") if err != nil { return "", err } - err = b.run(".", root.p.ImportPath, nil, "ar", "d", newarchive, "_cgo_flags") + err = b.run(".", desc, nil, "ar", "d", newarchive, "_cgo_flags") if err != nil { return "", err } @@ -2793,7 +2798,9 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions ldflags = append(ldflags, cgoldflags...) ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...) - ldflags = append(ldflags, root.p.CgoLDFLAGS...) + if root.p != nil { + ldflags = append(ldflags, root.p.CgoLDFLAGS...) + } ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)") @@ -2808,7 +2815,7 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions } var realOut string - switch ldBuildmode { + switch buildmode { case "exe": if usesCgo && goos == "linux" { ldflags = append(ldflags, "-Wl,-E") @@ -2843,12 +2850,14 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions case "c-shared": ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc") + case "shared": + ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc") default: - fatalf("-buildmode=%s not supported for gccgo", ldBuildmode) + fatalf("-buildmode=%s not supported for gccgo", buildmode) } - switch ldBuildmode { + switch buildmode { case "exe", "c-shared": if cxx { ldflags = append(ldflags, "-lstdc++") @@ -2869,41 +2878,27 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions } } - if err := b.run(".", root.p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil { + if err := b.run(".", desc, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil { return err } - switch ldBuildmode { + switch buildmode { case "c-archive": - if err := b.run(".", root.p.ImportPath, nil, "ar", "rc", realOut, out); err != nil { + if err := b.run(".", desc, nil, "ar", "rc", realOut, out); err != nil { return err } } return nil } +func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error { + return tools.link(b, root, out, allactions, mainpkg, ofiles, ldBuildmode, root.p.ImportPath) +} + func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error { - args := []string{"-o", out, "-shared", "-nostdlib", "-zdefs", "-Wl,--whole-archive"} - for _, a := range toplevelactions { - args = append(args, a.target) - } - args = append(args, "-Wl,--no-whole-archive", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc") - shlibs := []string{} - for _, a := range allactions { - if strings.HasSuffix(a.target, ".so") { - shlibs = append(shlibs, a.target) - } - } - for _, shlib := range shlibs { - args = append( - args, - "-L"+filepath.Dir(shlib), - "-Wl,-rpath="+filepath.Dir(shlib), - "-l"+strings.TrimSuffix( - strings.TrimPrefix(filepath.Base(shlib), "lib"), - ".so")) - } - return b.run(".", out, nil, tools.linker(), args, buildGccgoflags) + fakeRoot := &action{} + fakeRoot.deps = toplevelactions + return tools.link(b, fakeRoot, out, allactions, "", nil, "shared", out) } func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {