Python, ImportError: undefined symbol: g_utf8_skip

There are several dozen similar questions on StackOverflow, but after a few hours I finally gave up.

So I am trying to write a C extension for Python. Let's call him mylib

. Here is the header file:

mylib.h

#ifndef mylib_H
#define mylib_H

#include <Python.h>
< ... >
#include <glib.h>
< ... >

      

and 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])

      

If I run python setup.py install

I get the following (which I accept as a 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

      

But when I try to use mylib

from within Python I get this:

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

      

After a bit of getting around on StackOverflow, I got the idea that I should either 1. rebuild the library I want, or 2. put all references in the library I need after all the generated module names.

Recovery didn't work (or I did it wrong). As far as placing links to the desired library after everything else - well, I haven't found a way to do the distutils

reordering of the links in my compilation line. Is there a way?

I also tried to provide extra_link_args

/ to extra_compile_args

my extension (without any effect):

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

      

I felt rather unhappy and kept looking for work. Then I found out about SWIG . I decided to try it by creating another library (uppercase) mylib

(I changed the filenames and all text occurrences from 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

      

When I ran this thing everything worked fine (I could import the library and do everything with it). Here, as you can see, the links are at the very end of the compilation line. So now I'm trying to figure out: what am I missing with the help distutils

? How can I get it to work?

+3


source to share


2 answers


Well, actually I found a 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 adds them to the end of the compilation line.

+2


source


I found that adding -fPIC to "extra_compile_args" in the extension constructor helped as well. For example:



my_module = Extension('modulename',
                      ...
                      extra_compile_args=["-fPIC"]
                      sources = ['mycode.c'])

      

0


source







All Articles