【问题标题】:Is there a way to compile a python application into static binary?有没有办法将 python 应用程序编译成静态二进制文件?
【发布时间】:2017-02-16 06:03:48
【问题描述】:

我正在尝试将我的代码发送到远程服务器,该服务器可能安装了不同的 python 版本和/或可能没有我的应用所需的包。

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

(理论上)a way 可以静态构建 python 本身。

我想知道我是否可以将解释器与我的代码打包成一个二进制文件并将我的应用程序作为模块运行。类似的东西:./mypython -m myapp run./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application

【问题讨论】:

  • 你的意思是像 cx_freeze 这样的东西吗?
  • @TigerhawkT3,直到今天我才听说过 cx_freeze。浏览文档,似乎是我想要的,但它无法使用 python3.5.1 在 Ubuntu 12.04.5 上构建。我正在寻找替代品,感谢您朝正确的方向前进。
  • 遗憾的是,pyinstaller 不适用于 Django 1.9 并且 py2app/py2exe 不支持 linux :(
  • 如果 cx_Freeze 和 pyinstaller 不起作用,还是有希望的。您可以为您的目标发行版创建包,这将解决安装的所有依赖关系。或者,也许使用 docker 之类的东西来运行您的应用程序。
  • 其他选项是nuitka和cython

标签: python build


【解决方案1】:

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

  1. 使用静态构建器,例如 freeze 或 pyinstallerpy2exe
  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 向它们提供目录,然后在GCC 标志中使用-l 指定库的名称。有关这方面的更多信息,请参阅 GCC 标志

【讨论】:

  • 嗨,如果我的应用程序跨越多个文件怎么办。这种方法似乎只编译当前脚本而不是所有 Python 依赖项。
  • 现在不需要将你的python文件(比如test.py)重命名为pyx
  • 这对我帮助很大。要回答有关多个文件的问题,您可以使用 cythonize:cythonize -i file_0.py [...] file_n.py 用于所有 python 模块,然后使用 cython main_file.py --embed 用于主脚本。您最终会得到一个可执行文件和 .so 文件(.dll、.dylib 取决于您的操作系统),您可以将它们一起用作独立的解决方案。
  • 警告:Cython 需要动态加载内容,它不会生成独立的二进制文件。不要浪费你的时间!
  • 看来我得继续使用golang了。
【解决方案2】:

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

如果您使用它,您可能还会获得性能提升。推荐。

【讨论】:

  • 我找不到任何关于在 Django 中使用 Nuitka 的信息。你有没有这样的经历?
  • @roboslone,与 Nuitka PyPy 的静态构建器相比,Prakhar Agarwal Cython 非常支持外部库。例如,在此评论末尾的链接中,“人们使用 Cython 是因为它可以帮助他们解决问题。要么他们想从 Python 代码连接到外部非 Python 库,要么他们希望能够手动优化他们的代码,或两者兼而有之。”,链接为blog.behnel.de/posts/indexp241.html
  • R. S. Nikhil Krishna,我并不想让我的代码更快,我想把它放在一个带有 python 解释器的二进制文件中。
  • 啊,好吧。我以为你想将它与一些外部库绑定。我的错。
【解决方案3】:

您可能正在寻找像 Freeze 这样的东西,它能够将您的 Python 应用程序及其所有库编译成静态二进制文件:

PyPi page of Freeze

Python Wiki page of Freeze

Sourceforge page of Freeze

【讨论】:

    【解决方案4】:

    如果你在 Mac 上,你可以使用 py2app 创建一个 .app 包,当你双击它时,它会启动你的 Django 应用程序。

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

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

    【讨论】:

    • 我的应用程序主要在 Linux 上运行,所以 py2app 不适用
    • 文章虽然使用了py2app,但也可以使用pyinstaller。
    【解决方案5】:

    冻结选项:

    但是,您的目标服务器应该具有您想要的环境 -> 您应该能够“创建”它。如果没有,您应该构建您的软件以匹配环境。

    我找到了这个关于如何将自定义版本的 python 安装到 virtualenv 的方便指南,假设你有 ssh 访问权限:https://stackoverflow.com/a/5507373/5616110

    在 virtualenv 中,您应该能够 pip install 任何东西,并且您不必担心 sudo 权限。当然,拥有这些并访问像 apt 这样的包管理器会让一切变得容易得多。

    【讨论】:

    • 我已经在使用 virtualenv,但事实并非如此。我的问题是关于静态编译的 python 和所需的模块和应用程序。
    • 那你必须冻结它,别无他法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 2012-12-22
    相关资源
    最近更新 更多