Question

This works:

cc leveldb_ext.cc leveldb_object.cc -o leveldb.so -I /usr/include/python2.7 -lpython2.7 -lleveldb -lsnappy -shared -lc

This does not work:

cc -I /usr/include/python2.7 -g -c leveldb_ext.cc leveldb_object.cc
ld -shared -o leveldb.so -lpython2.7 -lleveldb -lsnappy leveldb_ext.o leveldb_object.o -lc

In both cases, I don't get any compiler/linking errors. However, when trying to import it, I get this error:

$ python -c "import leveldb"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: ./leveldb.so: undefined symbol: _ZNK7leveldb6Status8ToStringEv

Why? Is there any difference between the two methods? What is the difference?

Was it helpful?

Solution

The order of the object files and the libraries is not the same between the two cases. The order is significant.

OTHER TIPS

Usually a setup.py script is used to compile Python modules. Something like this should work:

from setuptools.extension import Extension

ext_modules = [
    Extension(
        'yourmodule',
        sources=['yourmodule.c'],
        libraries=['a', 'b', 'c'],
        extra_compile_args=['-Wall', '-g'],
    )
]

setup(..., ext_modules=ext_modules)

Setuptools makes sure the compiler and linker will be called with the right flags, avoiding issues like the one in your question.

Btw, you should have a look at Plyvel if you want a nice Python API for LevelDB. See https://github.com/wbolster/plyvel and https://plyvel.readthedocs.org/ for more information. (Disclaimer: I'm the author.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top