]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: combine gccgo's ld and ldShared methods
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Tue, 31 May 2016 08:48:42 +0000 (20:48 +1200)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Tue, 31 May 2016 22:23:53 +0000 (22:23 +0000)
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 <iant@golang.org>
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/go/build.go

index 340fcd767b330b66b2372f9b24968c71ca3ebc6f..5327fb9e4a57de6137eba8f669b4bd5b25a7172d 100644 (file)
@@ -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 {