undefined symbols in Cython C++ wrapper

1.4k views Asked by At

I have a working cpp project which builds fine with cmake. Now I need to create a Python wrapper for the same. So I chose cython to bridge the gap between C++ and Python.

Instead of writing the CMakeLists.txt logic in pyx file, I tried compiling the library with cmake itself and later wrap the Cython wrapper around it. Following is the setup.py file:

import os
import sys

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize


try:
    build_dir = os.path.join(os.getcwd(), "build")
    print("building bobcore.a")
    if not os.path.exists(build_dir):
        os.makedirs(build_dir)
    if not os.path.exists(build_dir):
        raise Exception("Not able to create `build` directory")

    os.chdir(build_dir)
    assert os.system("cmake ..") == 0
    assert os.system("make -j4") == 0
    os.chdir(os.path.abspath(os.path.join(os.getcwd(), os.pardir)))
except:
    if not os.path.exists("build/bobcli"):
        print("Error building external library, please create libsample.a manually.")
        sys.exit(1)

_ext_modules = cythonize([
    Extension("call_core",
              sources=["call_core.pyx"],
              language="c++",
              extra_compile_args=["-std=c++11", "-lpthread", "-lz", "-ldl"],
              extra_link_args=["-std=c++11"],
              include_dirs=[os.path.join(os.getcwd(), "src")],  # path to .h file(s)
              library_dirs=[os.path.join(os.getcwd(), "build")],  # path to .a or .so file(s)
              libraries=["bobcli"] # name of pre-built .so file.
              )
])

setup(
    name='Demos',
    ext_modules=_ext_modules,
)

Here is the call_core.pyx file:

cdef extern from "src/api/Api.h" namespace "cli":
    cdef cppclass Api:
        int getVal()


cdef Api *api = new Api()

def getHelp():
    return api.getVal()

del api

Now this file works fine if I implement the getVal() method in the header file itself. But as soon as I move the implementation to .cpp file, Cython compiler shows the following error:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: /usr/local/lib/python2.7/dist-packages/call_core.so: undefined symbol: _ZN3cli9Api6getValEv

NOTE: The above snippets work perfectly for the functions with their implementation in the .h files.

0

There are 0 answers