如何使用Cython将Python 3编译成C

时间:2021-01-12 23:44:29

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

我尝试将Python 3脚本转换成C,然后将C文件编译成可执行文件。

I have this simple python script:

我有这个简单的python脚本:

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

I've converted this script into C using:

我已经把这个脚本转换成C:

cython greet.py -o greet.c

Then I've compiled the C file using:

然后我编译了C文件使用:

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.

致命错误:Python。h:未终止此类文件或目录编译。

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:

在我犯了错误之后,我回去发现我用的是Python3,而且我在“cython”之后忘记了“3”。因此,使用以下方法重新编译python脚本:

cython3 greet.py -o greet.c

Then attempted to re-compile the C file using:

然后尝试使用以下方法重新编译C文件:

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.

我已经确保使用apt-get安装和pip安装安装安装安装了cython所有正确的依赖项,遗憾的是,它似乎仍然不能工作。

2 个解决方案

#1


6  

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

检查文档。仅仅做gcc x是不够的。c - o x。

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

本页面解释编译:http://docs.cython.org/src/reference/compiler .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:

编译.c文件将根据您的操作系统而有所不同。用于编写扩展模块的Python文档应该包含系统的一些细节。这里我们举一个Linux系统的例子:

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

$ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict- alialize -I/usr/include/python2.7 -o yourmod。所以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.

当然,在这种情况下,它更接近-I/usr/include/python3.4,甚至是$(pkg-config——libs——cflags python3)。你不是用-shared构建,因为你想要一个可执行文件。

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

最短的“this have to work”命令集是:

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

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

如果缺少pkg-config,您需要安装它。

#2


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.

正如@viraptor的回答所示,正如我的评论所示,您的主要问题是需要告诉C编译器(例如gcc)在哪里找到所需的python头(pyconfig)。h和Python.h)。为此,需要将-I选项传递给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.

另一个答案建议使用pkg-config将其添加到命令行中。但是,就像您一样,使用Ubuntu 14.04、cython3和python3-dev安装,使用这个方法,编译后的程序就会自动退出,并出现分割错误。

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)

运行以下命令。它假设Python。h和朋友在标准位置(例如,您已经完成了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.

如果不行,使用find / -iname Python。h查找所需文件的位置并相应地更改-I路径。

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)

最终,当您希望在更复杂的程序上使用cython(比如那些链接到其他C库的程序)时,您将需要了解传递给gcc的其他选项,以使它能够正确编译和链接。不过,为了让您继续工作,上面的工作应该可以(根据您的规范在Ubuntu 14.04上进行测试)

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.

另外,我不确定为什么pkg-config建议不起作用——但对我来说,它似乎增加了一个通往-I的额外路径,它破坏了一些东西。

#1


6  

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

检查文档。仅仅做gcc x是不够的。c - o x。

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

本页面解释编译:http://docs.cython.org/src/reference/compiler .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:

编译.c文件将根据您的操作系统而有所不同。用于编写扩展模块的Python文档应该包含系统的一些细节。这里我们举一个Linux系统的例子:

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

$ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict- alialize -I/usr/include/python2.7 -o yourmod。所以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.

当然,在这种情况下,它更接近-I/usr/include/python3.4,甚至是$(pkg-config——libs——cflags python3)。你不是用-shared构建,因为你想要一个可执行文件。

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

最短的“this have to work”命令集是:

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

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

如果缺少pkg-config,您需要安装它。

#2


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.

正如@viraptor的回答所示,正如我的评论所示,您的主要问题是需要告诉C编译器(例如gcc)在哪里找到所需的python头(pyconfig)。h和Python.h)。为此,需要将-I选项传递给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.

另一个答案建议使用pkg-config将其添加到命令行中。但是,就像您一样,使用Ubuntu 14.04、cython3和python3-dev安装,使用这个方法,编译后的程序就会自动退出,并出现分割错误。

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)

运行以下命令。它假设Python。h和朋友在标准位置(例如,您已经完成了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.

如果不行,使用find / -iname Python。h查找所需文件的位置并相应地更改-I路径。

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)

最终,当您希望在更复杂的程序上使用cython(比如那些链接到其他C库的程序)时,您将需要了解传递给gcc的其他选项,以使它能够正确编译和链接。不过,为了让您继续工作,上面的工作应该可以(根据您的规范在Ubuntu 14.04上进行测试)

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.

另外,我不确定为什么pkg-config建议不起作用——但对我来说,它似乎增加了一个通往-I的额外路径,它破坏了一些东西。