如何用Cython将Python3编译成C

How to use Cython to compile Python 3 into C

我正在尝试将 Python 3 脚本转换为 C 语言,然后将该 C 文件编译为可执行文件。

我有这个简单的 python 脚本:

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

greet("Mango")

我已将此脚本转换为 C 使用:

cython greet.py -o greet.c

然后我使用以下方法编译了 C 文件:

cc greet.c -o greet

输入最后一条命令后出现错误:

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

出现错误后,我返回并意识到我正在使用 Python3,而我忘记了 "cython" 之后的“3”。
所以重新编译 python 脚本使用:

cython3 greet.py -o greet.c

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

cc greet.c -o greet

再次失败并抛出相同的错误,所以我继续搜索 SO 和 Google 并发现了这些问题:

这些问题中的

None 个答案有效。

我已经确保我已经使用 apt-get install 安装了所有正确的 cython 依赖项,pip install 遗憾地认为它似乎仍然不起作用。

检查文档。做 gcc x.c -o x.

还不够

本页解释编译:http://docs.cython.org/src/reference/compilation.html

还有很多,但直接的答案是:

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

当然,在您的情况下,它会更接近 -I/usr/include/python3.4,甚至 $(pkg-config --libs --cflags python3)。而且您没有使用 -shared 进行构建,因为您需要一个可执行文件。

最短的 "this has to work" 命令集是:

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

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

正如 @viraptor's answer 向您展示的以及根据我的评论,您的主要问题是您需要告诉您的 C 编译器(例如 gcc)在哪里可以找到 python headers 需要(pyconfig.hPython.h)。为此,您需要将 -I 选项传递给 gcc.

另一个答案建议使用 pkg-config 将其添加到您的命令行。但是,像你一样,安装了 Ubuntu 14.04、cython3python3-dev,使用这种方法会导致编译的程序退出并出现分段错误。

所以,我建议你回到基础。之后

cython greet.py -o greet.c

运行下面的命令。它假定 Python.h 和朋友在标准位置(即您已经完成 python3-dev 的标准安装)

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

如果这不起作用 - 使用 find / -iname Python.h 查找必要文件的位置并相应地更改 -I 路径。

及时,当你想在更复杂的程序上使用 cython 时,例如那些 link 到其他 C 库的程序,你需要了解你需要传递给 gcc 让它编译并 link 正确。不过,为了让您继续前进,以上内容应该有效(根据您的规范在 Ubuntu 14.04 上测试)

P.S。我不确定为什么 pkg-config 建议不起作用 - 但对我来说,它似乎添加了一条通往 -I 的额外路径,这会破坏事情。

Python 2:

python -m pip install --upgrade cython

Python 3:

python3 -m pip install --upgrade cython