一直在玩赛通。通常在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 myfile.pyx(不带选项)生成.c文件。当我使用--embed选项时,它会生成一个比它大100行的.c文件。区别它们表明添加了一堆ifdef。我仍然面临着这个问题:我该如何使用这个。那么?我似乎找不到正确的编译器选项组合。阅读cython文档了解numpy,一种方法是制作一个导入.so的包装python程序。我很惊讶,当我隐藏.c和.pyx文件,然后说:import nameofmyfile没有扩展名时,它似乎选择了.so文件。
- 使用cython编译主python程序的可能副本
您需要的是用于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编译器优化。
- 看我上面的评论
- 好吧。我已经更新了。
- 兰恩,我很感激所有的建议,而且我正在接近。我的命令是:gcc-i[[python2.7包括]-o a.out helloworld.c-lpython2.4。我现在只有两个错误:对py_initmodule4_64和pyunicodeucs2_decodeutf8的未定义引用。谷歌认为这是32位和64位的混淆。我在Linux RH5上。
- 添加-fpic没有任何区别。
- 似乎您需要添加-D MS_WIN64,正如这个问题的答案之一所建议的那样,-fPIC是一个标志,使生成的二进制文件对操作系统更友好。如果我没记错的话,它可以避免我在Linux上构建Python模块时遇到的错误。为什么要使用python 2.7 includes和python2.4库?这也可能造成麻烦。
- -d选项不影响任何内容。我将python2.4包括在内,因为我使用2.5、.6和.7会出现"找不到"的错误。我试过包括完整的路径,但说它仍然找不到。系统管理员。现在正在做一个完整的更新——也许这会有所帮助。再次感谢你的建议。
- 我不明白的是:在python shell中,导入.pyx文件会导致它编译、加载和执行。为什么我不能在命令行上做同样的事情?
- 我想如果您愿意依赖于一个Python文件,您可以这样做。您可以制作一个使用pyximport导入cython脚本的python脚本。这看起来有点像一个黑客,但它可能适用于大多数简单的脚本。我认为使用gcc的一个优点是,您可以获得一个独立的可执行文件,它不依赖于python,但是目前还没有一个不依赖python的系统来验证这一点。您可能需要为此添加静态链接。Pyximport不允许您自定义安装脚本,因此这种方法也仅限于小型项目。
- 嗯。根据这个问题判断,对于没有安装python的系统,要使其成为完全独立的可执行文件还需要更多的东西。也许可以编译一个cython扩展模块,从python运行它,然后使用pyinstaller。但我现在不知道。
- 很遗憾,这不适用于Windows
- @Haydendarcy我最初用mingw测试过这个,尽管mingw不兼容最新的Python版本,甚至不兼容旧版本的libpython。a可能需要单独安装。对于MSVC来说,类似的方法应该是可行的。您必须更改为msvc样式的标志并链接到libpython.dll,而不是libpython.a或libpython.so。主要的想法是,Cython可以为独立的可执行文件生成代码,但是当您编译生成的文件时,必须包含针对Python运行时的Python头和链接(并确保在编译器搜索的路径中都可以找到这两者)。
- 别忘了添加Chrome驱动程序更改,因为它在其他PC以及其他问题(如我发现的)上都不起作用。虽然不像我想象的那么简单,但它还是可以工作的。或者,分发winpython bareboons+python作业。如果你想要安全,就加上赛通。正如人们会发现的那样,试图让没有python的python运行是可以理解的复杂和容易出错的。
- 只要您为chrome驱动程序提供正确的路径,pyinstaller就可以很好地工作。但是,在组合pyinstaller+cython时会出现问题。请参阅:stackoverflow.com/questions/47026649/&hellip;。这个文件非常庞大。Winpython+标准python文件也可以工作。我还没有看到一个独立的Cython或Nuitka解决方案,尽管这两个解决方案看起来都很麻烦,无法自己完成工作。
- 对,不管怎样,最终你都不得不依赖解释器和相应的运行时。重新分配这些文件会使文件变大。即使是静态编译方法也依赖于解释器,并且专注于编译扩展,而不是进行某种源代码到源代码的转换。由于Python中的所有动态特性,这种情况对于任意用户代码都是不可能的。如果给定的可执行文件可以嵌入任意的Python语义,那么它已经实现了某种解释器。对于任意的用户代码,这是不可能的。
在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 |
。
运行文件:
现在,对于Python3,类似这样的东西可以工作(未测试):
1
| gcc -Os -I /usr/include/python3.6 example.c -lpython3.6 -o example |
。
其中python3.x是安装在您的计算机上的python版本。
- 这会加载所有用赛通制作的导入和模块,对吗?
- 如果您的意思是python导入和模块,是的。
- 如何从多个.py文件生成独立文件?我有多个python文件,我想使用cython将它们全部编译成一个包。
- 你试过编译导入所有其他文件的主文件吗?