Use Cython to wrap C/C++-program depending on multiple libraries

Viewed 541

I have a large C/C++ project which I usually just build as a standalone executable. It also requires some libraries (system libraries like pthread, but also MKL from intel for example) which I specify when compiling the project.

Now, I want to use some functions from this project in Python. So my first plan was to simply build the project as a static library and then use that to write a cython wrapper. I.e.

  1. Build the c project: icc -c src/main.cpp .. options and stuff.. linking to all libraries needed .. -o main.o

  2. Create a static library (including the libraries I needed in step 1): ar -rc libmain.a main.o ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ... /usr/lib/x86_64-linux-gnu/libpthread.a ...

  3. I use the generated static library to build my cython wrapper

  4. when I try to execute a test python script calling a random function from my C program I get this error ImportError: /home/.../main.cpython-37m-x86_64-linux-gnu.so: undefined symbol: __kmpc_ok_to_fork

It seems like I need to tell cython to link to the corresponding libraries again or something, but I'm not really sure how to resolve this.. Also I don't want the python project to be dependent on some special libraries that I have installed on my system (that's what I try to achieve by adding all the libraries in step 2), is this possible at all?

My setup.py looks like this

from setuptools import setup, Extension
from Cython.Build import cythonize
import os

os.environ["CC"] = "icc"
os.environ["CXX"] = "icc"
setup(
   ext_modules = cythonize([Extension("test", ["test.pyx"], language="c++",
                                  library_dirs=[r'.'], libraries=['main'])])
)
1 Answers

Create a shared library (.so on linux). Python can only support dynamic or shared libraries. The linker is looking for a .so not a .a.

So your setup.py would be remain the same,

from setuptools import setup, Extension
from Cython.Build import cythonize
import os

os.environ["CC"] = "icc"
os.environ["CXX"] = "icc"
setup(
   ext_modules = cythonize([Extension("test", ["test.pyx"], language="c++",
                                  library_dirs=[r'.'], libraries=['main'])])
)

Related - Using Cython To Link Python To A Shared Library.

Related