未解析的外部符号构建了一个python C扩展,其中包含针对共享C库的swig

时间:2014-07-17 13:16:48

标签: python c swig

我正在尝试使用SWIG为python包装一个C库。我正在使用标准系统工具链的Linux 64位系统(Gentoo)。库(SUNDIALS)安装在我的系统上,共享库位于/usr/local/lib

我的界面文件很简单(开头)

%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"

鉴于上面的接口文件,我运行

$ 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

稍微挖掘一下双重检查事项

$ 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

据我所知,N_VLinearSum是N_VLinearSum_Serial的包装器(也有并行实现,所以假设nvecparallel中的N_VLinearSum将包装N_VLinearSum_Parallel)。虽然我失去了,但接下来该做什么。这是我的界面定义问题,还是编译问题?

2 个答案:

答案 0 :(得分:1)

我们通过链接额外的库来实现它。似乎libsundials_nvecserial.so并且弟兄们不包含符号N_VLinearSum。 SUNDIALS使进程将函数和符号从sundials_nvector.h放入不同的.so文件中,这在某种程度上与直觉相反。

目前,我使用了

$ gcc -shared -L/usr/local/lib nvecserial_wrap.o -o _nvecserial.so\
-lsundials_nvecserial -lsundials_cvode
$ python -c "import nvecserial"
$

我将继续使用来自源代码发布的实际.o文件,但考虑到最终使用distutils分发包装模块的意图,并且不是每个人都可以访问其系统上的SUNDIALS源,我和#39; ll可能会坚持使用额外的共享库中的链接。

答案 1 :(得分:0)

而不是

gcc -shared /usr/local/lib/libsundials_nvecserial.so nvecserial_wrap.o -o _nvecserial.so

尝试

gcc -shared -L/usr/local/lib nvecserial_wrap.o -o _nvecserial.so -lsundials_nvecserial

-l应该在结尾,否则可能不会搜索lib的符号。这在ld手册页中有解释。