diff --git a/misc/swig/callback/Makefile b/misc/swig/callback/Makefile new file mode 100644 index 0000000000..fde0d107bb --- /dev/null +++ b/misc/swig/callback/Makefile @@ -0,0 +1,17 @@ +# 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) $*.go + $(LD) $(SWIG_RPATH) -o $@ $*.$O diff --git a/misc/swig/callback/callback.h b/misc/swig/callback/callback.h new file mode 100644 index 0000000000..80232a8b3d --- /dev/null +++ b/misc/swig/callback/callback.h @@ -0,0 +1,24 @@ +// 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. + +class Callback { +public: + virtual ~Callback() { } + virtual std::string run() { return "Callback::run"; } +}; + +class Caller { +private: + Callback *callback_; +public: + Caller(): callback_(0) { } + ~Caller() { delCallback(); } + void delCallback() { delete callback_; callback_ = 0; } + void setCallback(Callback *cb) { delCallback(); callback_ = cb; } + std::string call() { + if (callback_ != 0) + return callback_->run(); + return ""; + } +}; diff --git a/misc/swig/callback/callback.swigcxx b/misc/swig/callback/callback.swigcxx new file mode 100644 index 0000000000..0c97ef1016 --- /dev/null +++ b/misc/swig/callback/callback.swigcxx @@ -0,0 +1,18 @@ +/* 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. */ + +/* An example of writing a C++ virtual function in Go. */ + +%module(directors="1") callback + +%{ +#include +#include "callback.h" +%} + +%include "std_string.i" + +%feature("director"); + +%include "callback.h" diff --git a/misc/swig/callback/run b/misc/swig/callback/run new file mode 100755 index 0000000000..de150ed05f Binary files /dev/null and b/misc/swig/callback/run differ diff --git a/misc/swig/callback/run.go b/misc/swig/callback/run.go new file mode 100644 index 0000000000..a76e636cb5 --- /dev/null +++ b/misc/swig/callback/run.go @@ -0,0 +1,39 @@ +// 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/callback" + "fmt" +) + +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) +} diff --git a/misc/swig/stdio/Makefile b/misc/swig/stdio/Makefile new file mode 100644 index 0000000000..e7d330587c --- /dev/null +++ b/misc/swig/stdio/Makefile @@ -0,0 +1,17 @@ +# 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/file +SWIGFILES=\ + file.swig + +CLEANFILES+=hello + +include ../../../src/Make.pkg + +%: install %.go + $(GC) $*.go + $(LD) $(SWIG_RPATH) -o $@ $*.$O diff --git a/misc/swig/stdio/file.swig b/misc/swig/stdio/file.swig new file mode 100644 index 0000000000..57c623f8f7 --- /dev/null +++ b/misc/swig/stdio/file.swig @@ -0,0 +1,11 @@ +/* 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. */ + +/* A trivial example of wrapping a C library using SWIG. */ + +%{ +#include +%} + +int puts(const char *); diff --git a/misc/swig/stdio/hello b/misc/swig/stdio/hello new file mode 100755 index 0000000000..10c55631f8 Binary files /dev/null and b/misc/swig/stdio/hello differ diff --git a/misc/swig/stdio/hello.go b/misc/swig/stdio/hello.go new file mode 100644 index 0000000000..eec2942786 --- /dev/null +++ b/misc/swig/stdio/hello.go @@ -0,0 +1,11 @@ +// 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") +} diff --git a/src/Make.pkg b/src/Make.pkg index 3d616ca999..dcdb09132e 100644 --- a/src/Make.pkg +++ b/src/Make.pkg @@ -41,6 +41,14 @@ CGO_OFILES+=$(patsubst %.go,%.cgo2.o,$(CGOFILES)) _cgo_export.o OFILES+=_cgo_defun.$O _cgo_import.$O $(CGO_OFILES) endif +ifdef SWIGFILES +GOFILES+=$(patsubst %.swig,_obj/%.go,$(patsubst %.swigcxx,%.swig,$(SWIGFILES))) +OFILES+=$(patsubst %.swig,_obj/%_gc.$O,$(patsubst %.swigcxx,%.swig,$(SWIGFILES))) +SWIG_PREFIX=$(subst /,-,$(TARG)) +SWIG_SOS+=$(patsubst %.swig,_obj/$(SWIG_PREFIX)-%.so,$(patsubst %.swigcxx,%.swig,$(SWIGFILES))) +INSTALLFILES+=$(patsubst %.swig,$(pkgdir)/swig/$(SWIG_PREFIX)-%.so,$(patsubst %.swigcxx,%.swig,$(SWIGFILES))) +endif + PREREQ+=$(patsubst %,%.make,$(DEPS)) coverage: @@ -109,6 +117,16 @@ dir: # _obj/x.cgo2.c - C implementations compiled with gcc to create a dynamic library # +ifneq ($(CGOFILES)$(SWIGFILES),) +# Have to run gcc with the right size argument on hybrid 32/64 machines. +_CGO_CFLAGS_386=-m32 +_CGO_CFLAGS_amd64=-m64 +_CGO_LDFLAGS_freebsd=-shared -lpthread -lm +_CGO_LDFLAGS_linux=-shared -lpthread -lm +_CGO_LDFLAGS_darwin=-dynamiclib -Wl,-undefined,dynamic_lookup +_CGO_LDFLAGS_windows=-shared -lm -mthreads +endif + ifdef CGOFILES _obj/_cgo_run: $(CGOFILES) @mkdir -p _obj @@ -158,14 +176,6 @@ _obj/_cgo_import.c: _cgo1_.o # added _cgo_defun.$O to $OFILES, and added the installed copy of # package_x.so (built from x.cgo2.c) to $(INSTALLFILES). -# Have to run gcc with the right size argument on hybrid 32/64 machines. -_CGO_CFLAGS_386=-m32 -_CGO_CFLAGS_amd64=-m64 -_CGO_LDFLAGS_freebsd=-shared -lpthread -lm -_CGO_LDFLAGS_linux=-shared -lpthread -lm -_CGO_LDFLAGS_darwin=-dynamiclib -Wl,-undefined,dynamic_lookup -_CGO_LDFLAGS_windows=-shared -lm -mthreads - # Have to compile the runtime header. RUNTIME_CFLAGS=-I$(pkgdir) @@ -173,6 +183,54 @@ RUNTIME_CFLAGS=-I$(pkgdir) _cgo_defun.$O: _obj/_cgo_defun.c $(CC) $(CFLAGS) $(RUNTIME_CFLAGS) -I . -o "$@" _obj/_cgo_defun.c +# To use swig in a Go package, add a line +# +# SWIGFILES=x.swig +# +# to the main Makefile. This signals that SWIG should process the +#.swig file when building the package. +# +# To wrap C code, use an extension of .swig. To wrap C++ code, use an +# extension of .swigcxx. +# +# SWIGFILES=myclib.swig mycxxlib.swigcxx + +ifdef SWIGFILES +_obj/%._swig_run _obj/%.go _obj/%_gc.c _obj/%_wrap.c: %.swig + @mkdir -p _obj + swig -go -module $* -soname $(SWIG_PREFIX)-$*.so -o _obj/$*_wrap.c -outdir _obj $< + +_obj/%._swig_run _obj/%.go _obj/%_gc.c _obj/%_wrap.cxx: %.swigcxx + @mkdir -p _obj + swig -go -c++ -module $* -soname $(SWIG_PREFIX)-$*.so -o _obj/$*_wrap.cxx -outdir _obj $< + +_obj/%_gc.$O: _obj/%_gc.c + $(CC) $(CFLAGS) -I . -I$(pkgdir) -o "$@" _obj/$*_gc.c + +_obj/%_wrap.o: _obj/%_wrap.c + $(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -I . -g -fPIC -O2 -o $@ -c $^ $(SWIG_CFLAGS) + +HOST_CXX=g++ + +_obj/%_wrapcxx.o: _obj/%_wrap.cxx + $(HOST_CXX) $(_CGO_CFLAGS_$(GOARCH)) -I . -g -fPIC -O2 -o $@ -c $^ $(SWIG_CXXFLAGS) + +_obj/$(SWIG_PREFIX)-%.so: _obj/%_wrap.o + $(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -o $@ $^ $(SWIG_LDFLAGS) $(_CGO_LDFLAGS_$(GOOS)) $(_SWIG_LDFLAGS_$(GOOS)) + +_obj/$(SWIG_PREFIX)-%.so: _obj/%_wrapcxx.o + $(HOST_CXX) $(_CGO_CFLAGS_$(GOARCH)) -o $@ $^ $(SWIG_LDFLAGS) $(_CGO_LDFLAGS_$(GOOS)) $(_SWIG_LDFLAGS_$(GOOS)) + +$(pkgdir)/swig/$(SWIG_PREFIX)-%.so: _obj/$(SWIG_PREFIX)-%.so + @test -d $(QUOTED_GOROOT)/pkg && mkdir -p $(pkgdir)/swig + cp $< "$@" + +all: $(SWIG_SOS) + +SWIG_RPATH=-r $(pkgdir)/swig + +endif + # Generic build rules. # These come last so that the rules above can override them # for more specific file names.