Skip to content

Commit f0ff63e

Browse files
cmd/go: if there are C++ sources, use g++ as default external linker
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
1 parent 7d734d9 commit f0ff63e

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

src/cmd/go/build.go

+51-1
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
15531553
importArgs := b.includeArgs("-L", allactions)
15541554
swigDirs := make(map[string]bool)
15551555
swigArg := []string{}
1556+
cxx := false
15561557
for _, a := range allactions {
15571558
if a.p != nil && a.p.usesSwig() {
15581559
sd := a.p.swigDir(&buildContext)
@@ -1564,8 +1565,50 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
15641565
}
15651566
swigDirs[sd] = true
15661567
}
1568+
if a.p != nil && len(a.p.CXXFiles) > 0 {
1569+
cxx = true
1570+
}
1571+
}
1572+
ldflags := buildLdflags
1573+
if cxx {
1574+
// The program includes C++ code. If the user has not
1575+
// specified the -extld option, then default to
1576+
// linking with the compiler named by the CXX
1577+
// environment variable, or g++ if CXX is not set.
1578+
extld := false
1579+
for _, f := range ldflags {
1580+
if f == "-extld" || strings.HasPrefix(f, "-extld=") {
1581+
extld = true
1582+
break
1583+
}
1584+
}
1585+
if !extld {
1586+
compiler := strings.Fields(os.Getenv("CXX"))
1587+
if len(compiler) == 0 {
1588+
compiler = []string{"g++"}
1589+
}
1590+
ldflags = append(ldflags, "-extld="+compiler[0])
1591+
if len(compiler) > 1 {
1592+
extldflags := false
1593+
add := strings.Join(compiler[1:], " ")
1594+
for i, f := range ldflags {
1595+
if f == "-extldflags" && i+1 < len(ldflags) {
1596+
ldflags[i+1] = add + " " + ldflags[i+1]
1597+
extldflags = true
1598+
break
1599+
} else if strings.HasPrefix(f, "-extldflags=") {
1600+
ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
1601+
extldflags = true
1602+
break
1603+
}
1604+
}
1605+
if !extldflags {
1606+
ldflags = append(ldflags, "-extldflags="+add)
1607+
}
1608+
}
1609+
}
15671610
}
1568-
return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, buildLdflags, mainpkg)
1611+
return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
15691612
}
15701613

15711614
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 []
16411684
ldflags := b.gccArchArgs()
16421685
cgoldflags := []string{}
16431686
usesCgo := false
1687+
cxx := false
16441688
for _, a := range allactions {
16451689
if a.p != nil {
16461690
if !a.p.Standard {
@@ -1660,6 +1704,9 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
16601704
}
16611705
usesCgo = true
16621706
}
1707+
if len(a.p.CXXFiles) > 0 {
1708+
cxx = true
1709+
}
16631710
}
16641711
}
16651712
for _, afile := range afiles {
@@ -1672,6 +1719,9 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
16721719
if usesCgo && goos == "linux" {
16731720
ldflags = append(ldflags, "-Wl,-E")
16741721
}
1722+
if cxx {
1723+
ldflags = append(ldflags, "-lstdc++")
1724+
}
16751725
return b.run(".", p.ImportPath, nil, "gccgo", "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
16761726
}
16771727

0 commit comments

Comments
 (0)