Reputation: 2207
I'm trying to wrap a C library for python using SWIG. I'm on a linux 64-bit sytem (Gentoo) using the standard system toolchain. The library (SUNDIALS) is installed on my system with shared libraries in /usr/local/lib
My interface file is simple (to start with)
%module nvecserial
%{
#include "sundials/sundials_config.h"
#include "sundials/sundials_types.h"
#include "sundials/sundials_nvector.h"
#include "nvector/nvector_serial.h"
%}
%include "sundials/sundials_config.h"
%include "sundials/sundials_types.h"
%include "sundials/sundials_nvector.h"
%include "nvector/nvector_serial.h"
Given the interface file above, I run
$ swig -python -I/usr/local/include nvecserial.i
$ gcc -O2 -fPIC -I/usr/include/python2.7 -c nvecserial_wrap.c
$ gcc -shared /usr/local/lib/libsundials_nvecserial.so nvecserial_wrap.o -o _nvecserial.so
$ python -c "import nvecserial"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "nvecserial.py", line 28, in <module>
_nvecserial = swig_import_helper()
File "nvecserial.py", line 24, in swig_import_helper
_mod = imp.load_module('_nvecserial', fp, pathname, description)
ImportError: ./_nvecserial.so: undefined symbol: N_VLinearSum
A little digging to double check things shows
$ objdump -t /usr/local/lib/libsundials_nvecserial.so |grep Linear
0000000000001cf0 g F .text 00000000000002e4 N_VLinearSum_Serial
$ objdump -t _nvecserial.so |grep Linear
00000000000097e0 l F .text 0000000000000234 _wrap_N_VLinearSum
000000000000cd10 l F .text 0000000000000234 _wrap_N_VLinearSum_Serial
0000000000000000 *UND* 0000000000000000 N_VLinearSum
0000000000000000 F *UND* 0000000000000000 N_VLinearSum_Serial
As far as I can tell, N_VLinearSum is a wrapper around N_VLinearSum_Serial (there's a parallel implementation too, so presumably, N_VLinearSum in nvecparallel would wrap N_VLinearSum_Parallel). Where I'm lost though is what to do next. Is this a problem with my interface definition, or a problem with my compilation?
Upvotes: 0
Views: 895
Reputation: 2207
We'll I've got it working by linking in an extra library. It seems libsundials_nvecserial.so
and brethren don't contain the symbol N_VLinearSum. The SUNDIALS make process places functions and symbols from sundials_nvector.h
into different .so files, somewhat counter intuitively.
For now, I got this working with
$ gcc -shared -L/usr/local/lib nvecserial_wrap.o -o _nvecserial.so\
-lsundials_nvecserial -lsundials_cvode
$ python -c "import nvecserial"
$
I'll continue playing around with actual .o files from the source distribution, but considering the intent to distribute the wrapped module eventually using distutils, and that not everyone will have access to the SUNDIALS source on their systems, I'll probably stick with linking in the extra shared library.
Upvotes: 1
Reputation: 29493
Instead of
gcc -shared /usr/local/lib/libsundials_nvecserial.so nvecserial_wrap.o -o _nvecserial.so
try
gcc -shared -L/usr/local/lib nvecserial_wrap.o -o _nvecserial.so -lsundials_nvecserial
The -l should be at end otherwise the lib may not be searched for symbols. This is explained in the ld man page.
Upvotes: 0