]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: support -buildmode=c-shared for gccgo
authorIan Lance Taylor <iant@golang.org>
Thu, 30 Apr 2015 19:08:46 +0000 (12:08 -0700)
committerIan Lance Taylor <iant@golang.org>
Thu, 30 Apr 2015 21:03:07 +0000 (21:03 +0000)
Change-Id: I4cdfd5a59e0468e9e5400aa06334b21cc80913cd
Reviewed-on: https://go-review.googlesource.com/9550
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/go/build.go

index 1791aa777effee853c531da3d2308468e9b2f61c..de06fe7b1d2c236a4101be7e43544fb1bd3232d0 100644 (file)
@@ -308,6 +308,7 @@ func pkgsNotMain(pkgs []*Package) (res []*Package) {
 var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
 
 func buildModeInit() {
+       _, gccgo := buildToolchain.(gccgoToolchain)
        var codegenArg string
        platform := goos + "/" + goarch
        switch buildBuildmode {
@@ -324,14 +325,18 @@ func buildModeInit() {
                ldBuildmode = "c-archive"
        case "c-shared":
                pkgsFilter = pkgsMain
-               switch platform {
-               case "linux/amd64":
-                       codegenArg = "-shared"
-               case "linux/arm":
-                       buildAsmflags = append(buildAsmflags, "-shared")
-               case "android/arm":
-               default:
-                       fatalf("-buildmode=c-shared not supported on %s\n", platform)
+               if gccgo {
+                       codegenArg = "-fPIC"
+               } else {
+                       switch platform {
+                       case "linux/amd64":
+                               codegenArg = "-shared"
+                       case "linux/arm":
+                               buildAsmflags = append(buildAsmflags, "-shared")
+                       case "android/arm":
+                       default:
+                               fatalf("-buildmode=c-shared not supported on %s\n", platform)
+                       }
                }
                ldBuildmode = "c-shared"
        case "default":
@@ -341,31 +346,43 @@ func buildModeInit() {
                ldBuildmode = "exe"
        case "shared":
                pkgsFilter = pkgsNotMain
-               switch platform {
-               case "linux/amd64":
-               default:
-                       fatalf("-buildmode=shared not supported on %s\n", platform)
+               if gccgo {
+                       codegenArg = "-fPIC"
+               } else {
+                       switch platform {
+                       case "linux/amd64":
+                       default:
+                               fatalf("-buildmode=shared not supported on %s\n", platform)
+                       }
+                       codegenArg = "-dynlink"
                }
                if *buildO != "" {
                        fatalf("-buildmode=shared and -o not supported together")
                }
-               codegenArg = "-dynlink"
                ldBuildmode = "shared"
        default:
                fatalf("buildmode=%s not supported", buildBuildmode)
        }
        if buildLinkshared {
-               if platform != "linux/amd64" {
-                       fmt.Fprintf(os.Stderr, "go %s: -linkshared is only supported on linux/amd64\n", flag.Args()[0])
-                       os.Exit(2)
+               if gccgo {
+                       codegenArg = "-fPIC"
+               } else {
+                       if platform != "linux/amd64" {
+                               fmt.Fprintf(os.Stderr, "go %s: -linkshared is only supported on linux/amd64\n", flag.Args()[0])
+                               os.Exit(2)
+                       }
+                       codegenArg = "-dynlink"
+                       // TODO(mwhudson): remove -w when that gets fixed in linker.
+                       buildLdflags = append(buildLdflags, "-linkshared", "-w")
                }
-               codegenArg = "-dynlink"
-               // TODO(mwhudson): remove -w when that gets fixed in linker.
-               buildLdflags = append(buildLdflags, "-linkshared", "-w")
        }
        if codegenArg != "" {
-               buildAsmflags = append(buildAsmflags, codegenArg)
-               buildGcflags = append(buildGcflags, codegenArg)
+               if gccgo {
+                       buildGccgoflags = append(buildGccgoflags, codegenArg)
+               } else {
+                       buildAsmflags = append(buildAsmflags, codegenArg)
+                       buildGcflags = append(buildGcflags, codegenArg)
+               }
                if buildContext.InstallSuffix != "" {
                        buildContext.InstallSuffix += "_"
                }
@@ -2166,6 +2183,7 @@ func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string
        if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
                defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
        }
+       defs = tools.maybePIC(defs)
        defs = append(defs, b.gccArchArgs()...)
        return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-I", obj, "-o", ofile, defs, sfile)
 }
@@ -2244,13 +2262,15 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
                }
        }
 
-       if ldBuildmode == "c-archive" {
+       switch ldBuildmode {
+       case "c-archive", "c-shared":
                ldflags = append(ldflags, "-Wl,--whole-archive")
        }
 
        ldflags = append(ldflags, afiles...)
 
-       if ldBuildmode == "c-archive" {
+       switch ldBuildmode {
+       case "c-archive", "c-shared":
                ldflags = append(ldflags, "-Wl,--no-whole-archive")
        }
 
@@ -2266,12 +2286,6 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
                if usesCgo && goos == "linux" {
                        ldflags = append(ldflags, "-Wl,-E")
                }
-               if cxx {
-                       ldflags = append(ldflags, "-lstdc++")
-               }
-               if objc {
-                       ldflags = append(ldflags, "-lobjc")
-               }
 
        case "c-archive":
                // Link the Go files into a single .o, and also link
@@ -2296,10 +2310,23 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
                realOut = out
                out = out + ".o"
 
+       case "c-shared":
+               ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc")
+
        default:
                fatalf("-buildmode=%s not supported for gccgo", ldBuildmode)
        }
 
+       switch ldBuildmode {
+       case "exe", "c-shared":
+               if cxx {
+                       ldflags = append(ldflags, "-lstdc++")
+               }
+               if objc {
+                       ldflags = append(ldflags, "-lobjc")
+               }
+       }
+
        if err := b.run(".", p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
                return err
        }
@@ -2314,7 +2341,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
        return nil
 }
 
-func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
+func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
        inc := filepath.Join(goroot, "pkg", "include")
        cfile = mkAbs(p.Dir, cfile)
        defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
@@ -2326,10 +2353,20 @@ func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) er
        case "386", "amd64":
                defs = append(defs, "-fsplit-stack")
        }
+       defs = tools.maybePIC(defs)
        return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
                "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
 }
 
+// maybePIC adds -fPIC to the list of arguments if needed.
+func (tools gccgoToolchain) maybePIC(args []string) []string {
+       switch buildBuildmode {
+       case "c-shared", "shared":
+               args = append(args, "-fPIC")
+       }
+       return args
+}
+
 func gccgoPkgpath(p *Package) string {
        if p.build.IsCommand() && !p.forceLibrary {
                return ""