6

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.

7
  • 3
    install python-dev Commented Apr 4, 2016 at 9:39
  • 3
    The accepted answer to your first example question - did you try instead doing sudo apt-get install python3-dev? (note the 3). On 14.04, you need to do that to get the dev libraries for py 3 instead of 2. Commented Apr 4, 2016 at 9:40
  • 1
    @JRichardSnape Yes I'm sure that I have changed all the python version where necessary, but I will try again. Commented Apr 4, 2016 at 9:41
  • 1
    Note also - you might need to do the minor version specific command e.g. install python3.4-dev Commented Apr 4, 2016 at 9:42
  • 2
    You need to tell gcc where the headers are (e.g. pass the path with -I to the compiler or -l for libraries when linking. Commented Apr 4, 2016 at 10:09

4 Answers 4

8

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.

Sign up to request clarification or add additional context in comments.

12 Comments

I am using this command: gcc -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing /usr/include/python3.4 -o test.so test.c but I still get the error.
If you get the same error, then check which version of headers you actually have installed. Or you can avoid all specifics by just compiling with gcc $(pkg-config --libs --cflags python3) greet.c -o greet. If you get an error about missing main instead, you need to use cython3 --embed greet.py.
Your instructions have gotten rid of all the other errors but one remains Must specify package names on the command line. and then it says pyconfig.h no such file or directory.
That's OK we all make mistakes. I have used the updated instructions and I now have a couple dozen undefined reference to errors does this mean that there is a error in my source code?
What's the undefined name? Can you paste the error?
|
0

As @viraptor's answer shows you and as per my comment, your main problem is that you need to tell your C compiler (e.g. gcc) where to find the python headers required (pyconfig.h and Python.h). To do this, you need to pass a -I option to gcc.

The other answer suggests using pkg-config to add this to your command line. However, like you, with Ubuntu 14.04, cython3 and python3-dev installs, using this method leads the compiled program to exit with a segmentation fault for me.

So, I suggest you go back to basics. After

cython greet.py -o greet.c

Run the following command. It assumes that Python.h and friends are in the standard place (i.e. you've done a standard install of python3-dev)

gcc -I/usr/include/python3.4m -o greet greet.c -lpython3.4m

If that doesn't work - use find / -iname Python.h to find the location of the necessary files and alter the -I path accordingly.

In time, when you want to use cython on more complex programs, such as those that link to other C libraries, you'll need to learn about the other options you need to pass to gcc to get it to compile and link correctly. To get you going, though, the above should work (tested on Ubuntu 14.04 as per your spec)

P.S. I'm not sure why the pkg-config suggestion doesn't work - but for me it seems to add in an extra path to -I which breaks things.

1 Comment

I have a bunch of Python.h's, one for each Conda env, for Pycharm, for vscode, etc. Some of them are small case python.h. I should probably try the one in the activated conda env.
0

This one makes a shared object file cython1.so, which we could later import in our python 3 project:

gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing $(python3-config --includes) -o /home/alex/python_cython/cython1.so /home/alex/python_cython/cython1.c

Or just make it as follows. It works on .pyx files: cythonize --3str -i /home/alex/folder/cython1.pyx

Comments

-2

Python 2:

python -m pip install --upgrade cython

Python 3:

python3 -m pip install --upgrade cython

3 Comments

That looks like how you update Cython. However, the question was asking how to compile Cython-generated C files
If you have actually tested, the issues are solved exactly by using my approach.
Maybe you should explain why. Because it looks like the person asking the question already has an up-to-date version of Cython installed. The accepted answer shows that the problem was the include path passed to gcc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.