pythonccythonubuntu-16.04

How to use Cython to compile Python 3 into C


I'm trying to convert a Python 3 script into C and then compile that C file into an executable.

I have this simple python script:

def greet(name = ""):
  print("Hello {0}".format(name if len(name) > 0 else "World"))

greet("Mango")

I've converted this script into C using:

cython greet.py -o greet.c

Then I've compiled the C file using:

cc greet.c -o greet

After I entered the last command I got the error:

fatal error: Python.h: No such file or directory compilation terminated.

After I got the error I went back and realised that I was using Python3 and that I had forgot the "3" after "cython".
So re-compiled the python script using:

cython3 greet.py -o greet.c

Then attempted to re-compile the C file using:

cc greet.c -o greet

Again this failed and threw the same error so I went searching on SO and Google and found these questions:

None of these answers in these questions work.

I've made sure that I have installed cython all of the correct dependencies using apt-get install and pip install sadly thought it still does not seem to work.


Solution

  • Check the documentation. It's not enough to do gcc x.c -o x.

    This page explains compilation: http://docs.cython.org/src/reference/compilation.html

    There's a lot more to it, but a direct answer is:

    Compiling your .c files will vary depending on your operating system. Python documentation for writing extension modules should have some details for your system. Here we give an example on a Linux system:

    $ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o yourmod.so yourmod.c

    Of course in your situation it's going to be something closer to -I/usr/include/python3.4, or even $(pkg-config --libs --cflags python3). And you're not building with -shared, because you want an executable.

    Shortest "this has to work" set of commands is:

    cython3 --embed greet.py -o greet.c
    gcc $(pkg-config --libs --cflags python3) greet.c -o greet
    

    You need to install pkg-config if it's missing.