diff options
author | Ian Lance Taylor <iant@golang.org> | 2014-05-12 12:43:51 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2014-05-12 12:43:51 -0700 |
commit | 11460dcf0b008d89fa6915d1ead9194925e181b7 (patch) | |
tree | 71dbb0c9706011f1e2b071f1311138b34e09a8eb /src/cmd/go | |
parent | fc46eb95614bccdfa01f448fc78acd1ee82adcc1 (diff) | |
download | go-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.go | 105 | ||||
-rw-r--r-- | src/cmd/go/clean.go | 14 | ||||
-rw-r--r-- | src/cmd/go/doc.go | 1 | ||||
-rw-r--r-- | src/cmd/go/pkg.go | 18 |
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 { |