Update for Go 1.2 release. Add support for linking SWIG code directly

into executable, rather than using a shared library.
This commit is contained in:
Ian Lance Taylor 2013-12-16 19:50:17 -08:00
commit 1dca0af024
32 changed files with 385 additions and 371 deletions

View file

@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.0 (in progress)
============================
2013-12-16: iant
[Go] Update for Go 1.2 release. Add support for linking
SWIG code directly into executable, rather than using a
shared library.
2013-12-13: iant
[Go] Add SWIG source file name as comments in generated
files. This can be used by Go documentation tools.

View file

@ -55,7 +55,7 @@ there is no convenient way to call C++ code. SWIG fills this gap.
<p>
There are (at least) two different Go compilers. One is the gc
compiler, normally invoked under the names 6g, 8g, or 5g. The other
compiler, normally invoked under via the go tool. The other
is the gccgo compiler, which is a frontend to the gcc compiler suite.
The interface to C/C++ code is completely different for the two Go
compilers. SWIG supports both, selected by a command line option.
@ -80,7 +80,7 @@ code for gccgo, you should also use the <tt>-gccgo</tt> option.
<p>
These are the command line options for SWIG's GO module. They can
These are the command line options for SWIG's Go module. They can
also be seen by using:
</p>
@ -108,7 +108,7 @@ swig -go -help
<tr>
<td>-gccgo</td>
<td>Generate code for gccgo. The default is to generate code for
6g/8g/5g.</td>
the gc compiler.</td>
</tr>
<tr>
@ -117,13 +117,21 @@ swig -go -help
package name is the SWIG module name.</td>
</tr>
<tr>
<td>-use-shlib</td>
<td>Tell SWIG to emit code that uses a shared library. This is only
meaningful for the gc compiler, which needs to know at compile time
whether a shared library will be used.</td>
</tr>
<tr>
<td>-soname %lt;name%gt;</td>
<td>Set the runtime name of the shared library that the dynamic linker
should include at runtime. The default is the package name with
".so" appended. This is only used when generating code for
6g/8g/5g; when using gccgo, the equivalent name will be taken from
the <code>-soname</code> option passed to the linker.</td>
the gc compiler; when using gccgo, the equivalent name will be taken from
the <code>-soname</code> option passed to the linker. Using this
option implies the -use-shlib option.</td>
</tr>
<tr>
@ -165,25 +173,56 @@ may be helpful to include it in your code, compiled with the usual C
or C++ compiler.
<li>
If using the gc compiler, MODULE_gc.c will contain C code which should
be compiled with the C compiler distributed as part of the gc compiler: 6c, 8c,
or 5c. It should then be combined with the compiled MODULE.go using
gopack. This file will not be generated when using gccgo.
be compiled with the C compiler distributed as part of the gc
compiler. It should then be combined with the compiled MODULE.go
using gopack. This file will not be generated when using gccgo.
</ul>
<p>
A typical command sequence would look like this:
Most Go programs are built using the go tool. The go tool has limited
support for SWIG. To use it, put your SWIG interface into a file with
the extension .swig, or, if you are wrapping C++ code, .swigcxx. Put
that file in a GOPATH/src directory as usual for Go sources. Put
other interface code in the same directory with extensions of .c and
.cxx. The go build command and go install commands will automatically
run SWIG for you and will build the interface code.
</p>
<p>
You can also use SWIG directly yourself. When using the gc compiler
version 1.2 or later, or when using gccgo, the code generated by SWIG
can be linked directly into the Go program. A typical command
sequence when using the gc compiler would look like this:
</p>
<div class="code"><pre>
% swig -go example.i
% gcc -c code.c # The C library being wrapped.
% gcc -c example_wrap.c
% go tool 6g example.go
% go tool 6c example_gc.c
% go tool pack grc example.a example.6 example_gc.6 code.o example_wrap.o
% go tool 6g main.go
% go tool 6l main.6
</pre></div>
<p>
You can also put the wrapped code into a shared library, and when
using the gc compiler before version 1.2 this is the only supported
option. A typical command sequence for this approach would look like
this:
</p>
<div class="code"><pre>
% swig -go -use-shlib example.i
% gcc -c -fpic example.c
% gcc -c -fpic example_wrap.c
% gcc -shared example.o example_wrap.o -o example.so
% 6g example.go
% 6c example_gc.c
% gopack grc example.a example.6 example_gc.6
% 6g main.go # your code, not generated by SWIG
% 6l main.6
% go tool 6g example.go
% go tool 6c example_gc.c
% go tool pack grc example.a example.6 example_gc.6
% go tool 6g main.go # your code, not generated by SWIG
% go tool 6l main.6
</pre></div>
<H2><a name="Go_basic_tour"></a>22.3 A tour of basic C/C++ wrapping</H2>

View file

@ -1555,6 +1555,7 @@ r_clean:
GO = @GO@
GOGCC = @GOGCC@
GO1 = @GO1@
GO12 = @GO12@
GOC = @GOC@
GOOPT = @GOOPT@
GOVERSIONOPTION = @GOVERSIONOPTION@
@ -1576,41 +1577,76 @@ GOGCOBJS = $(GOSRCS:.go=.$(GOOBJEXT))
GOGCCOBJS = $(GOSRCS:.go=.@OBJEXT@)
# ----------------------------------------------------------------
# Build a Go dynamically loadable module (C)
# Build a Go module (C)
# ----------------------------------------------------------------
go: $(SRCS)
$(SWIG) -go $(GOOPT) $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH)
$(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES)
$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
if $(GO12) || $(GOGCC); then \
$(CC) -g -c $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES); \
else \
$(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES); \
$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO); \
fi
$(COMPILETOOL) $(GO) $(GOCOMPILEARG) -I . $(GOSRCS)
if ! $(GOGCC) ; then \
$(COMPILETOOL) $(GOTOOL) $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \
$(COMPILETOOL) $(GOPACK) grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
$(COMPILETOOL) $(GOTOOL) $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS); \
rm -f $(GOPACKAGE); \
if $(GO12); then \
$(COMPILETOOL) $(GOPACK) grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)) $(OBJS) $(IOBJS); \
else \
$(COMPILETOOL) $(GOPACK) grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
fi; \
fi
# ----------------------------------------------------------------
# Build a Go dynamically loadable module (C++)
# Build a Go module (C++)
# ----------------------------------------------------------------
go_cpp: $(SRCS)
$(SWIG) -go -c++ $(GOOPT) $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH)
$(CXX) -g -c $(CCSHARED) $(CXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES)
$(CXXSHARED) $(CXXFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
if $(GO12) || $(GOGCC); then \
$(CXX) -g -c $(CXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES); \
else \
$(CXX) -g -c $(CCSHARED) $(CXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES); \
$(CXXSHARED) $(CXXFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO); \
fi
$(COMPILETOOL) $(GO) $(GOCOMPILEARG) -I . $(GOSRCS)
if ! $(GOGCC) ; then \
$(COMPILETOOL) $(GOTOOL) $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \
$(COMPILETOOL) $(GOPACK) grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
$(COMPILETOOL) $(GOTOOL) $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS); \
rm -f $(GOPACKAGE); \
if $(GO12); then \
$(COMPILETOOL) $(GOPACK) grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)) $(OBJS) $(IOBJS); \
else \
$(COMPILETOOL) $(GOPACK) grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
fi; \
fi
# -----------------------------------------------------------------
# Running a Go example
# Running a Go example (C)
# -----------------------------------------------------------------
go_run: runme.go
$(GO) $(GOCOMPILEARG) runme.go
if $(GOGCC) ; then \
$(COMPILETOOL) $(GO) -o runme runme.@OBJEXT@ $(GOGCCOBJS) $(LIBPREFIX)$(TARGET)$(SO); \
$(COMPILETOOL) $(GO) -o runme runme.@OBJEXT@ $(GOGCCOBJS) $(OBJS) $(IOBJS); \
elif $(GO12); then \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -linkmode external -extld $(CC) -extldflags "$(CFLAGS)" -o runme runme.$(GOOBJEXT); \
else \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o runme runme.$(GOOBJEXT); \
fi
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) ./runme $(RUNPIPE)
# -----------------------------------------------------------------
# Running a Go example (C++)
# -----------------------------------------------------------------
go_run_cpp: runme.go
$(GO) $(GOCOMPILEARG) runme.go
if $(GOGCC) ; then \
$(COMPILETOOL) $(GO) -o runme runme.@OBJEXT@ $(GOGCCOBJS) $(OBJS) $(IOBJS) -lstdc++; \
elif $(GO12); then \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -linkmode external -extld $(CXX) -extldflags "$(CXXFLAGS)" -o runme runme.$(GOOBJEXT); \
else \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o runme runme.$(GOOBJEXT); \
fi

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
CXXSRCS = callback.cxx
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run_cpp
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
CXXSRCS = class.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run_cpp
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -6,7 +6,7 @@ INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
CXXSRCS = enum.cxx
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run_cpp
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
CXXSRCS = extend.cxx
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run_cpp
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
SRCS = funcptr.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
SRCS = multimap.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
SRCS = pointer.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
CXXSRCS = reference.cxx
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run_cpp
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -1,11 +1,11 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
SRCS = simple.c
TARGET = example
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \

View file

@ -6,7 +6,7 @@ INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run_cpp
build:
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \

View file

@ -1,12 +1,12 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
SRCS = variables.c
TARGET = example
INTERFACE = example.i
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
build:
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \

View file

@ -6,6 +6,7 @@ LANGUAGE = go
GO = @GO@
GOGCC = @GOGCC@
GO1 = @GO1@
GO12 = @GO12@
GOC = @GOC@
SCRIPTSUFFIX = _runme.go
@ -30,7 +31,7 @@ include $(srcdir)/../common.mk
%.cpptest:
$(setup)
+$(swig_and_compile_cpp)
$(run_testcase)
$(run_testcase_cpp)
%.ctest:
$(setup)
@ -58,7 +59,22 @@ run_testcase = \
if test -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
$(COMPILETOOL) $(GO) $(GOCOMPILEARG) -I . $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
if $(GOGCC) ; then \
$(COMPILETOOL) $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ $*.@OBJEXT@ $*$(SO); \
$(COMPILETOOL) $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ $*.@OBJEXT@ $*_wrap.@OBJEXT@; \
elif $(GO12); then \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -linkmode external -extld $(CC) -extldflags "$(CFLAGS)" -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
else \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
fi && \
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) ./$*_runme; \
fi
run_testcase_cpp = \
if test -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
$(COMPILETOOL) $(GO) $(GOCOMPILEARG) -I . $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
if $(GOGCC) ; then \
$(COMPILETOOL) $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ $*.@OBJEXT@ $*_wrap.@OBJEXT@ -lstdc++; \
elif $(GO12); then \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -linkmode external -extld $(CXX) -extldflags "$(CXXFLAGS)" -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
else \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
fi && \
@ -70,7 +86,9 @@ run_multi_testcase = \
$(COMPILETOOL) $(GO) $(GOCOMPILEARG) -I . $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
if $(GOGCC) ; then \
files=`cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list`; \
$(COMPILETOOL) $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ `for f in $$files; do echo $$f.@OBJEXT@ $$f$(SO); done`; \
$(COMPILETOOL) $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ `for f in $$files; do echo $$f.@OBJEXT@ $${f}_wrap.@OBJEXT@; done` -lstdc++; \
elif $(GO12); then \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -L . -linkmode external -extld $(CXX) -extldflags "$(CXXFLAGS)" -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
else \
$(COMPILETOOL) $(GOTOOL) $(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
fi && \

View file

@ -1,62 +0,0 @@
package main
import "./director_abstract"
type MyFoo struct{}
func (p *MyFoo) Ping() string {
return "MyFoo::ping()"
}
func f1() {
a := director_abstract.NewDirectorFoo(&MyFoo{})
if a.Ping() != "MyFoo::ping()" {
panic(a.Ping())
}
if a.Pong() != "Foo::pong();MyFoo::ping()" {
panic(a.Pong())
}
}
type MyExample1 struct{}
func (p *MyExample1) Color(r, g, b byte) int {
return int(r)
}
type MyExample2 struct{}
func (p *MyExample2) Color(r, g, b byte) int {
return int(g)
}
type MyExample3 struct{}
func (p *MyExample3) Color(r, g, b byte) int {
return int(b)
}
func f2() {
me1 := director_abstract.NewDirectorExample1(&MyExample1{})
if director_abstract.Example1Get_color(me1, 1, 2, 3) != 1 {
println(director_abstract.Example1Get_color(me1, 1, 2, 3))
panic(0)
}
me2 := director_abstract.NewDirectorExample2(&MyExample2{}, 1, 2)
if director_abstract.Example2Get_color(me2, 1, 2, 3) != 2 {
panic(0)
}
me3 := director_abstract.NewDirectorExample3_i(&MyExample3{})
if director_abstract.Example3_iGet_color(me3, 1, 2, 3) != 3 {
panic(0)
}
}
func main() {
f1()
f2()
}

View file

@ -1,28 +0,0 @@
package main
import . "./director_thread"
type Derived struct {
abi Foo
} // From Foo
func (p *Derived) Do_foo() {
p.abi.SetVal(p.abi.GetVal() - 1)
}
func main() {
// FIXME: This test fails until we fix callbacks from a
// different thread.
return
p := &Derived{nil}
d := NewDirectorFoo(p)
p.abi = d
d.Run()
if d.GetVal() >= 0 {
panic(d.GetVal())
}
d.Stop()
}

View file

@ -1,29 +0,0 @@
package main
import "template_typedef_cplx2"
import "template_typedef_import"
func main() {
// this is OK
s := template_typedef_import.NewSin()
s.Get_base_value()
s.Get_value()
s.Get_arith_value()
template_typedef_import.My_func_r(s)
template_typedef_cplx2.Make_Multiplies_double_double_double_double(s, s)
z := template_typedef_import.NewCSin()
z.Get_base_value()
z.Get_value()
z.Get_arith_value()
template_typedef_import.My_func_c(z)
template_typedef_cplx2.Make_Multiplies_complex_complex_complex_complex(z, z)
// Here we fail
d := template_typedef_cplx2.Make_Identity_double()
template_typedef_import.My_func_r(d)
c := template_typedef_cplx2.Make_Identity_complex()
template_typedef_import.My_func_c(c)
}

View file

@ -7,7 +7,8 @@
%{
typedef struct SWIGCDATA {
char *data;
int len;
intgo len;
intgo cap;
} SWIGCDATA;
%}
@ -15,7 +16,8 @@ typedef struct SWIGCDATA {
%typemap(out) SWIGCDATA %{
$result.data = (char*)_swig_goallocate($1.len);
memcpy($result.data, $1.data, $1.len);
$result.len = (int)$1.len;
$result.len = (intgo)$1.len;
$result.cap = $result.len;
%}
/* -----------------------------------------------------------------------------

View file

@ -22,6 +22,8 @@ class GO:public Language {
bool gccgo_flag;
// Prefix to use with gccgo.
String *go_prefix;
// Whether to use a shared library.
bool use_shlib;
// Name of shared library to import.
String *soname;
// Size in bits of the C type "long".
@ -86,6 +88,7 @@ public:
module(NULL),
gccgo_flag(false),
go_prefix(NULL),
use_shlib(false),
soname(NULL),
long_type_size(32),
intgo_type_size(0),
@ -153,6 +156,9 @@ private:
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-use-shlib") == 0) {
Swig_mark_arg(i);
use_shlib = true;
} else if (strcmp(argv[i], "-soname") == 0) {
if (argv[i + 1]) {
soname = NewString(argv[i + 1]);
@ -274,7 +280,7 @@ private:
if (!package) {
package = Copy(module);
}
if (!soname) {
if (!soname && use_shlib) {
soname = Copy(package);
Append(soname, ".so");
}
@ -387,7 +393,7 @@ private:
Swig_banner(f_go_begin);
Printf(f_go_begin, "\n// source: %s\n", swig_filename);
if (!gccgo_flag) {
if (!gccgo_flag && soname) {
Swig_banner(f_gc_begin);
Printf(f_gc_begin, "\n/* source: %s */\n\n", swig_filename);
Printf(f_gc_begin, "\n/* This file should be compiled with 6c/8c. */\n");
@ -1084,6 +1090,7 @@ private:
Wrapper *f = NewWrapper();
Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL);
Printv(f->def, "#pragma cgo_import_static ", wname, "\n", NULL);
Printv(f->def, "extern void (*", wname, ")(void*);\n", NULL);
Printv(f->def, "static void (*x", wname, ")(void*) = ", wname, ";\n", NULL);
Printv(f->def, "\n", NULL);
@ -2825,6 +2832,7 @@ private:
Printv(f_c_directors, " crosscall2(", wname, ", &a, (int) sizeof a);\n", NULL);
Printv(f_gc_wrappers, "#pragma dynexport ", wname, " ", wname, "\n", NULL);
Printv(f_gc_wrappers, "#pragma cgo_export_static ", wname, " ", wname, "\n", NULL);
Printv(f_gc_wrappers, "extern void \xc2\xb7", go_name, "();\n", NULL);
Printv(f_gc_wrappers, "void\n", NULL);
Printv(f_gc_wrappers, wname, "(void *a, int32 n)\n", NULL);
@ -2918,17 +2926,20 @@ private:
return r;
}
String *go_upcall = NewString("Director");
Append(go_upcall, cn);
Append(go_upcall, go_name);
r = makeDispatchFunction(on, go_upcall, director_struct_name, is_static, director_struct_name, true);
if (r != SWIG_OK) {
return r;
if (!GetFlag(n, "abstract")) {
String *go_upcall = NewString("Director");
Append(go_upcall, cn);
Append(go_upcall, go_name);
r = makeDispatchFunction(on, go_upcall, director_struct_name, is_static, director_struct_name, true);
if (r != SWIG_OK) {
return r;
}
Delete(go_upcall);
}
Delete(cn);
Delete(go_name);
Delete(director_struct_name);
Delete(go_upcall);
Delete(go_name);
Delete(cn);
}
}
Setattr(class_methods, name, NewString(""));
@ -3010,6 +3021,11 @@ private:
Append(upcall_name, go_name);
String *upcall_wname = Swig_name_wrapper(upcall_name);
if (overname) {
Append(upcall_wname, overname);
}
String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
String *go_with_over_name = Copy(go_name);
if (overname) {
@ -3052,40 +3068,36 @@ private:
Printv(f_go_wrappers, "\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
// Declare the upcall function, which calls the method on the
// parent class.
if (!GetFlag(n, "abstract")) {
// Declare the upcall function, which calls the method on the
// parent class.
if (overname) {
Append(upcall_wname, overname);
if (gccgo_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", upcall_gc_name, "(", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
String *tm = goWrapperType(p, Getattr(p, "type"), false);
Printv(f_go_wrappers, ", ", tm, NULL);
Delete(tm);
p = nextParm(p);
}
Printv(f_go_wrappers, ")", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goWrapperType(n, result, true);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
Printv(f_go_wrappers, "\n", NULL);
}
String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
if (gccgo_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", upcall_gc_name, "(", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
String *tm = goWrapperType(p, Getattr(p, "type"), false);
Printv(f_go_wrappers, ", ", tm, NULL);
Delete(tm);
p = nextParm(p);
}
Printv(f_go_wrappers, ")", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goWrapperType(n, result, true);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
Printv(f_go_wrappers, "\n", NULL);
// Define the method on the director class in Go.
Printv(f_go_wrappers, "func (swig_p *", director_struct_name, ") ", go_with_over_name, "(", NULL);
@ -3136,181 +3148,189 @@ private:
}
Printv(f_go_wrappers, "\t}\n", NULL);
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(swig_p.", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
if (GetFlag(n, "abstract")) {
Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL);
} else {
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
p = nextParm(p);
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(swig_p.", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
}
p = nextParm(p);
}
Printv(f_go_wrappers, ")\n", NULL);
}
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
// Define a method in the C++ director class that the C++ upcall
// function can call. This permits an upcall to a protected
// method.
String *upcall_method_name = NewString("_swig_upcall_");
Append(upcall_method_name, name);
if (overname) {
Append(upcall_method_name, overname);
}
SwigType *rtype = Getattr(n, "classDirectorMethods:type");
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0, 0);
Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
Delete(upcall_decl);
Printv(f_c_directors_h, " ", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_c_directors_h, "return ", NULL);
}
String *super_call = Swig_method_call(super, parms);
Printv(f_c_directors_h, super_call, ";\n", NULL);
Delete(super_call);
Printv(f_c_directors_h, " }\n", NULL);
// Define the C++ function that the Go function calls.
SwigType *first_type = NULL;
Parm *first_parm = parms;
if (!is_static) {
first_type = NewString("SwigDirector_");
Append(first_type, class_name);
SwigType_add_pointer(first_type);
first_parm = NewParm(first_type, "p", n);
set_nextSibling(first_parm, parms);
}
Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
Setattr(n, "wrap:name", upcall_wname);
String *action = NewString("");
if (SwigType_type(result) != T_VOID) {
Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
if (SwigType_isreference(result)) {
Printv(action, "&", NULL);
if (!GetFlag(n, "abstract")) {
String *upcall_method_name = NewString("_swig_upcall_");
Append(upcall_method_name, name);
if (overname) {
Append(upcall_method_name, overname);
}
}
Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
SwigType *rtype = Getattr(n, "classDirectorMethods:type");
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0, 0);
Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
Delete(upcall_decl);
p = parms;
int i = 0;
while (p != NULL) {
if (SwigType_type(Getattr(p, "type")) != T_VOID) {
String *pname = Swig_cparm_name(NULL, i + 1);
if (i > 0) {
Printv(action, ", ", NULL);
Printv(f_c_directors_h, " ", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_c_directors_h, "return ", NULL);
}
String *super_call = Swig_method_call(super, parms);
Printv(f_c_directors_h, super_call, ";\n", NULL);
Delete(super_call);
Printv(f_c_directors_h, " }\n", NULL);
// Define the C++ function that the Go function calls.
SwigType *first_type = NULL;
Parm *first_parm = parms;
if (!is_static) {
first_type = NewString("SwigDirector_");
Append(first_type, class_name);
SwigType_add_pointer(first_type);
first_parm = NewParm(first_type, "p", n);
set_nextSibling(first_parm, parms);
}
Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
Setattr(n, "wrap:name", upcall_wname);
String *action = NewString("");
if (SwigType_type(result) != T_VOID) {
Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
if (SwigType_isreference(result)) {
Printv(action, "&", NULL);
}
}
Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
// A parameter whose type is a reference is converted into a
// pointer type by gcCTypeForGoValue. We are calling a
// function which expects a reference so we need to convert
// back.
if (SwigType_isreference(Getattr(p, "type"))) {
Printv(action, "*", NULL);
p = parms;
int i = 0;
while (p != NULL) {
if (SwigType_type(Getattr(p, "type")) != T_VOID) {
String *pname = Swig_cparm_name(NULL, i + 1);
if (i > 0) {
Printv(action, ", ", NULL);
}
// A parameter whose type is a reference is converted into a
// pointer type by gcCTypeForGoValue. We are calling a
// function which expects a reference so we need to convert
// back.
if (SwigType_isreference(Getattr(p, "type"))) {
Printv(action, "*", NULL);
}
Printv(action, pname, NULL);
Delete(pname);
i++;
}
Printv(action, pname, NULL);
Delete(pname);
i++;
p = nextSibling(p);
}
p = nextSibling(p);
}
Printv(action, ");", NULL);
Setattr(n, "wrap:action", action);
Printv(action, ");", NULL);
Setattr(n, "wrap:action", action);
if (!gccgo_flag) {
// Write the upcall wrapper function. This is compiled by gc
// and calls the C++ function.
int r = gcFunctionWrapper(n, upcall_name, upcall_name, overname, upcall_wname, first_parm, result, is_static, true);
if (r != SWIG_OK) {
return r;
if (!gccgo_flag) {
// Write the upcall wrapper function. This is compiled by gc
// and calls the C++ function.
int r = gcFunctionWrapper(n, upcall_name, upcall_name, overname, upcall_wname, first_parm, result, is_static, true);
if (r != SWIG_OK) {
return r;
}
r = gccFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
}
} else {
int r = gccgoFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
}
}
r = gccFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
Delete(first_type);
if (first_parm != parms) {
Delete(first_parm);
}
} else {
int r = gccgoFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
Swig_restore(n);
Delete(upcall_method_name);
// Define a function that uses the Go director type that other
// methods in the Go type can call to get parent methods.
Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
String *tm = goType(p, Getattr(p, "type"));
Printv(f_go_wrappers, tm, NULL);
Delete(tm);
p = nextParm(p);
}
}
Delete(first_type);
if (first_parm != parms) {
Delete(first_parm);
}
Printv(f_go_wrappers, ")", NULL);
Swig_restore(n);
// Define a function which uses the Go director type that other
// methods in the Go type can call to get parent methods.
Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
String *tm = goType(p, Getattr(p, "type"));
Printv(f_go_wrappers, tm, NULL);
Delete(tm);
p = nextParm(p);
}
Printv(f_go_wrappers, ")", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goType(n, result);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
Printv(f_go_wrappers, " {\n", NULL);
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(p.(*", director_struct_name, ").", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goType(n, result);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
p = nextParm(p);
}
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
Printv(f_go_wrappers, " {\n", NULL);
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(p.(*", director_struct_name, ").", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
}
p = nextParm(p);
}
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
}
// The Go function which invokes the method. This is called
// from by the C++ method on the director class.
@ -3390,17 +3410,16 @@ private:
}
Printv(f_go_wrappers, "\n", NULL);
Delete(upcall_gc_name);
}
Printv(f_go_wrappers, "}\n\n", NULL);
Delete(result_wrapper);
// Build the C++ functions.
Delete(upcall_wname);
Delete(upcall_gc_name);
// Build the C++ functions.
if (!gccgo_flag) {
Printv(f_c_directors, "extern \"C\" void ", callback_wname, "(void*, int);\n", NULL);
@ -3437,7 +3456,6 @@ private:
Printv(f_c_directors, " __asm__(\"", go_prefix, ".", package, ".", callback_name, "\");\n", NULL);
}
Delete(upcall_method_name);
Delete(go_with_over_name);
}
@ -3544,6 +3562,7 @@ private:
// The C wrapper code which calls the Go function.
Printv(f_gc_wrappers, "#pragma dynexport ", callback_wname, " ", callback_wname, "\n", NULL);
Printv(f_gc_wrappers, "#pragma cgo_export_static ", callback_wname, " ", callback_wname, "\n", NULL);
Printv(f_gc_wrappers, "extern void \xc2\xb7", callback_name, "();\n", NULL);
Printv(f_gc_wrappers, "void\n", NULL);
Printv(f_gc_wrappers, callback_wname, "(void *a, int32 n)\n", NULL);
@ -4909,5 +4928,6 @@ Go Options (available with -go)\n\
-longsize <s> - Set size of C/C++ long type--32 or 64 bits\n\
-intgosize <s> - Set size of Go int type--32 or 64 bits\n\
-package <name> - Set name of the Go package to <name>\n\
-use-shlib - Force use of a shared library\n\
-soname <name> - Set shared library holding C/C++ code to <name>\n\
\n";

View file

@ -1996,6 +1996,7 @@ if test x"${GOBIN}" = xno -o x"${with_alllang}" = xno ; then
GO=
GOC=
GO1=false
GO12=false
GOGCC=false
GOOPT=
GOVERSIONOPTION=
@ -2009,6 +2010,7 @@ else
GOGCC=false
GO1=false
GO12=false
GOOPT=
GOVERSIONOPTION=
if test -n "$GO" ; then
@ -2046,6 +2048,15 @@ else
fi
;;
esac
case $go_version in
go1.0* | go1.1*)
GO12=false
GOOPT="$GOOPT -use-shlib"
;;
*)
GO12=true
;;
esac
else
GOC=`echo $GO | sed -e 's/g/c/'`
GOVERSIONOPTION=-V
@ -2059,6 +2070,7 @@ else
AC_MSG_RESULT([no])
fi
GOOPT="-intgosize 32"
GO12=false
fi
fi
fi
@ -2067,6 +2079,7 @@ AC_SUBST(GOGCC)
AC_SUBST(GO)
AC_SUBST(GOC)
AC_SUBST(GO1)
AC_SUBST(GO12)
AC_SUBST(GOOPT)
AC_SUBST(GOVERSIONOPTION)