问题描述
StackOverflow上有数十个类似的问题,但经过数小时的潜伏,我终于放弃了。
There are like tens of similar questions on StackOverflow, but after several hours of lurking I finally gave up.
因此,我正在尝试为蟒蛇。我们称之为 mylib
。这是头文件:
So I'm trying to write a C extension for Python. Let's call it mylib
. Here is the header file:
mylib.h
#ifndef mylib_H
#define mylib_H
#include <Python.h>
< ... >
#include <glib.h>
< ... >
和 setup.py:
from distutils.core import setup, Extension
include_list = [
"/usr/include/glib-2.0", "-lglib-2.0",
"/usr/lib/x86_64-linux-gnu/glib-2.0/include"
]
module = Extension('mylib', ['mylib.c'])
setup(name='mylib', version='1.0',
include_dirs=include_list,
ext_modules=[module])
如果我运行 python setup.py install
,以下内容(我认为安装成功):
If I run python setup.py install
, I get the following (which I take as successful installation):
running install
running build
running build_ext
building 'mylib' extension
creating build
creating build/temp.linux-x86_64-2.7
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/glib-2.0 -I-lglib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/python2.7 -c mylib.c -o build/temp.linux-x86_64-2.7/mylib.o
mylib.c: In function ‘c_sound_utf8’:
mylib.c:117:5: warning: ‘g_unicode_canonical_decomposition’ is deprecated (declared at /usr/include/glib-2.0/glib/gunicode.h:627) [-Wdeprecated-declarations]
decomposition = g_unicode_canonical_decomposition(c_composed, &decomposition_len);
^
creating build/lib.linux-x86_64-2.7
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/mylib.o -o build/lib.linux-x86_64-2.7/mylib.so
running install_lib
copying build/lib.linux-x86_64-2.7/mylib.so -> /usr/local/lib/python2.7/dist-packages
running install_egg_info
Removing /usr/local/lib/python2.7/dist-packages/mylib-1.0.egg-info
Writing /usr/local/lib/python2.7/dist-packages/mylib-1.0.egg-info
但是当我尝试从Python内部使用 mylib
时,我得到以下信息:
But when I try to use mylib
from inside Python, I get the following:
>>> import mylib
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/python2.7/dist-packages/mylib.so: undefined symbol: g_utf8_skip
在StackOverflow上徘徊了一段时间后,我想到应该 1。重建所需的库或 2。 库之后生成的模块名称。
After rambling around StackOverflow for some time I got an idea that I should either 1. rebuild the needed library or 2. put all the links to needed library after all generated module names.
重建没有用(或者我做错了方法)。至于在所有其他步骤之后放置指向所需库的链接,那么,我没有找到使 distutils
更改其编译字符串中的链接顺序的方法。 有办法吗?
Rebuilding didn't work (or I did it the wrong way). As for placing links to the needed library after everything else - well, I didn't find out the way to make distutils
change the order of links in its compile string. Is there a way?
我还尝试提供 extra_link_args
/ extra_compile_args
到我的扩展名(无任何作用):
I also tried providing extra_link_args
/extra_compile_args
to my extension (without any effect):
module = Extension('mylib', ['mylib.c'],
extra_link_args=["-Xlinker", "-export-dynamic"])
我感到非常痛苦,并且一直在搜寻。然后我发现了关于 SWIG 的信息。我决定尝试通过制作另一个库(大写) MYLIB
来尝试(我更改了文件名和所有 mylib出现的文本
到 MYLIB
)。我写了一个shell脚本:
I felt pretty miserable and kept googling on. Then I found out about SWIG. I decided to try it by making another library, (uppercase) MYLIB
(I changed filenames and all text occurences of mylib
to MYLIB
). I wrote a shell script:
#!/bin/bash
GLIB_IMPORT_OPTS="-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0"
PY_IMPORT_OPTS="-I/usr/include/python2.7/ -lpython2.7"
swig -Wall -python MYLIB.i
gcc -fPIC -Wall -c MYLIB.c $GLIB_IMPORT_OPTS
gcc -fPIC -Wall -shared MYLIB.o MYLIB_wrap.c -o _MYLIB.so $GLIB_IMPORT_OPTS -L. $PY_IMPORT_OPTS $GLIB_IMPORT_OPTS
当我运行此程序时,一切正常(我可以导入库并执行东西)。如您所见,这里的链接位于编译行的末尾。所以现在我想了解: distutils
方式让我错过了什么?
When I ran this thing, everything worked fine (I could import the library and do stuff with it). Here, as you can see, links are at the very end of the compile line. So now I'm trying to understand: what did I miss with the distutils
way? How can I make it work?
推荐答案
好吧,实际上我找到了解决方案。 A必须在 extra_link_args
中添加库链接:
Well, actually I found the solution. A had to add library links to extra_link_args
:
extra_link_args=["-I", "/usr/include/glib-2.0", "-l", "glib-2.0", "-I", "/usr/lib/x86_64-linux-gnu/glib-2.0/include"]
会将它们附加到编译字符串的末尾。
which appends them to the end of compile string.
这篇关于Python,ImportError:未定义符号:g_utf8_skip的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!