C++ and SWIG: linking to 3rd-party libraries

1,924 views
Skip to first unread message

koschse...@googlemail.com

unread,
Dec 14, 2013, 11:07:02 PM12/14/13
to golan...@googlegroups.com
Hi there,

I'm trying to write a simple C++ function (not even a class) containing some OpenCV code, to be called from within my Go program. Unfortunately, much of the "good stuff" in OpenCV is C++ only.

Currently, my C++ file (let's call it ocv.cc) has said function in it; a header file (ocv.h) contains a single line with the function name. I added a ocv.swigcxx file which simply reads in a verbatim copy of the includes and the header file (%include "ocv.h"). All three files are in a subdirectory of my Go stuff.

My Go code imports that subdirectory and calls the C++ function. I can call the usual go build [projectname] and go takes care of all the SWIG stuff for me. I'm blown away. As long as I don't make any OpenCV calls in the C++ function, it actually works flawlessly.

Upon calling OpenCV functions, however, I get runtime errors like

/home/sebastian/go/bin/prjk: symbol lookup error: /home/sebastian/go/pkg/linux_amd64/swig/github.com-skosch-prjk-ocv-ocv-swigcxx.so: undefined symbol: _ZN2cv6imreadERKSsi

Examples of non-trivial Go/SWIG/C++ configurations are pretty much non-existent :(, and so I don't know what to do. The official docs aren't helpful -- I've tried going through the SWIG steps myself (as shown in the SWIG docs) but have had no luck so far. I would imagine that I have to indicate somewhere that I'd like to link to the /usr/local/lib/libopencv*.so files, but I don't know where.

I'd appreciate your help!

Sebastian

Justin Israel

unread,
Dec 15, 2013, 2:42:23 AM12/15/13
to koschse...@googlemail.com, golang-nuts
I basically have the exact same problem, but replace OpenCV with OpenImageIO. I can get everything build, but it doesn't seem to link properly against OpenImageIO.


--
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.
For more options, visit https://groups.google.com/groups/opt_out.

Jsor

unread,
Dec 15, 2013, 5:15:37 AM12/15/13
to golan...@googlegroups.com, koschse...@googlemail.com
I'm not a mega expert at C++ or SWIG, but from my experience this smells like a linker error. Are you sure you're linking against OpenCV (or any SWIG-generated libraries if it makes one) correctly? Are your library paths linked correctly? Do you have valid LDFLAGS set over your import "C" statement?

Jsor

unread,
Dec 15, 2013, 5:18:44 AM12/15/13
to golan...@googlegroups.com, koschse...@googlemail.com
Er, sorry, you both already noticed it was a linker error. :)

Here's a file for Go bindings for OpenGL


It, obviously, doesn't use SWIG. But it does show how to link properly from Go. Maybe it will help? Don't forget you can also use -L if need be.

Sebastian Kosch

unread,
Dec 15, 2013, 10:31:02 AM12/15/13
to golan...@googlegroups.com
Thanks :)
The problem is that cgo doesn't work with C++ code, which forces us to
use SWIG. But the automagical compiling and linking of the files that
happens when you write a .swigcxx file, which works great in principle,
doesn't seem to have a documented way of telling the C++ linker what
libs to link to. Is that clearer at all?

(If push comes to shove I'll just use opengl; I just have to run some
big matrix convolutions on a GPU. But it would be so much nicer to get
'real' C++ support.)

Best,
Seb
> <http://github.com-skosch-prjk-ocv-ocv-swigcxx.so>:
> undefined symbol: _ZN2cv6imreadERKSsi
>
> Examples of non-trivial Go/SWIG/C++ configurations are
> pretty much non-existent :(, and so I don't know what to do.
> The official docs aren't helpful -- I've tried going through
> the SWIG steps myself (as shown in the SWIG docs) but have
> had no luck so far. I would imagine that I have to indicate
> somewhere that I'd like to link to the
> /usr/local/lib/libopencv*.so files, but I don't know where.
>
> I'd appreciate your help!
>
> Sebastian
>
> --
> 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.
> For more options, visit
> https://groups.google.com/groups/opt_out
> <https://groups.google.com/groups/opt_out>.
>
>

minux

unread,
Dec 15, 2013, 12:14:12 PM12/15/13
to Sebastian Kosch, golang-nuts


On Dec 15, 2013 10:31 AM, "Sebastian Kosch" <koschse...@googlemail.com> wrote:
> The problem is that cgo doesn't work with C++ code, which forces us to use SWIG. But the automagical compiling and linking of the files that happens when you write a .swigcxx file, which works great in principle, doesn't seem to have a documented way of telling the C++ linker what libs to link to. Is that clearer at all?

cmd/go supports building c++ code along with a go package, so if write a "-style extern "C" wrapper for you C++ library, you can still use cgo. And cgo supports proper indication of libraries to be linked via LDFLAGS or pkgconfig.

Carlos Castillo

unread,
Dec 16, 2013, 2:21:59 AM12/16/13
to golan...@googlegroups.com, koschse...@googlemail.com
The problem is that the SWIG builder in the go tool builds a 'helper' shared library that contains all the results of the SWIG and G++ compilation. That library is essential for the go package to work, and so must either be installed into the library path (or use LD_LIBRARY_PATH env), or sit next to the final binary when run. If you look at your ${GOPATH}/pkg/${GOARCH}_${GOOS}/swig directory after running "go install" on the package, there should be a dll/so/dylib file there which you need to deal with for dependent commands / packages to work.

Now you can do the following:
  • Add the directory containing the library to the system env variable which controls the dynamic linker:
    • LD_LIBRARY_PATH - for Linux / *BSD
    • DYLD_LIBRARY_PATH - for Macosx
    • PATH - for Windows
  • Move / Copy / Link the library into a system library path (eg: /usr/local/lib)
  • Move / Copy / Link the library into the directory containing the command once it's built
For example, on my machine (Mac OS X 64-bit), with GOPATH=${HOME}/Projects/go I set the DYLD_LIBRARY_PATH=${HOME}/Projects/go/darwin_amd64/swig, and any swig-based packages installed should now link correctly.

I remember Ian Lance Taylor talking about moving that helper code from a dynamic lib into a static lib that would be linked into the package, but that didn't make it into 1.2. It was dependent on the external linking mode which didn't exist until 1.2. I can't seem to find an issue for it on the tracker though.

Stephen Gutekanst

unread,
Dec 16, 2013, 8:58:35 AM12/16/13
to golan...@googlegroups.com, koschse...@googlemail.com
There are two major problems with SWIG and the 'go' tool in my opinion:

1. The helper-code generated (which Carlos mentioned in his earlier mail, maybe a issue should be filed?) is a dynamic library which ideally could be a static one instead.

2. There are no CFLAGS/LDFLAGS that can be set per-package for compiling swig packages that depend on external libraries (what I think the OP is talking about), see http://code.google.com/p/go/issues/detail?id=6696

Stephen

Carlos Castillo

unread,
Dec 16, 2013, 9:37:10 AM12/16/13
to Stephen Gutekanst, golang-nuts, koschse...@googlemail.com
You're right, I didn't look close enough at the error posted by the OP: the problem wasn't finding the helper library, it was resolving a symbol it needed.


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/O8nQ_2_bXrE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Carlos Castillo
Reply all
Reply to author
Forward
0 new messages