关于python:在Cython中创建可执行文件

Making an executable in Cython

一直在玩赛通。通常在python中编程,但在以前的生命中使用c。我不知道如何生成一个独立的可执行文件。

我已经下载了cython,我可以制作一个.pyx文件(这只是一个扩展名为.pyx的普通python文件),它在python shell中执行,使用:导入pyximport;pyximport.install()

我可以使用:cython file.pyx在命令行生成.c文件我可以通过构建标准setup.py并执行以下操作来生成.so文件:

1
setup.py build_ext --inplace

我试过用gcc制作一个.so文件的可执行文件,但总是有大量丢失的文件、头文件等。我试过从几乎所有地方指向头文件,但没有成功,我不太熟悉gcc所有选项的作用,甚至我应该使用gcc。

我在这里有一个断开连接,我可以在python shell中运行我的程序,但不能在命令行中运行(我不希望用户必须进入shell、导入模块等)。

我这里缺什么?


您需要的是用于cython编译器的--embed标志。上面没有很多文档,但这是我能找到的。它确实链接到一个简单的工作示例。

要将cython源代码编译为C文件,然后将其编译为可执行文件,可以使用诸如cython myfile.pyx --embed之类的命令,然后使用您使用的任何C编译器进行编译。

在编译C源代码时,仍然需要将目录包含在python头中,并链接到系统上相应的python共享库(如果使用python 2.7,则文件名类似于libpython27.so)或libpython27.a)。

编辑:这里还有一些关于如何获取包含正确标题和针对正确库链接的命令的更多说明。

正如我前面所说,您需要像这样运行cython编译器:

1
cython <cython_file> --embed

要使用gcc进行编译,您需要找到系统中Python头文件的位置(您可以通过运行distutils.sysconfig.get_python_inc()来获得这个位置(您必须先导入它)。它可能只是python安装目录中的/include子目录。

您还必须找到Python共享库。对于python 2.7,它将是windows上的libpython27.a或Linux上的libpython2.7.so

你的GCC命令将是

1
gcc <C_file_from_cython> -I<include_directory> -L<directory_containing_libpython> -l<name_of_libpython_without_lib_on_the_front> -o <output_file_name>

最好加上-fPIC标志。在Windows64位计算机上,还必须包含标志-D MS_WIN64,它告诉mingw为64位窗口编译。

如果您正在编译依赖于numpy的内容,则还需要包含numpy头的目录。您可以通过运行numpy.get_include()找到这个文件夹(同样,在导入numpy之后)。你的GCC命令变成

1
gcc <C_file_from_cython> -I<include_directory> -I<numpy_include_directory> -L<directory_containing_libpython> -l<name_of_libpython_without_lib_on_the_front> -o <output_file_name>

本GCC命令选项指南可能会有所帮助。

另外,如果可能的话,我建议您使用Cython内存视图。这样就不必包含numpy头文件,也不必在cython文件中包含numpy pxd文件。它还使切片操作更容易被C编译器优化。


在Ubuntu上测试过:

使用以下(python 2)安装Cython

1
sudo apt-get install cython

对于python 3:

1
sudo apt-get install cython3

要将python代码编译为C代码运行(对于python 3,将Cython更改为cython3

1
cython --embed -o example.c example.py

这将生成example.c文件。

现在编译example.c文件:

1
gcc -Os -I /usr/include/python2.7 example.c -lpython2.7 -o example

运行文件:

1
./example

现在,对于Python3,类似这样的东西可以工作(未测试):

1
gcc -Os -I /usr/include/python3.6 example.c -lpython3.6 -o example

其中python3.x是安装在您的计算机上的python版本。