python 各类打包软件对比
一、工作原理
简介
github地址: https://github.com/indygreg/PyOxidizer
使用文档:https://pyoxidizer.readthedocs.io/en/stable/index.html
从很高的层次上讲,PyOxidizer它是用于打包和分发Python应用程序的工具。的总体目标PyOxidizer 是使这个(通常是复杂的)问题空间变得简单,以便应用程序维护人员可以专注于构建高质量的应用程序,而不是使用构建系统和打包工具进行繁琐的工作。
在较低的技术层面上,PyOxidizer有一个命令行工具-pyoxidizer能够构建二进制文件(可执行文件或库),这些二进制文件将功能齐全的Python解释器以及Python扩展和模块嵌入到单个二进制文件中。使用生成的二进制文件具有PyOxidizer高度的可移植性,几乎可以在每个系统上工作,而无需任何特殊要求,例如容器,FUSE文件系统,甚至是临时目录访问。在Linux上,PyOxidizer可以生成完全静态链接的甚至不支持动态加载的可执行文件。
名称的Oxidizer部分来自Rust:用Rust构建的二进制文件 PyOxidizer是从Rust编译的,Rust代码负责管理嵌入式Python解释器及其所有操作。但是Rust的存在对于许多用户来说应该是不可见的,就像C语言(可从www.python.org获得的官方Python发行版)是在C语言中实现的事实一样。Rust仅仅是实现最终目标的工具(尽管有效且功能强大的工具)。
PyInstaller可以生成包含您的应用程序的自包含可执行文件,但是,在运行时,PyInstaller会将二进制文件和自定义的ZlibArchive提取到一个临时目录,然后从文件系统导入模块。
PyOxidizer通常会跳过此步骤,并使用零复制直接从内存中加载模块。使用此功能后,PyOxidizer可执行文件的启动速度将大大加快。
工作原理
该pyoxidizer
工具用于创建新项目或添加PyOxidizer
到现有(Rust)项目。这需要:
- 生成样板的Rust源文件以调用
pyembed
板条箱以运行Python解释器。 - 生成工作
pyoxidizer.bzl
配置文件。 - 告诉项目的Rust构建系统有关
PyOxidizer
的信息。
当项目的pyembed
板条箱由Rust的构建系统构建时,它会调用PyOxidizer
来处理活动的PyOxidizer
配置文件。 PyOxidizer
将获得经过优化的嵌入式Python发行版。然后,它将使用此发行版来完成自身的打包以及配置文件中指示的任何其他Python依赖项。例如,您可以在构建时处理一个pip要求文件,以在生成的二进制文件中包括其他Python包。
在此香肠粉碎机的末尾,将PyOxidizer
发出一个包含Python的存档库(可以链接到另一个库或可执行文件)和一个包含Python数据的*资源文件*(例如Python模块源和字节码)。最重要的是,PyOxidizer
告诉Rust的构建系统如何将这些组件集成到正在构建的二进制文件中。
从这里开始,Rust的构建系统将标准Rust位与PyOxidizer
生成的文件结合在一起,并将所有内容转换为二进制文件,通常是可执行文件。
在运行时,从pyembed
板条箱将创建一个OxidizedPythonInterpreterConfig
结构的实例,以定义嵌入式Python解释器的行为。(PyOxidizer
执行的构建时操作之一是将Starlark配置文件转换为该结构的默认实例。)此结构用于实例化Python解释器。
该pyembed
板条箱实现了Python *扩展模块*,该*模块*提供了自定义模块导入功能。Light magic用于强制Python解释器在初始化期间非常早地加载此模块。这使模块可以处理Pythonimport
请求。pyembed
安装的自定义模块导入程序支持从嵌入在可执行文件本身中的只读数据结构中检索数据。本质上,Python import
请求调用由pyembed
提供的一些Rust代码,Rust向内存返回一个void*
,其中包含PyOxidizer
在构建时生成的(模块源代码,字节码等),这些数据是在构建时由Rust的构建系统生成并随后嵌入到二进制文件中的。
一旦嵌入式Python解释器被初始化,应用程序就可以像任何其他Python应用程序一样工作了!主要区别在于模块(可能)是从内存中导入的,而Rust(而不是Python发行版的Python
可执行逻辑)是Python执行的驱动因素。
二、简单的示例
准备工作:
默认安装了rust python
安装 cargo install pyoxidizer
查看安装:
D:\Rust\projects>pyoxidizer
PyOxidizer 0.11.0
Gregory Szorc <gregory.szorc@gmail.com>
Build and distribute Python applications
USAGE:
pyoxidizer [FLAGS] [SUBCOMMAND]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Enable verbose output
SUBCOMMANDS:
add Add PyOxidizer to an existing Rust project. (EXPERIMENTAL)
analyze Analyze a built binary
build Build a PyOxidizer enabled project
find-resources Find resources in a file or directory
help Prints this message or the help of the given subcommand(s)
init-config-file Create a new PyOxidizer configuration file.
init-rust-project Create a new Rust project embedding a Python interpreter
list-targets List targets available to resolve in a configuration file
python-distribution-extract Extract a Python distribution archive to a directory
python-distribution-info Show information about a Python distribution archive
python-distribution-licenses Show licenses for a given Python distribution
run Run a target in a PyOxidizer configuration file
run-build-script Run functionality that a build script would perform
D:\Rust\projects>pyoxidizer init-config-file pyapp
writing pyapp\pyoxidizer.bzl
A new PyOxidizer configuration file has been created. 已创建新的pyoxidator配置文件。
This configuration file can be used by various `pyoxidizer` commands 此配置文件可由各种“pyoxizer”命令使用
For example, to build and run the default Python application:
$ cd pyapp
$ pyoxidizer run
The default configuration is to invoke a Python REPL. 默认配置是调用Python REPL。
You can edit the configuration file to change behavior. 您可以编辑配置文件以更改行为。
初次运行 pyoxidizer run
会构建python的编译环境:
国内或许会报错:
resolving Python distribution Url { url: "https://github.com/indygreg/python-build-standalone/releases/download/20210303/cpython-3.9.2-x86_64-pc-windows-msvc-share
d-pgo-20210303T0937.tar.zst", sha256: "27b27d19eb6a460fb865547a98d30f76fe1875daec4413fa7752c35a53195c01" }
downloading https://github.com/indygreg/python-build-standalone/releases/download/20210303/cpython-3.9.2-x86_64-pc-windows-msvc-shared-pgo-20210303T0937.tar.zst
error[PYOXIDIZER_BUILD]: error sending request for url (https://github.com/indygreg/python-build-standalone/releases/download/20210303/cpython-3.9.2-x86_64-pc-wind
ows-msvc-shared-pgo-20210303T0937.tar.zst): connection error: broken pipe
可以先下载文件,【github下载加速】
将文件放置在pyapp\build\python_distributions
文件夹下即可,再次运行加载编译。如下如即成功:
(To exit the REPL, press CTRL+d or CTRL+z.)
接下来按照官方入门文档示例继续实验即可。
它可以以3种不同的模式打包东西:
- repl — 这真的很简洁,我认为它是一个其自身的“可交付的”类别。它允许你分发一个预先配置了任何和所有依赖项的单文件交互式Python REPL。可以将Jupyter Notebook看作是一个可执行的命令行。
- eval — 使用你选择的Python命令运行一个单行字符串。其文档使用import uuid; print(uuid.uuid4())为例。它可以很好地处理执行简单任务或调用具有简单接口的模块的代码。
- module — 将一个模块加载为__main__并执行它。我预计这是大型应用程序的常见选择。
TOML配置文件中提供的打包选项允许进行大量自定义设置。
处理模块依赖关系的4个选项: 单文件pip安装、使用需求文件、提供根目录包含或简单地指向一个配置了所有依赖关系的虚拟环境。
运行打包的代码时__file__属性不会被设置。 详情。块时,其代码的运行环境就会受到限制。