]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: if there are C++ sources, use g++ as default external linker
authorIan Lance Taylor <iant@golang.org>
Mon, 9 Sep 2013 19:50:49 +0000 (12:50 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 9 Sep 2013 19:50:49 +0000 (12:50 -0700)
This will bring in the C++ standard library without requiring
any special #cgo LDFLAGS options.

When using gccgo, just add -lstdc++ to link line; this should
do no harm if it is not needed.

No tests, since we don't want to assume a C++ compiler.

Update #5629

R=golang-dev, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/13394045

src/cmd/go/build.go

index 1846f745dafa1db6b72ddf432c9b18c81a96e751..af80be8081ca021d13069293c50f131887a23427 100644 (file)
@@ -1553,6 +1553,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
        importArgs := b.includeArgs("-L", allactions)
        swigDirs := make(map[string]bool)
        swigArg := []string{}
+       cxx := false
        for _, a := range allactions {
                if a.p != nil && a.p.usesSwig() {
                        sd := a.p.swigDir(&buildContext)
@@ -1564,8 +1565,50 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
                        }
                        swigDirs[sd] = true
                }
+               if a.p != nil && len(a.p.CXXFiles) > 0 {
+                       cxx = true
+               }
+       }
+       ldflags := buildLdflags
+       if cxx {
+               // The program includes C++ code.  If the user has not
+               // specified the -extld option, then default to
+               // linking with the compiler named by the CXX
+               // environment variable, or g++ if CXX is not set.
+               extld := false
+               for _, f := range ldflags {
+                       if f == "-extld" || strings.HasPrefix(f, "-extld=") {
+                               extld = true
+                               break
+                       }
+               }
+               if !extld {
+                       compiler := strings.Fields(os.Getenv("CXX"))
+                       if len(compiler) == 0 {
+                               compiler = []string{"g++"}
+                       }
+                       ldflags = append(ldflags, "-extld="+compiler[0])
+                       if len(compiler) > 1 {
+                               extldflags := false
+                               add := strings.Join(compiler[1:], " ")
+                               for i, f := range ldflags {
+                                       if f == "-extldflags" && i+1 < len(ldflags) {
+                                               ldflags[i+1] = add + " " + ldflags[i+1]
+                                               extldflags = true
+                                               break
+                                       } else if strings.HasPrefix(f, "-extldflags=") {
+                                               ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
+                                               extldflags = true
+                                               break
+                                       }
+                               }
+                               if !extldflags {
+                                       ldflags = append(ldflags, "-extldflags="+add)
+                               }
+                       }
+               }
        }
-       return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, buildLdflags, mainpkg)
+       return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
 }
 
 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
@@ -1641,6 +1684,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
        ldflags := b.gccArchArgs()
        cgoldflags := []string{}
        usesCgo := false
+       cxx := false
        for _, a := range allactions {
                if a.p != nil {
                        if !a.p.Standard {
@@ -1660,6 +1704,9 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
                                }
                                usesCgo = true
                        }
+                       if len(a.p.CXXFiles) > 0 {
+                               cxx = true
+                       }
                }
        }
        for _, afile := range afiles {
@@ -1672,6 +1719,9 @@ 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++")
+       }
        return b.run(".", p.ImportPath, nil, "gccgo", "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
 }