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:
- fatal error: Python.h: No such file or directory
- I have Python on my Ubuntu system, but gcc can't find Python.h
- https://askubuntu.com/questions/526708/fatal-error-python-h-no-file-or-directory
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.
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.
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.