Search code examples
pythonbuildvirtualenvcythondistutils

cython build via setup.py does wrong thing (putting all .so files in extra src dir)


I'm trying to convert from using pyximport to building via distutils, and I'm being stumped by the weird choices its making on where to put the .so files. So, I decided to build the tutorial out of the cython doc, only to find it prints a message saying its building, but does nothng. I'm in a virtualenv, and cython, python2.7, etc are all installed therein.

First the basics:

$ cython --version
Cython version 0.21.2
$ cat setup.py
from distutils.core import setup
from Cython.Build import cythonize
print "hello build"
setup(
    ext_modules = cythonize("helloworld.pyx")
)
$ cat helloworld.pyx
print "hello world"

Now When I build it everything looks ok except for the extra src/src stuff in the output:

$ python setup.py build_ext --inplace
hello build
Compiling helloworld.pyx because it changed.
Cythonizing helloworld.pyx
running build_ext
building 'src.helloworld' extension
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c helloworld.c -o build/temp.linux-x86_64-2.7/helloworld.o
creating /home/henry/Projects/eyeserver/dserver/src/src
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/helloworld.o -o /home/henry/Projects/eyeserver/dserver/src/src/helloworld.so

And when I run it, it of course fails:

$ echo "import helloworld" | python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named helloworld

Until I move the .so file out of its extra src directory:

$ mv src/helloworld.so  .
$ echo "import helloworld" | python
Hello world

What am I doing wrong? Obviously I could make the build process move all of the .so files, but that seems really hacky.


Solution

  • Whenever I use cython I use the Extension command.

    I would write the setup.py file as follows:

    from distutils.core import setup
    from distutils.extension import Extension
    from Cython.Build import cythonize
    
    extensions = [
        Extension("helloworld", ["helloworld.pyx"])
    ]
    
    setup(
        ext_modules = cythonize(extensions)
    )
    

    Hopefully this will then put the .so file in the current directory.