summaryrefslogtreecommitdiff
path: root/src/cmd/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2014-05-12 12:43:51 -0700
committerIan Lance Taylor <iant@golang.org>2014-05-12 12:43:51 -0700
commit11460dcf0b008d89fa6915d1ead9194925e181b7 (patch)
tree71dbb0c9706011f1e2b071f1311138b34e09a8eb /src/cmd/go
parentfc46eb95614bccdfa01f448fc78acd1ee82adcc1 (diff)
downloadgo-11460dcf0b008d89fa6915d1ead9194925e181b7.tar.gz
cmd/go: link SWIG objects directly rather than using a shared library
This change requires using SWIG version 3.0 or later. Earlier versions of SWIG do not generate the pragmas required to use the external linker. Fixes issue 7155. Fixes issue 7156. LGTM=rsc R=rsc CC=golang-codereviews https://codereview.appspot.com/97120046
Diffstat (limited to 'src/cmd/go')
-rw-r--r--src/cmd/go/build.go105
-rw-r--r--src/cmd/go/clean.go14
-rw-r--r--src/cmd/go/doc.go1
-rw-r--r--src/cmd/go/pkg.go18
4 files changed, 26 insertions, 112 deletions
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 78ff9ade3..a6a21317e 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -1048,21 +1048,6 @@ func (b *builder) install(a *action) (err error) {
defer os.Remove(a1.target)
}
- if a.p.usesSwig() {
- for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
- dir = a.p.swigDir(&buildContext)
- if err := b.mkdir(dir); err != nil {
- return err
- }
- soname := a.p.swigSoname(f)
- source := filepath.Join(a.objdir, soname)
- target := filepath.Join(dir, soname)
- if err = b.copyFile(a, target, source, perm); err != nil {
- return err
- }
- }
- }
-
return b.moveOrCopyFile(a, a.target, a1.target, perm)
}
@@ -1721,25 +1706,8 @@ func packInternal(b *builder, afile string, ofiles []string) error {
func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
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)
- if len(swigArg) == 0 {
- swigArg = []string{"-r", sd}
- } else if !swigDirs[sd] {
- swigArg[1] += ":"
- swigArg[1] += sd
- }
- swigDirs[sd] = true
- if a.objdir != "" && !swigDirs[a.objdir] {
- swigArg[1] += ":"
- swigArg[1] += a.objdir
- swigDirs[a.objdir] = true
- }
- }
if a.p != nil && len(a.p.CXXFiles) > 0 {
cxx = true
}
@@ -1792,7 +1760,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
}
}
}
- return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
+ return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
}
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
@@ -1865,7 +1833,6 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
// and all LDFLAGS from cgo dependencies.
apackagesSeen := make(map[*Package]bool)
afiles := []string{}
- sfiles := []string{}
ldflags := b.gccArchArgs()
cgoldflags := []string{}
usesCgo := false
@@ -1898,14 +1865,6 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
usesCgo = true
}
if a.p.usesSwig() {
- sd := a.p.swigDir(&buildContext)
- if a.objdir != "" {
- sd = a.objdir
- }
- for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
- soname := a.p.swigSoname(f)
- sfiles = append(sfiles, filepath.Join(sd, soname))
- }
usesCgo = true
}
if len(a.p.CXXFiles) > 0 {
@@ -1917,7 +1876,6 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
}
}
ldflags = append(ldflags, afiles...)
- ldflags = append(ldflags, sfiles...)
ldflags = append(ldflags, cgoldflags...)
ldflags = append(ldflags, p.CgoLDFLAGS...)
if usesCgo && goos == "linux" {
@@ -2364,13 +2322,12 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
- var extraObj []string
for _, file := range gccfiles {
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
if err := b.gcc(p, ofile, cflags, file); err != nil {
return nil, nil, err
}
- extraObj = append(extraObj, ofile)
+ outObj = append(outObj, ofile)
}
for _, file := range gxxfiles {
@@ -2379,7 +2336,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
if err := b.gxx(p, ofile, cxxflags, file); err != nil {
return nil, nil, err
}
- extraObj = append(extraObj, ofile)
+ outObj = append(outObj, ofile)
}
for _, file := range mfiles {
@@ -2388,7 +2345,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
if err := b.gcc(p, ofile, cflags, file); err != nil {
return nil, nil, err
}
- extraObj = append(extraObj, ofile)
+ outObj = append(outObj, ofile)
}
intgosize, err := b.swigIntSize(obj)
@@ -2397,7 +2354,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
}
for _, f := range p.SwigFiles {
- goFile, objFile, err := b.swigOne(p, f, obj, false, intgosize, extraObj)
+ goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, false, intgosize)
if err != nil {
return nil, nil, err
}
@@ -2407,9 +2364,12 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
if objFile != "" {
outObj = append(outObj, objFile)
}
+ if gccObjFile != "" {
+ outObj = append(outObj, gccObjFile)
+ }
}
for _, f := range p.SwigCXXFiles {
- goFile, objFile, err := b.swigOne(p, f, obj, true, intgosize, extraObj)
+ goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, true, intgosize)
if err != nil {
return nil, nil, err
}
@@ -2419,6 +2379,9 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
if objFile != "" {
outObj = append(outObj, objFile)
}
+ if gccObjFile != "" {
+ outObj = append(outObj, gccObjFile)
+ }
}
return outGo, outObj, nil
}
@@ -2450,13 +2413,13 @@ func (b *builder) swigIntSize(obj string) (intsize string, err error) {
}
// Run SWIG on one SWIG input file.
-func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string, extraObj []string) (outGo, outObj string, err error) {
- cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
+func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
+ cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
var cflags []string
if cxx {
- cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS, "-fPIC")
+ cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS)
} else {
- cflags = stringList(cgoCPPFLAGS, cgoCFLAGS, "-fPIC")
+ cflags = stringList(cgoCPPFLAGS, cgoCFLAGS)
}
n := 5 // length of ".swig"
@@ -2471,7 +2434,6 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
if cxx {
gccExt = "cxx"
}
- soname := p.swigSoname(file)
_, gccgo := buildToolchain.(gccgoToolchain)
@@ -2480,12 +2442,14 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
"-go",
"-intgosize", intgosize,
"-module", base,
- "-soname", soname,
"-o", obj + gccBase + gccExt,
"-outdir", obj,
}
if gccgo {
args = append(args, "-gccgo")
+ if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+ args = append(args, "-go-pkgpath", pkgpath)
+ }
}
if cxx {
args = append(args, "-c++")
@@ -2494,12 +2458,12 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
if len(out) > 0 {
if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
- return "", "", errors.New("must have SWIG version >= 2.0.9\n")
+ return "", "", "", errors.New("must have SWIG version >= 3.0\n")
}
b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
- return "", "", errPrintedOutput
+ return "", "", "", errPrintedOutput
}
- return "", "", err
+ return "", "", "", err
}
var cObj string
@@ -2507,7 +2471,7 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
// cc
cObj = obj + cBase + archChar
if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
- return "", "", err
+ return "", "", "", err
}
}
@@ -2515,32 +2479,15 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
gccObj := obj + gccBase + "o"
if !cxx {
if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
- return "", "", err
+ return "", "", "", err
}
} else {
if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
- return "", "", err
+ return "", "", "", err
}
}
- // create shared library
- osldflags := map[string][]string{
- "darwin": {"-dynamiclib", "-Wl,-undefined,dynamic_lookup"},
- "freebsd": {"-shared", "-lpthread", "-lm"},
- "linux": {"-shared", "-lpthread", "-lm"},
- "windows": {"-shared", "-lm", "-mthreads"},
- }
- var cxxlib []string
- if cxx {
- cxxlib = []string{"-lstdc++"}
- }
- ldflags := stringList(osldflags[goos], cflags, cgoLDFLAGS, cxxlib)
- target := filepath.Join(obj, soname)
- if err := b.run(p.Dir, p.ImportPath, nil, b.gccCmd(p.Dir), "-o", target, gccObj, extraObj, ldflags); err != nil {
- return "", "", err
- }
-
- return obj + goFile, cObj, nil
+ return obj + goFile, cObj, gccObj, nil
}
// An actionQueue is a priority queue of actions.
diff --git a/src/cmd/go/clean.go b/src/cmd/go/clean.go
index 3028193bc..16054a5b5 100644
--- a/src/cmd/go/clean.go
+++ b/src/cmd/go/clean.go
@@ -216,20 +216,6 @@ func clean(p *Package) {
}
}
- if cleanI && p.usesSwig() {
- for _, f := range stringList(p.SwigFiles, p.SwigCXXFiles) {
- dir := p.swigDir(&buildContext)
- soname := p.swigSoname(f)
- target := filepath.Join(dir, soname)
- if buildN || buildX {
- b.showcmd("", "rm -f %s", target)
- }
- if !buildN {
- removeFile(target)
- }
- }
- }
-
if cleanR {
for _, p1 := range p.imports {
clean(p1)
diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go
index 7fe0008a0..05dc9c2bd 100644
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -144,7 +144,6 @@ source directories corresponding to the import paths:
DIR(.exe) from go build
DIR.test(.exe) from go test -c
MAINFILE(.exe) from go build MAINFILE.go
- *.so from SWIG
In the list, DIR represents the final path element of the
directory, and MAINFILE is the base name of any Go source
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 59c5d357e..7c78f8e66 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -560,24 +560,6 @@ func (p *Package) usesCgo() bool {
return len(p.CgoFiles) > 0
}
-// swigSoname returns the name of the shared library we create for a
-// SWIG input file.
-func (p *Package) swigSoname(file string) string {
- return strings.Replace(p.ImportPath, "/", "-", -1) + "-" + strings.Replace(file, ".", "-", -1) + ".so"
-}
-
-// swigDir returns the name of the shared SWIG directory for a
-// package.
-func (p *Package) swigDir(ctxt *build.Context) string {
- dir := p.build.PkgRoot
- if ctxt.Compiler == "gccgo" {
- dir = filepath.Join(dir, "gccgo_"+ctxt.GOOS+"_"+ctxt.GOARCH)
- } else {
- dir = filepath.Join(dir, ctxt.GOOS+"_"+ctxt.GOARCH)
- }
- return filepath.Join(dir, "swig")
-}
-
// packageList returns the list of packages in the dag rooted at roots
// as visited in a depth-first post-order traversal.
func packageList(roots []*Package) []*Package {