mirror of
https://github.com/golang/go
synced 2024-11-22 01:24:42 -07:00
cmd/go, go/build, misc/swig: add SWIG support to Go tool
R=adg, rsc, franciscossouza, seb.binet, gen.battle CC=golang-dev https://golang.org/cl/5845071
This commit is contained in:
parent
dee5adcf74
commit
6fa38e5e0a
@ -23,6 +23,8 @@ pkg go/ast, method (CommentMap) Filter(Node) CommentMap
|
|||||||
pkg go/ast, method (CommentMap) String() string
|
pkg go/ast, method (CommentMap) String() string
|
||||||
pkg go/ast, method (CommentMap) Update(Node) Node
|
pkg go/ast, method (CommentMap) Update(Node) Node
|
||||||
pkg go/ast, type CommentMap map[Node][]*CommentGroup
|
pkg go/ast, type CommentMap map[Node][]*CommentGroup
|
||||||
|
pkg go/build, type Package struct, SwigCXXFiles []string
|
||||||
|
pkg go/build, type Package struct, SwigFiles []string
|
||||||
pkg go/doc, var IllegalPrefixes []string
|
pkg go/doc, var IllegalPrefixes []string
|
||||||
pkg image, const YCbCrSubsampleRatio440 YCbCrSubsampleRatio
|
pkg image, const YCbCrSubsampleRatio440 YCbCrSubsampleRatio
|
||||||
pkg math/big, method (*Int) MarshalJSON() ([]byte, error)
|
pkg math/big, method (*Int) MarshalJSON() ([]byte, error)
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
# Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
# Use of this source code is governed by a BSD-style
|
|
||||||
# license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
include ../../../src/Make.inc
|
|
||||||
|
|
||||||
TARG=swig/callback
|
|
||||||
SWIGFILES=\
|
|
||||||
callback.swigcxx
|
|
||||||
|
|
||||||
CLEANFILES+=run
|
|
||||||
|
|
||||||
include ../../../src/Make.pkg
|
|
||||||
|
|
||||||
%: install %.go
|
|
||||||
$(GC) $(GCFLAGS) $(GCIMPORTS) $*.go
|
|
||||||
$(LD) $(SWIG_RPATH) -o $@ $*.$O
|
|
11
misc/swig/callback/callback.go
Normal file
11
misc/swig/callback/callback.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package callback
|
||||||
|
|
||||||
|
type GoCallback struct{}
|
||||||
|
|
||||||
|
func (p *GoCallback) Run() string {
|
||||||
|
return "GoCallback.Run"
|
||||||
|
}
|
34
misc/swig/callback/callback_test.go
Normal file
34
misc/swig/callback/callback_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package callback_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"../callback"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCall(t *testing.T) {
|
||||||
|
c := callback.NewCaller()
|
||||||
|
cb := callback.NewCallback()
|
||||||
|
|
||||||
|
c.SetCallback(cb)
|
||||||
|
s := c.Call()
|
||||||
|
if s != "Callback::run" {
|
||||||
|
t.Errorf("unexpected string from Call: %q", s)
|
||||||
|
}
|
||||||
|
c.DelCallback()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCallback(t *testing.T) {
|
||||||
|
c := callback.NewCaller()
|
||||||
|
cb := callback.NewDirectorCallback(&callback.GoCallback{})
|
||||||
|
c.SetCallback(cb)
|
||||||
|
s := c.Call()
|
||||||
|
if s != "GoCallback.Run" {
|
||||||
|
t.Errorf("unexpected string from Call with callback: %q", s)
|
||||||
|
}
|
||||||
|
c.DelCallback()
|
||||||
|
callback.DeleteDirectorCallback(cb)
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"swig/callback"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GoCallback struct{}
|
|
||||||
|
|
||||||
func (p *GoCallback) Run() string {
|
|
||||||
return "GoCallback.Run"
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
c := callback.NewCaller()
|
|
||||||
cb := callback.NewCallback()
|
|
||||||
|
|
||||||
c.SetCallback(cb)
|
|
||||||
s := c.Call()
|
|
||||||
fmt.Println(s)
|
|
||||||
if s != "Callback::run" {
|
|
||||||
panic(s)
|
|
||||||
}
|
|
||||||
c.DelCallback()
|
|
||||||
|
|
||||||
cb = callback.NewDirectorCallback(&GoCallback{})
|
|
||||||
c.SetCallback(cb)
|
|
||||||
s = c.Call()
|
|
||||||
fmt.Println(s)
|
|
||||||
if s != "GoCallback.Run" {
|
|
||||||
panic(s)
|
|
||||||
}
|
|
||||||
c.DelCallback()
|
|
||||||
callback.DeleteDirectorCallback(cb)
|
|
||||||
}
|
|
@ -6,6 +6,19 @@
|
|||||||
|
|
||||||
%{
|
%{
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
%}
|
%}
|
||||||
|
|
||||||
int puts(const char *);
|
%typemap(gotype) const char * "string"
|
||||||
|
%typemap(in) const char * %{
|
||||||
|
$1 = malloc($input.n + 1);
|
||||||
|
memcpy($1, $input.p, $input.n);
|
||||||
|
$1[$input.n] = '\0';
|
||||||
|
%}
|
||||||
|
%typemap(freearg) const char * %{
|
||||||
|
free($1);
|
||||||
|
%}
|
||||||
|
|
||||||
|
FILE *fopen(const char *name, const char *mode);
|
||||||
|
int fclose(FILE *);
|
||||||
|
int fgetc(FILE *);
|
||||||
|
22
misc/swig/stdio/file_test.go
Normal file
22
misc/swig/stdio/file_test.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package file
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// Open this file itself and verify that the first few characters are
|
||||||
|
// as expected.
|
||||||
|
func TestRead(t *testing.T) {
|
||||||
|
f := Fopen("file_test.go", "r")
|
||||||
|
if f == nil {
|
||||||
|
t.Fatal("fopen failed")
|
||||||
|
}
|
||||||
|
if Fgetc(f) != '/' || Fgetc(f) != '/' || Fgetc(f) != ' ' || Fgetc(f) != 'C' {
|
||||||
|
t.Error("read unexpected characters")
|
||||||
|
}
|
||||||
|
if Fclose(f) != 0 {
|
||||||
|
t.Error("fclose failed")
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "swig/file"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
file.Puts("Hello, world")
|
|
||||||
}
|
|
@ -684,6 +684,21 @@ func (b *builder) build(a *action) (err error) {
|
|||||||
gofiles = append(gofiles, outGo...)
|
gofiles = append(gofiles, outGo...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run SWIG.
|
||||||
|
if a.p.usesSwig() {
|
||||||
|
// In a package using SWIG, any .c or .s files are
|
||||||
|
// compiled with gcc.
|
||||||
|
gccfiles := append(cfiles, sfiles...)
|
||||||
|
cfiles = nil
|
||||||
|
sfiles = nil
|
||||||
|
outGo, outObj, err := b.swig(a.p, obj, gccfiles)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cgoObjects = append(cgoObjects, outObj...)
|
||||||
|
gofiles = append(gofiles, outGo...)
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare Go import path list.
|
// Prepare Go import path list.
|
||||||
inc := b.includeArgs("-I", a.deps)
|
inc := b.includeArgs("-I", a.deps)
|
||||||
|
|
||||||
@ -799,6 +814,20 @@ func (b *builder) install(a *action) (err error) {
|
|||||||
defer os.Remove(a1.target)
|
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)
|
||||||
|
target := filepath.Join(dir, soname)
|
||||||
|
if err = b.copyFile(a, target, soname, perm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return b.copyFile(a, a.target, a1.target, perm)
|
return b.copyFile(a, a.target, a1.target, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,7 +1304,21 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
|
|||||||
|
|
||||||
func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg 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)
|
importArgs := b.includeArgs("-L", allactions)
|
||||||
return b.run(".", p.ImportPath, tool(archChar+"l"), "-o", out, importArgs, buildLdflags, mainpkg)
|
swigDirs := make(map[string]bool)
|
||||||
|
swigArg := []string{}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.run(".", p.ImportPath, tool(archChar+"l"), "-o", out, importArgs, swigArg, buildLdflags, mainpkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
|
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
|
||||||
@ -1336,6 +1379,7 @@ func (tools gccgcToolchain) ld(b *builder, p *Package, out string, allactions []
|
|||||||
// gccgo needs explicit linking with all package dependencies,
|
// gccgo needs explicit linking with all package dependencies,
|
||||||
// and all LDFLAGS from cgo dependencies.
|
// and all LDFLAGS from cgo dependencies.
|
||||||
afiles := make(map[*Package]string)
|
afiles := make(map[*Package]string)
|
||||||
|
sfiles := make(map[*Package][]string)
|
||||||
ldflags := []string{}
|
ldflags := []string{}
|
||||||
cgoldflags := []string{}
|
cgoldflags := []string{}
|
||||||
for _, a := range allactions {
|
for _, a := range allactions {
|
||||||
@ -1346,11 +1390,21 @@ func (tools gccgcToolchain) ld(b *builder, p *Package, out string, allactions []
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
|
cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
|
||||||
|
if a.p.usesSwig() {
|
||||||
|
sd := a.p.swigDir(&buildContext)
|
||||||
|
for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
|
||||||
|
soname := a.p.swigSoname(f)
|
||||||
|
sfiles[a.p] = append(sfiles[a.p], filepath.Join(sd, soname))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, afile := range afiles {
|
for _, afile := range afiles {
|
||||||
ldflags = append(ldflags, afile)
|
ldflags = append(ldflags, afile)
|
||||||
}
|
}
|
||||||
|
for _, sfiles := range sfiles {
|
||||||
|
ldflags = append(ldflags, sfiles...)
|
||||||
|
}
|
||||||
ldflags = append(ldflags, cgoldflags...)
|
ldflags = append(ldflags, cgoldflags...)
|
||||||
return b.run(".", p.ImportPath, "gccgo", "-o", out, buildGccgoflags, ofiles, "-Wl,-(", ldflags, "-Wl,-)")
|
return b.run(".", p.ImportPath, "gccgo", "-o", out, buildGccgoflags, ofiles, "-Wl,-(", ldflags, "-Wl,-)")
|
||||||
}
|
}
|
||||||
@ -1558,6 +1612,104 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
|||||||
return outGo, outObj, nil
|
return outGo, outObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run SWIG on all SWIG input files.
|
||||||
|
func (b *builder) swig(p *Package, obj string, gccfiles []string) (outGo, outObj []string, err error) {
|
||||||
|
for _, f := range p.SwigFiles {
|
||||||
|
goFile, objFile, err := b.swigOne(p, f, obj, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if goFile != "" {
|
||||||
|
outGo = append(outGo, goFile)
|
||||||
|
}
|
||||||
|
if objFile != "" {
|
||||||
|
outObj = append(outObj, objFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, f := range p.SwigCXXFiles {
|
||||||
|
goFile, objFile, err := b.swigOne(p, f, obj, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if goFile != "" {
|
||||||
|
outGo = append(outGo, goFile)
|
||||||
|
}
|
||||||
|
if objFile != "" {
|
||||||
|
outObj = append(outObj, objFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outGo, outObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run SWIG on one SWIG input file.
|
||||||
|
func (b *builder) swigOne(p *Package, file, obj string, cxx bool) (outGo, outObj string, err error) {
|
||||||
|
n := 5 // length of ".swig"
|
||||||
|
if cxx {
|
||||||
|
n = 8 // length of ".swigcxx"
|
||||||
|
}
|
||||||
|
base := file[:len(file)-n]
|
||||||
|
goFile := base + ".go"
|
||||||
|
cBase := base + "_gc."
|
||||||
|
gccBase := base + "_wrap."
|
||||||
|
gccExt := "c"
|
||||||
|
if cxx {
|
||||||
|
gccExt = "cxx"
|
||||||
|
}
|
||||||
|
soname := p.swigSoname(file)
|
||||||
|
|
||||||
|
_, gccgo := buildToolchain.(gccgcToolchain)
|
||||||
|
|
||||||
|
// swig
|
||||||
|
args := []string{
|
||||||
|
"-go",
|
||||||
|
"-module", base,
|
||||||
|
"-soname", soname,
|
||||||
|
"-o", obj + gccBase + gccExt,
|
||||||
|
"-outdir", obj,
|
||||||
|
}
|
||||||
|
if gccgo {
|
||||||
|
args = append(args, "-gccgo")
|
||||||
|
}
|
||||||
|
if cxx {
|
||||||
|
args = append(args, "-c++")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := b.run(p.Dir, p.ImportPath, "swig", args, file); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var cObj string
|
||||||
|
if !gccgo {
|
||||||
|
// cc
|
||||||
|
cObj = obj + cBase + archChar
|
||||||
|
if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// gcc
|
||||||
|
gccObj := obj + gccBase + "o"
|
||||||
|
if err := b.gcc(p, gccObj, []string{"-g", "-fPIC", "-O2"}, obj+gccBase+gccExt); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create shared library
|
||||||
|
osldflags := map[string][]string{
|
||||||
|
"darwin": []string{"-dynamiclib", "-Wl,-undefined,dynamic_lookup"},
|
||||||
|
"freebsd": []string{"-shared", "-lpthread", "-lm"},
|
||||||
|
"linux": []string{"-shared", "-lpthread", "-lm"},
|
||||||
|
"windows": []string{"-shared", "-lm", "-mthreads"},
|
||||||
|
}
|
||||||
|
var cxxlib []string
|
||||||
|
if cxx {
|
||||||
|
cxxlib = []string{"-lstdc++"}
|
||||||
|
}
|
||||||
|
ldflags := stringList(osldflags[goos], cxxlib)
|
||||||
|
b.run(p.Dir, p.ImportPath, b.gccCmd(p.Dir), "-o", soname, gccObj, ldflags)
|
||||||
|
|
||||||
|
return obj + goFile, cObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
// An actionQueue is a priority queue of actions.
|
// An actionQueue is a priority queue of actions.
|
||||||
type actionQueue []*action
|
type actionQueue []*action
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ source directories corresponding to the import paths:
|
|||||||
DIR(.exe) from go build
|
DIR(.exe) from go build
|
||||||
DIR.test(.exe) from go test -c
|
DIR.test(.exe) from go test -c
|
||||||
MAINFILE(.exe) from go build MAINFILE.go
|
MAINFILE(.exe) from go build MAINFILE.go
|
||||||
|
*.so from SWIG
|
||||||
|
|
||||||
In the list, DIR represents the final path element of the
|
In the list, DIR represents the final path element of the
|
||||||
directory, and MAINFILE is the base name of any Go source
|
directory, and MAINFILE is the base name of any Go source
|
||||||
@ -98,6 +99,7 @@ var cleanExt = map[string]bool{
|
|||||||
".8": true,
|
".8": true,
|
||||||
".a": true,
|
".a": true,
|
||||||
".o": true,
|
".o": true,
|
||||||
|
".so": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
func clean(p *Package) {
|
func clean(p *Package) {
|
||||||
@ -191,6 +193,20 @@ 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 cleanN || cleanX {
|
||||||
|
b.showcmd("", "rm -f %s", target)
|
||||||
|
}
|
||||||
|
if !cleanN {
|
||||||
|
os.Remove(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cleanR {
|
if cleanR {
|
||||||
for _, p1 := range p.imports {
|
for _, p1 := range p.imports {
|
||||||
clean(p1)
|
clean(p1)
|
||||||
|
@ -299,6 +299,8 @@ being passed to the template is:
|
|||||||
HFiles []string // .h source files
|
HFiles []string // .h source files
|
||||||
SFiles []string // .s source files
|
SFiles []string // .s source files
|
||||||
SysoFiles []string // .syso object files to add to archive
|
SysoFiles []string // .syso object files to add to archive
|
||||||
|
SwigFiles []string // .swig files
|
||||||
|
SwigCXXFiles []string // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
CgoCFLAGS []string // cgo: flags for C compiler
|
CgoCFLAGS []string // cgo: flags for C compiler
|
||||||
|
@ -47,6 +47,8 @@ being passed to the template is:
|
|||||||
HFiles []string // .h source files
|
HFiles []string // .h source files
|
||||||
SFiles []string // .s source files
|
SFiles []string // .s source files
|
||||||
SysoFiles []string // .syso object files to add to archive
|
SysoFiles []string // .syso object files to add to archive
|
||||||
|
SwigFiles []string // .swig files
|
||||||
|
SwigCXXFiles []string // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
CgoCFLAGS []string // cgo: flags for C compiler
|
CgoCFLAGS []string // cgo: flags for C compiler
|
||||||
|
@ -42,6 +42,8 @@ type Package struct {
|
|||||||
HFiles []string `json:",omitempty"` // .h source files
|
HFiles []string `json:",omitempty"` // .h source files
|
||||||
SFiles []string `json:",omitempty"` // .s source files
|
SFiles []string `json:",omitempty"` // .s source files
|
||||||
SysoFiles []string `json:",omitempty"` // .syso system object files added to package
|
SysoFiles []string `json:",omitempty"` // .syso system object files added to package
|
||||||
|
SwigFiles []string `json:",omitempty"` // .swig files
|
||||||
|
SwigCXXFiles []string `json:",omitempty"` // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
|
CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
|
||||||
@ -94,6 +96,8 @@ func (p *Package) copyBuild(pp *build.Package) {
|
|||||||
p.HFiles = pp.HFiles
|
p.HFiles = pp.HFiles
|
||||||
p.SFiles = pp.SFiles
|
p.SFiles = pp.SFiles
|
||||||
p.SysoFiles = pp.SysoFiles
|
p.SysoFiles = pp.SysoFiles
|
||||||
|
p.SwigFiles = pp.SwigFiles
|
||||||
|
p.SwigCXXFiles = pp.SwigCXXFiles
|
||||||
p.CgoCFLAGS = pp.CgoCFLAGS
|
p.CgoCFLAGS = pp.CgoCFLAGS
|
||||||
p.CgoLDFLAGS = pp.CgoLDFLAGS
|
p.CgoLDFLAGS = pp.CgoLDFLAGS
|
||||||
p.CgoPkgConfig = pp.CgoPkgConfig
|
p.CgoPkgConfig = pp.CgoPkgConfig
|
||||||
@ -408,6 +412,29 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// usesSwig returns whether the package needs to run SWIG.
|
||||||
|
func (p *Package) usesSwig() bool {
|
||||||
|
return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 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")
|
||||||
|
} 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
|
// packageList returns the list of packages in the dag rooted at roots
|
||||||
// as visited in a depth-first post-order traversal.
|
// as visited in a depth-first post-order traversal.
|
||||||
func packageList(roots []*Package) []*Package {
|
func packageList(roots []*Package) []*Package {
|
||||||
@ -459,7 +486,7 @@ func isStale(p *Package, topRoot map[string]bool) bool {
|
|||||||
// distributions of Go packages, although such binaries are
|
// distributions of Go packages, although such binaries are
|
||||||
// only useful with the specific version of the toolchain that
|
// only useful with the specific version of the toolchain that
|
||||||
// created them.
|
// created them.
|
||||||
if len(p.gofiles) == 0 {
|
if len(p.gofiles) == 0 && !p.usesSwig() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,6 +549,21 @@ func isStale(p *Package, topRoot map[string]bool) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, src := range stringList(p.SwigFiles, p.SwigCXXFiles) {
|
||||||
|
if olderThan(filepath.Join(p.Dir, src)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
soname := p.swigSoname(src)
|
||||||
|
fi, err := os.Stat(soname)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
fiSrc, err := os.Stat(src)
|
||||||
|
if err != nil || fiSrc.ModTime().After(fi.ModTime()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,6 +595,25 @@ func (b *builder) runTest(a *action) error {
|
|||||||
cmd.Stderr = &buf
|
cmd.Stderr = &buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are any local SWIG dependencies, we want to load
|
||||||
|
// the shared library from the build directory.
|
||||||
|
if a.p.usesSwig() {
|
||||||
|
env := os.Environ()
|
||||||
|
found := false
|
||||||
|
prefix := "LD_LIBRARY_PATH="
|
||||||
|
for i, v := range env {
|
||||||
|
if strings.HasPrefix(v, prefix) {
|
||||||
|
env[i] = v + ":."
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
env = append(env, "LD_LIBRARY_PATH=.")
|
||||||
|
}
|
||||||
|
cmd.Env = env
|
||||||
|
}
|
||||||
|
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
err := cmd.Start()
|
err := cmd.Start()
|
||||||
|
|
||||||
|
@ -287,6 +287,8 @@ type Package struct {
|
|||||||
HFiles []string // .h source files
|
HFiles []string // .h source files
|
||||||
SFiles []string // .s source files
|
SFiles []string // .s source files
|
||||||
SysoFiles []string // .syso system object files to add to archive
|
SysoFiles []string // .syso system object files to add to archive
|
||||||
|
SwigFiles []string // .swig files
|
||||||
|
SwigCXXFiles []string // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
CgoPkgConfig []string // Cgo pkg-config directives
|
CgoPkgConfig []string // Cgo pkg-config directives
|
||||||
@ -489,7 +491,7 @@ Found:
|
|||||||
}
|
}
|
||||||
ext := name[i:]
|
ext := name[i:]
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".go", ".c", ".s", ".h", ".S":
|
case ".go", ".c", ".s", ".h", ".S", ".swig", ".swigcxx":
|
||||||
// tentatively okay - read to make sure
|
// tentatively okay - read to make sure
|
||||||
case ".syso":
|
case ".syso":
|
||||||
// binary objects to add to package archive
|
// binary objects to add to package archive
|
||||||
@ -532,6 +534,12 @@ Found:
|
|||||||
case ".S":
|
case ".S":
|
||||||
Sfiles = append(Sfiles, name)
|
Sfiles = append(Sfiles, name)
|
||||||
continue
|
continue
|
||||||
|
case ".swig":
|
||||||
|
p.SwigFiles = append(p.SwigFiles, name)
|
||||||
|
continue
|
||||||
|
case ".swigcxx":
|
||||||
|
p.SwigCXXFiles = append(p.SwigCXXFiles, name)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
|
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
|
||||||
|
Loading…
Reference in New Issue
Block a user