FAQ
Hello,

I am trying to wrap a library with a C++ interface and access it from
golang. The usage is simple, I just need to instantiate a class and call
one or two methods on it. At this point, I don't even care if the
resulting API exposed to golang is a simple C function, but my attempts at
that didn't work, so I am trying swig.
I did follow one of the earlier discussions here, but I am still lost (
https://groups.google.com/forum/#!topic/golang-nuts/ZkGL6hKBfZM/discussion )

The problem, at least the first one I encountered, is that I can't seem to
figure out how to pass the include directive (it takes effect for some of
the gcc invocations, but not for the one that shows error, quoted towards
the end of the email).

My environment is listed below.
$ go version
go version go1.2.1 linux/amd64

$ swig -version
SWIG Version 3.0.0
Compiled with g++ [x86_64-unknown-linux-gnu]
Configured options: +pcre

$ cat device_atlas.go
package main

// #cgo CPPFLAGS: -I/home/harry/DA_cpp_1.5.3.1/include/
import "C"
// no code for now

$ cat device_atlas.swigcxx
%module da
%{
#include <mtld/devatlas.h>
%}

#include <mtld/devatlas.h>

$ go build -x
WORK=/tmp/go-build957195266
mkdir -p $WORK/us.xmpl.hkb/da/_obj/
mkdir -p $WORK/us.xmpl.hkb/da/_obj/exe/
cd /home/harry/go_work/src/us.xmpl.hkb/da
/usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/us.xmpl.hkb/da/_obj/
-- -I/home/harry/DA_cpp_1.5.3.1/include/ -I $WORK/us.xmpl.hkb/da/_obj/
device_atlas.go
/usr/local/go/pkg/tool/linux_amd64/6c -F -V -w -I
$WORK/us.xmpl.hkb/da/_obj/ -I /usr/local/go/pkg/linux_amd64 -o
$WORK/us.xmpl.hkb/da/_obj/_cgo_defun.6 -D GOOS_linux -D GOARCH_amd64
$WORK/us.xmpl.hkb/da/_obj/_cgo_defun.c
gcc -I . -g -O2 -fPIC -m64 -pthread -print-libgcc-file-name
gcc -I . -g -O2 -fPIC -m64 -pthread -I/home/harry/DA_cpp_1.5.3.1/include/
-I $WORK/us.xmpl.hkb/da/_obj/ -o $WORK/us.xmpl.hkb/da/_obj/_cgo_main.o -c
$WORK/us.xmpl.hkb/da/_obj/_cgo_main.c
gcc -I . -g -O2 -fPIC -m64 -pthread -I/home/harry/DA_cpp_1.5.3.1/include/
-I $WORK/us.xmpl.hkb/da/_obj/ -o $WORK/us.xmpl.hkb/da/_obj/_cgo_export.o -c
$WORK/us.xmpl.hkb/da/_obj/_cgo_export.c
gcc -I . -g -O2 -fPIC -m64 -pthread -I/home/harry/DA_cpp_1.5.3.1/include/
-I $WORK/us.xmpl.hkb/da/_obj/ -o
$WORK/us.xmpl.hkb/da/_obj/device_atlas.cgo2.o -c
$WORK/us.xmpl.hkb/da/_obj/device_atlas.cgo2.c
gcc -I . -g -O2 -fPIC -m64 -pthread -o $WORK/us.xmpl.hkb/da/_obj/_cgo_.o
$WORK/us.xmpl.hkb/da/_obj/_cgo_main.o
$WORK/us.xmpl.hkb/da/_obj/_cgo_export.o
$WORK/us.xmpl.hkb/da/_obj/device_atlas.cgo2.o
/usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/us.xmpl.hkb/da/_obj/
-dynimport $WORK/us.xmpl.hkb/da/_obj/_cgo_.o -dynout
$WORK/us.xmpl.hkb/da/_obj/_cgo_import.c
/usr/local/go/pkg/tool/linux_amd64/6c -F -V -w -I
$WORK/us.xmpl.hkb/da/_obj/ -I /usr/local/go/pkg/linux_amd64 -o
$WORK/us.xmpl.hkb/da/_obj/_cgo_import.6 -D GOOS_linux -D GOARCH_amd64
$WORK/us.xmpl.hkb/da/_obj/_cgo_import.c
gcc -I . -g -O2 -fPIC -m64 -pthread -o $WORK/us.xmpl.hkb/da/_obj/_all.o
$WORK/us.xmpl.hkb/da/_obj/_cgo_export.o
$WORK/us.xmpl.hkb/da/_obj/device_atlas.cgo2.o -Wl,-r -nostdlib
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/libgcc.a
cd $WORK
/usr/local/go/pkg/tool/linux_amd64/6g -o ./us.xmpl.hkb/da/_obj/_go_.6 -p
command-line-arguments -complete -D _$WORK ./swig_intsize.go
cd /home/harry/go_work/src/us.xmpl.hkb/da
swig -go -intgosize 64 -module device_atlas -soname
us.xmpl.hkb-da-device_atlas-swigcxx.so -o
$WORK/us.xmpl.hkb/da/_obj/device_atlas_wrap.cxx -outdir
$WORK/us.xmpl.hkb/da/_obj/ -c++ device_atlas.swigcxx
/usr/local/go/pkg/tool/linux_amd64/6c -F -V -w -I
$WORK/us.xmpl.hkb/da/_obj/ -I /usr/local/go/pkg/linux_amd64 -o
$WORK/us.xmpl.hkb/da/_obj/device_atlas_gc.6 -D GOOS_linux -D GOARCH_amd64
$WORK/us.xmpl.hkb/da/_obj/device_atlas_gc.c
gcc -I . -g -O2 -fPIC -m64 -pthread -g -fPIC -O2 -o
$WORK/us.xmpl.hkb/da/_obj/device_atlas_wrap.o -c
$WORK/us.xmpl.hkb/da/_obj/device_atlas_wrap.cxx
# us.xmpl.hkb/da
/tmp/go-build957195266/us.xmpl.hkb/da/_obj/device_atlas_wrap.cxx:221:27:
error: mtld/devatlas.h: No such file or directory

I understand there could be something funky with the devatlas.h appearing
twice (once for swig to parse) and then again inside the %{ %} directive.
I would have thought swig-generated include file should come in the go
headers. But I am just going by whatever I could see in the documentation.
When I remove what is inside those directive and do a build, I get

/tmp/go-build854690558/us.xmpl.hkb/da/_obj/device_atlas.go:13: package
device_atlas; expected main

--
Harry

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Gustavo Niemeyer at Mar 24, 2014 at 2:53 am

    On Sun, Mar 23, 2014 at 9:58 PM, wrote:
    I am trying to wrap a library with a C++ interface and access it from
    golang. The usage is simple, I just need to instantiate a class and call one
    or two methods on it. At this point, I don't even care if the resulting API
    exposed to golang is a simple C function, but my attempts at that didn't
    work, so I am trying swig.
    The ideas covered in this blog post and the resulting code will most
    likely serve as a good example of how to do this without SWIG:

    http://blog.labix.org/2014/03/21/arbitrary-qt-extensions-with-go-qml


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Mar 24, 2014 at 3:17 am

    On Sun, Mar 23, 2014 at 5:58 PM, wrote:
    // #cgo CPPFLAGS: -I/home/harry/DA_cpp_1.5.3.1/include/
    import "C"
    #cgo and import "C" are for cgo, not SWIG. Don't use them when using
    a .swigcxx file.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Justin Israel at Mar 25, 2014 at 6:52 am
    I've also got some examples of how I have been using Go to wrap a C++
    library, if you are interested:
    https://github.com/justinfx/opencolorigo

    (I borrowed from Gustavo on the project structure)

    On Mon, Mar 24, 2014 at 4:17 PM, Ian Lance Taylor wrote:
    On Sun, Mar 23, 2014 at 5:58 PM, wrote:

    // #cgo CPPFLAGS: -I/home/harry/DA_cpp_1.5.3.1/include/
    import "C"
    #cgo and import "C" are for cgo, not SWIG. Don't use them when using
    a .swigcxx file.

    Ian

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Harrysungod at Mar 25, 2014 at 6:56 pm
    Thank you Gustavo, Ian, and Justin. I found Gustavo's example a bit hard
    to follow with the Qt details. I will get back to the list after one more
    attempt at both Gustavo's link as well as yours. In the meanwhile, I will
    list my current status below in case anyone can tell me what I am missing.

    I did make more progress on my example, but I am now stuck at a linker
    stage. I actually have two issues (one with the import path and another
    with the linker when I work around the first one - they might be related).

    I have checked in whatever part could be published here
    https://github.com/harrysungod/da_api . You can't build it because one of
    the include files is outside of the tree and it is a
    proprietary/third-party, but I have checked in the generated SWIG files and
    .o and .6 as well. See build.sh to see the build commands I used.

    The build.sh is nothing but the steps listed in
    http://www.swig.org/Doc2.0/Go.html Section: 22.2.2

    Issue #1: This line produces an import error, which I work around by using
    the "./da/da" url. I know it is ugly and I must be doing something wrong.
    https://github.com/harrysungod/da_api/blob/master/da_main.go#L3

    Issue #2: If I use the work around for Issue #1, the last line of build.sh
    fails with

    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da.Init_da:
    undefined:
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da._swig_wrap_init_da
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da.Da_get_property:
    undefined:
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da._swig_wrap_da_get_property

    Now, I understand I might have to pass in some argument for the linker to
    know where da_api.so is, but I don't see how.

    Issue #3: The swig.com instructions above want me to use 'gopack'. Google
    directs me here https://github.com/d2fn/gopack . Those instructions talk
    about 'gopack', but builds binary named 'gp'. Invoking gp fails because I
    don't have a config file. Not sure what to put in the config file.

    --
    Harry
    On Monday, March 24, 2014 11:52:04 PM UTC-7, Justin Israel wrote:

    I've also got some examples of how I have been using Go to wrap a C++
    library, if you are interested:
    https://github.com/justinfx/opencolorigo

    (I borrowed from Gustavo on the project structure)


    On Mon, Mar 24, 2014 at 4:17 PM, Ian Lance Taylor <ia...@golang.org<javascript:>
    wrote:
    On Sun, Mar 23, 2014 at 5:58 PM, <harry...@gmail.com <javascript:>>
    wrote:
    // #cgo CPPFLAGS: -I/home/harry/DA_cpp_1.5.3.1/include/
    import "C"
    #cgo and import "C" are for cgo, not SWIG. Don't use them when using
    a .swigcxx file.

    Ian

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Mar 25, 2014 at 9:35 pm

    On Tue, Mar 25, 2014 at 11:56 AM, wrote:
    Thank you Gustavo, Ian, and Justin. I found Gustavo's example a bit hard to
    follow with the Qt details. I will get back to the list after one more
    attempt at both Gustavo's link as well as yours. In the meanwhile, I will
    list my current status below in case anyone can tell me what I am missing.

    I did make more progress on my example, but I am now stuck at a linker
    stage. I actually have two issues (one with the import path and another with
    the linker when I work around the first one - they might be related).

    I have checked in whatever part could be published here
    https://github.com/harrysungod/da_api . You can't build it because one of
    the include files is outside of the tree and it is a
    proprietary/third-party, but I have checked in the generated SWIG files and
    .o and .6 as well. See build.sh to see the build commands I used.

    The build.sh is nothing but the steps listed in
    http://www.swig.org/Doc2.0/Go.html Section: 22.2.2
    The go tool understands SWIG. You can often simply use that rather
    than those older commands. See
    http://golang.org/cmd/go/#hdr-Calling_between_Go_and_C .

    Issue #1: This line produces an import error, which I work around by using
    the "./da/da" url. I know it is ugly and I must be doing something wrong.
    https://github.com/harrysungod/da_api/blob/master/da_main.go#L3
    Do you have the GOPATH environment variable set? See
    http://blog.golang.org/organizing-go-code .

    Issue #2: If I use the work around for Issue #1, the last line of build.sh
    fails with

    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da.Init_da:
    undefined:
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da._swig_wrap_init_da
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da.Da_get_property:
    undefined:
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da._swig_wrap_da_get_property

    Now, I understand I might have to pass in some argument for the linker to
    know where da_api.so is, but I don't see how.
    Not sure what is happening there.

    Issue #3: The swig.com instructions above want me to use 'gopack'. Google
    directs me here https://github.com/d2fn/gopack . Those instructions talk
    about 'gopack', but builds binary named 'gp'. Invoking gp fails because I
    don't have a config file. Not sure what to put in the config file.
    gopack is gone. With Go 1.2 you can use "go tool pack" instead. But,
    again, try just using the go tool.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Harrysungod at Mar 25, 2014 at 10:58 pm
    Ian,
    On Tuesday, March 25, 2014 2:34:25 PM UTC-7, Ian Lance Taylor wrote:

    On Tue, Mar 25, 2014 at 11:56 AM, <harry...@gmail.com <javascript:>>
    wrote:
    The build.sh is nothing but the steps listed in
    http://www.swig.org/Doc2.0/Go.html Section: 22.2.2
    I realize that documentation points to swig 2. swig 3.0's documentation
    does refer to 'go tool pack'
    However, that doesn't help (explained later)

    The go tool understands SWIG. You can often simply use that rather
    than those older commands. See
    http://golang.org/cmd/go/#hdr-Calling_between_Go_and_C .
    I tried "go build -x" , but it stops at the import error (a variation of
    it) I talked about earlier. here is the output.

    WORK=/tmp/go-build799138325
    can't load package:
    /home/harry/go_work/src/github.com/harrysungod/da_api/da_main.go:4:8: local
    import "./da/da" in non-local package
    da_main.go:4:8: open
    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da: no such file
    or directory


    Issue #1: This line produces an import error, which I work around by using
    the "./da/da" url. I know it is ugly and I must be doing something wrong.
    https://github.com/harrysungod/da_api/blob/master/da_main.go#L3
    Do you have the GOPATH environment variable set? See
    http://blog.golang.org/organizing-go-code .
    Yes, I do have that environment set. You can see the path matches
    $GOPATH/src/<import-path>. In fact I tested a simple pure-Go 'package' and
    'caller' separately and that worked.

    $ echo $GOPATH
    /home/harry/go_work

    Issue #2: If I use the work around for Issue #1, the last line of build.sh
    fails with

    /home/harry/go_work/src/github.com/harrysungod/da_api/da/da.Init_da:
    undefined:
    /home/harry/go_work/src/
    github.com/harrysungod/da_api/da/da._swig_wrap_init_da
    /home/harry/go_work/src/
    github.com/harrysungod/da_api/da/da.Da_get_property:
    undefined:
    /home/harry/go_work/src/
    github.com/harrysungod/da_api/da/da._swig_wrap_da_get_property
    Now, I understand I might have to pass in some argument for the linker to
    know where da_api.so is, but I don't see how.
    Not sure what is happening there.
    Issue #3: The swig.com instructions above want me to use 'gopack'. Google
    directs me here https://github.com/d2fn/gopack . Those instructions talk
    about 'gopack', but builds binary named 'gp'. Invoking gp fails because I
    don't have a config file. Not sure what to put in the config file.
    gopack is gone. With Go 1.2 you can use "go tool pack" instead. But,
    again, try just using the go tool.
    As per the '3.0' documentation, it does refer to 'go tool pack'. Sorry
    about that.
    http://www.swig.org/Doc3.0/Go.html . 'go tool pack' goes through. I am
    still at the same error at the last linker step.
    I understand there is some magic that I missing. But I don't see how
    example.a is given to the linker step, so I can see why it would fail.

    I have attempted a CGO only version at
    https://github.com/harrysungod/da_api_cgo

    But that stops here

    $ go tool cgo da_main.go
    error: 'init_da' undeclared (first use in this function)
    error: (Each undeclared identifier is reported only once
    error: for each function it appears in.)
    error: 'da_get_property' undeclared (first use in this function)

    cgo is able to locate my include file for sure. Because if I change the
    reference in da_main.go to a non-existent filename, it breaks at include
    line.

    Ian
    --
    Harry


    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Harrysungod at Mar 26, 2014 at 4:26 am
    Ian, Gustavo, Justin, the pure CGO version worked! The issue was that my
    "extern C" declaration wasn't wrapped in a "#ifdef __cplusplus".

    Thanks for all your help! I am not going to bother with the swig version
    for now.

    So cgo's invocation of gcc failed and cgo or gcc was somehow eating that
    error message. When I ran with --debug-gcc=true, I found it.

    Actual error

    In file included from
    /home/harry/go_work/src/github.com/harrysungod/da_api_cgo/da_main.go:6:
    da_c_api.hxx:1: error: expected identifier or '(' before string constant
    da_c_api.hxx:3: error: expected identifier or '(' before string constant

    without the --debug-gcc, all I saw was

    error: 'init_da' undeclared (first use in this function)
    error: (Each undeclared identifier is reported only once
    error: for each function it appears in.)
    error: 'da_get_property' undeclared (first use in this function)

    Thanks
    --
    Harry
    On Tuesday, March 25, 2014 3:58:41 PM UTC-7, harry...@gmail.com wrote:

    I have attempted a CGO only version at
    https://github.com/harrysungod/da_api_cgo

    But that stops here

    $ go tool cgo da_main.go
    error: 'init_da' undeclared (first use in this function)
    error: (Each undeclared identifier is reported only once
    error: for each function it appears in.)
    error: 'da_get_property' undeclared (first use in this function)

    cgo is able to locate my include file for sure. Because if I change the
    reference in da_main.go to a non-existent filename, it breaks at include
    line.

    Ian
    --
    Harry
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 24, '14 at 12:58a
activeMar 26, '14 at 4:26a
posts8
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase