2014-11-26 2 views
3

В StackOverflow есть десятки подобных вопросов, но через несколько часов я наконец-то сдался.Python, ImportError: undefined symbol: g_utf8_skip

Так что я пытаюсь написать расширение C для Python. Назовем это mylib. Вот файл заголовка:

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, я получаю следующее (я взять в качестве успешная установка):

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 

Но когда я пытаюсь использовать mylib внутри Python, я получаю следующее:

>>> 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.put all the links to needed библиотека после все сгенерированные имена модулей.

Восстановление не работает (или я сделал это неправильно). Что касается размещения ссылок на нужную библиотеку после всего остального - ну, я не нашел способ сделать distutils изменить порядок ссылок в своей строке компиляции. Есть ли способ?

Я также попытался предоставлением extra_link_args/extra_compile_args моего расширения (без какого-либо эффекта):

module = Extension('mylib', ['mylib.c'], 
        extra_link_args=["-Xlinker", "-export-dynamic"]) 

Я чувствовал себя очень несчастным и держал на прибегая к помощи. Затем я узнал о SWIG. Я решил попробовать его, создав еще одну библиотеку: (верхний регистр)MYLIB (я изменил имена файлов и все текстовые вхождения mylib до MYLIB). Я написал скрипт:

#!/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? Как я могу заставить его работать?

ответ

2

Ну, на самом деле я нашел решение. А имел добавить библиотечные ссылки на 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"] 

, который присоединяет их к концу строки компиляции.

0

Я обнаружил, что добавление -fPIC в "extra_compile_args" в конструкторе расширения также помогло. Например:

my_module = Extension('modulename', 
         ... 
         extra_compile_args=["-fPIC"] 
         sources = ['mycode.c']) 
Смежные вопросы