使用Cython编译主Python程序

时间:2011-02-24 13:48:32

标签: python cython

我有一个Python2.6程序,可以使用Cython加载编译为.so文件的Python模块。我用Cython将.py模块编译成.so文件,一切正常。

这是我在Cython中使用的setup.py文件:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension("ldap", ["ldap.pyx"]),
    Extension("checker", ["checker.pyx"]),
    Extension("finder", ["finder.pyx"]),
    Extension("utils", ["utils.pyx"]),
]

setup(
  name = 'bchecker',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

所以我知道我可以使用Cython编译Python模块(我猜Cython从我的Python文件创建'C'文件然后编译它们),但是我可以将我的主Python程序编译成我可以在Linux平台上执行的程序吗?如果是这样,将欣赏Cython命令行示例。感谢。

4 个答案:

答案 0 :(得分:133)

与Adam Matan和其他人断言的相反, 实际上是使用Cython从纯Python(.py)文件创建单个可执行二进制文件。 / p>

是的,Cython旨在按照规定使用 - 作为简化为CPython python运行时编写C / C ++扩展模块的一种方法。

但是,正如nudzo在此comment中提到的那样,您可以在命令行提示符下使用--embed开关。

这是一个非常简单的例子。我正在使用python3和cython3来从Debian Sid工作站执行此操作。

确保您事先安装了 python-dev python3-dev 软件包。

1)创建一个非常简单的Python程序,名为 hello.py

  

$ cat hello.py

     

print(“Hello World!”)

2)使用Cython将您的python程序编译为C ...

cython3 --embed -o hello.c hello.py

3)使用GCC将hello.c编译成名为 hello 的可执行文件...

gcc -Os -I /usr/include/python3.3m -o hello hello.c -lpython3.3m -lpthread -lm -lutil -ldl

4)您最终得到一个名为 hello 的文件......

  

$ file hello

     

你好:ELF 64位LSB可执行文件,x86-64,版本1(SYSV),   动态链接(使用共享库),用于GNU / Linux 2.6.32,   BuildID [sha1] = 006f45195a26f1949c6ed051df9cbd4433e1ac23,未剥离

$ ldd hello
linux-vdso.so.1 (0x00007fff273fe000)
libpython3.3m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.3m.so.1.0 (0x00007fc61dc2c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc61da0f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc61d70b000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fc61d508000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc61d304000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc61cf5a000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc61cd52000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fc61cb28000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc61c90f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc61e280000)

在这种情况下,可执行文件在我的Debian系统上动态链接到Python 3.3。

5)运行 hello ...

  

$ ./hello

     

Hello World!

正如您所看到的,使用此方法您基本上可以使用Cython将纯Python应用程序转换为可执行的编译目标代码。

我将此方法用于更复杂的应用程序 - 例如,完整的Python / PySide / Qt应用程序。

对于不同版本的Python,您可以定制gcc -I -l 以适应。

然后,您可以将可执行文件打包为分发(.deb等)文件,而无需打包Python / PySide / Qt文件 - 优点是您的应用程序即使在分发更新后仍应能够运行在该发行版上使用相同版本的Python等。

答案 1 :(得分:17)

看一下Can Cython compile to an EXE?的答案,与此处的所有其他答案相反,是的,可以编译成可执行文件。

Embedding Cython的链接似乎是一个很好的起点,但它不是Cython的主要目的,所以我不知道它会有多么简单。

答案 2 :(得分:3)

我不知道这是否有帮助,但Nudzo是正确的。您可以使用cython --embed -o main.o main.py获取它,然后我尝试使用cl / EHsc

编译结果

答案 3 :(得分:-18)

你不能,Cython不是为了编译Python而是把它变成可执行文件。

要生成.exe文件,请使用py2exe

要生成适用于Mac或Linux的软件包,请使用常规打包系统过程,因为Unix环境中没有关于脚本语言程序的具体内容。