有没有办法将python应用程序编译成静态二进制文件?


83

我想做的是将我的代码发送到远程服务器,该服务器可能安装了不同的python版本和/或可能没有我的应用程序所需的软件包。

现在,要实现这种可移植性,我必须使用解释器和代码来构建可重定位的virtualenv。这种方法存在一些问题(例如,由于--always-copy无法按预期工作,您必须手动将一堆库复制到virtualenv中),并且通常速度较慢。

从理论上讲,有一种方法可以静态地自行构建python。

我想知道是否可以将解释器和代码一起打包到一个二进制文件中,然后将应用程序作为模块运行。那样的东西:./mypython -m myapp run./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application


您是说cx_freeze吗?
TigerhawkT3

@ TigerhawkT3,直到今天我才听说过cx_freeze。查看文档,似乎是我想要的,但是它无法在python3.5.1的Ubuntu 12.04.5上构建。我正在寻找替代方案,感谢您朝着正确的方向前进。
roboslone

可悲的是,pyinstaller不能与Django 1.9一起使用,而py2app / py2exe不支持linux :(
roboslone

2
如果cx_Freeze和pyinstaller无法正常工作,仍然有希望。您可以为目标发行版创建软件包,这将解决所有安装依赖性。或者,也许使用诸如docker之类的东西来运行您的应用程序。
KeatsPeeks

1
其他选项是nuitka和cython
denfromufa 16-10-11

Answers:


116

有两种方法可以解决您的问题

  1. 使用静态生成器(例如冻结)或pyinstaller,或py2exe
  2. 编译使用 cython

我将解释如何使用第二种方法,因为第一种方法不是跨平台和跨版本的,并且已在其他答案中进行了解释。另外,使用pyinstaller之类的程序通常会导致文件很大,而使用cython会导致文件大小为KB

首先,安装cython。然后,将您的python文件(例如test.py)重命名为一个.pyx文件

sudo pip install cython
mv test.py test.pyx

然后,您可以将其cython与GCC一起使用进行编译(cython从Python.pyx文件中生成C文件,然后GCC编译C文件)

(参考https://stackoverflow.com/a/22040484/5714445

cython test.pyx --embed
gcc -Os -I /usr/include/python3.5m -o test test.c -lpython3.5m -lpthread -lm -lutil -ldl

注意:根据您的python版本,您可能必须更改最后一个命令。要知道您使用的是哪个版本的python,只需使用

$ python -V

现在,您将找到一个二进制文件“ test”

其他注意事项

  1. Cython用于将C类型变量定义用于静态内存分配,以加快Python程序的速度。但是,就您而言,您仍将使用传统的Python定义。
  2. 如果您正在使用其他库(例如opencv,例如),则可能必须使用提供它们的目录-L,然后-l在GCC标志中使用指定库的名称。有关此的更多信息,请参阅GCC标志

19
嗨,如果我的应用程序跨多个文件怎么办?这种方法似乎只编译当前脚本,而不是所有Python依赖项。
RChat

2
无需立即将python文件(例如test.py)重命名为pyx
iMath

3
这对我有很大帮助。要回答有关多个文件的问题,可以使用cythonize:cythonize -i file_0.py [...] file_n.py对所有python模块,然后cython main_file.py --embed对主脚本使用。您最终将获得可执行文件和.so文件(.dll,.dylib,具体取决于您的操作系统),可以将它们一起用作独立解决方案。
afp

我收到“没有名为编码的模块”。我知道我需要python安装中的某些文件。但是,我的目标系统没有python。请帮忙。
Abhiarora

8

您可能希望调查Nuitka。它需要python源代码并将其转换为C ++ API调用。然后将其编译为可执行二进制文件(在Linux上为ELF)。它已经存在了几年,并且支持各种Python版本。

如果使用它,您可能还会获得性能改进。推荐的。


我找不到有关将Nuitka与Django一起使用的任何信息。您是否有这样的经验?
roboslone

与Nuitka PyPy的静态生成器相比,@ roboslone,Prakhar Agarwal Cython确实非常支持外部库。例如,在此注释末尾的链接中,“人们使用Cython是因为它可以帮助他们解决问题。要么是他们想要从Python代码连接到外部非Python库,要么是他们希望能够手动优化他们的代码,或同时优化两者。”,链接为blog.behnel.de/posts/indexp241.html
RS Nikhil Krishna

1
RS Nikhil Krishna,我不是想让我的代码更快,而是想将它打包成一个带有python解释器的二进制文件。
roboslone

好的 我以为您想将其与某些外部库绑定。我的错。
RS Nikhil Krishna


0

冻结选项:

但是,目标服务器应具有所需的环境->您应该能够“创建”它。如果不是这样,则应构建适合环境的软件。

假设您具有ssh访问权限,我发现了此便捷指南,介绍如何将自定义版本的python安装到virtualenv: https //stackoverflow.com/a/5507373/5616110

在virtualenv中,您应该可以pip安装任何内容,并且无需担心sudo特权。当然,拥有像apt这样的程序包并可以访问程序包管理器会使一切变得简单得多。


我已经在使用virtualenv,事实并非如此。我的问题是关于静态编译的python和所需的模块和应用程序。
roboslone

然后,您必须冻结它,而没有其他解决方法。
iScrE4m

0

如果您使用的是Mac,则可以使用py2app来创建.app捆绑包,双击该捆绑包即可启动Django应用。

我在https://moosystems.com/articles/14-distribute-django-app-as-native-desktop-app-01.html上介绍了如何将Django和CherryPy捆绑到这样的捆绑中

在本文中,我使用pywebview在本地应用程序窗口中显示Django站点。


我的应用程序主要在Linux上运行,因此py2app不适用
roboslone

尽管本文使用py2app,但也可以使用pyinstaller完成。
安德烈Aulich
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.