Search code examples
pythonc++cython

Python Cython Symbols are missing


I compiled the C++ rnnlib as shared library and want to call it from python. I chose cython and created a a c++ function void libCall(int argc, char* argv[]) (which is actually the same as the main function of rnnlib but renamed it to make it easier callable). The rnnlib library is inside /usr/lib

rnn.pyx

# distutils: language = c++

cdef extern from "libcall.hpp":
    void libCall(int argc, char* argv[])

cpdef call():
    print 'hallo welt'

setuprnn.py

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

os.environ["CC"] = "gcc"
os.environ["CXX"] = "g++"
os.environ["CFLAGS"]="-I./src/"

setup(ext_modules = cythonize(
       "rnn.pyx",
       libraries=["rnnlib","netcdf_c++","netcdf","m","stdc++"],
       language="c++",
      ))

Additional test.cpp

#include <iostream>
#include "libcall.hpp"

using namespace std;


int main(int argc, char* argv[]) {
    libCall(argc, argv);
}

Building test.cpp with

g++ -Wall -I./src/ test.cpp -lrnnlib -lnetcdf_c++ -lnetcdf -lm -lstdc++ -o test

works.

When I run python setuprnn.py build_ext -i I get rnn.so and rnn.cpp. But when trying to import rnn in Python:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./rnn.so: undefined symbol: _ZNK5NcVar3getEPcPKl

Inspecting rnn.so with nm yields:

000000000003f140 W _ZNK5Mdrnn5printERSo
             U _ZNK5NcDim4sizeEv
             U _ZNK5NcVar3getEPcPKl

This is strange, because this is the missing symbol.


Solution

  • The problem are the dependencies of my libraries. Cython does not handle them.

    The python script from above (setuprnn.py) does nothing else but execute this:

    cython ...
    gcc ...
    g++ ... -lrnnlib -lnetcdf -lstdc++ -o rnn.so
    

    This creates a problem as stated above in the entry post. The solution is then just to create a shell script for creating the library:

    #!/bin/sh
    cython ...
    gcc ...
    g++ ... -o rnn.so -lnetcdf_c++ -lnetcdf -lm -lstdc++ -lrnnlib