使用 Cython 编译主 Python 程序
- 2025-04-17 08:59:00
- admin 原创
- 17
问题描述:
我有一个 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 命令行示例。谢谢。
解决方案 1:
与 Adam Matan 和其他人所断言的相反,您实际上可以使用 Cython 从纯 Python (.py) 文件创建单个可执行二进制文件。
是的,Cython 旨在按所述用途使用 - 作为简化为 CPython python 运行时编写 C/C++ 扩展模块的一种方式。
但是,正如 nudzo 在此评论中提到的,您可以--embed
在命令行提示符下使用该开关。
这是一个非常简单的例子。我在 Debian Sid 工作站上使用 python3 和 cython3 执行此操作。
确保您已预先安装了python-dev或python3-dev包。
1)创建一个非常简单的Python程序,名为hello.py
$ cat hello.py
打印(“你好,世界!”)
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 ...的文件。
$文件你好
你好: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)运行你好...
$./你好
你好世界!
如您所见,使用此方法,您基本上可以使用 Cython 将纯 Python 应用程序转换为可执行的、编译的目标代码。
我正在将此方法用于更为复杂的应用程序 - 例如,功能齐全的 Python/PySide/Qt 应用程序。
对于不同版本的 Python,您可以定制 gcc-I
和-l
开关以适应。
然后,您可以将可执行文件打包为分发(.deb 等)文件,而不必打包 Python/PySide/Qt 文件 - 优点是即使在分发更新到相同版本的 Python 等之后,您的应用程序仍然能够运行。
解决方案 2:
看一下Cython 可以编译为 EXE 吗?的答案,与这里的所有其他答案相反,答案是肯定的,可以编译为可执行文件。
嵌入 Cython上的链接似乎是一个很好的起点,但这不是 Cython 的主要目的,所以我不知道它有多么简单。
解决方案 3:
我不知道这是否有用,但 Nudzo 是正确的。你可以用它获取它cython --embed -o main.o main.py
,然后我尝试用 cl/EHsc 编译结果。
解决方案 4:
看看这个帖子:
cython <cython_file> --embed
然后就
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>
这里有一个例子:
cython3 main.py --embed
gcc main.c -I /usr/include/python3.8/ -L /lib/x86_64-linux-gnu/ -l python3.8 -o main
解决方案 5:
你不能,Cython 不是用来编译 Python 的,也不是用来将其转换为可执行文件的。
要生成 .exe 文件,请使用py2exe。
要为 Mac 或 Linux 生成软件包,请使用常规打包系统流程,因为 Unix 环境中的脚本语言程序没有任何特殊之处。
扫码咨询,免费领取项目管理大礼包!