PyApp:Python 工程打包工具
PyApp 是一款基于 Rust 语言编写的工具,可将 Python 程序封装为独立的'点击即运行'可执行文件。相比市面上其他解决方案,它提供了一种更易于使用的打包方式。
开发者通常面临将 Python 程序重新分发为独立软件包的困难。虽然存在第三方解决方案,但各有缺点:
- PyInstaller:历史最悠久、知名度最高,但使用较为棘手,往往需要大量试错才能生成可用分发包。
- Nuitka:较新的项目,将 Python 编译为二进制文件,但产物体积可能庞大且编译耗时较长。
PyApp 采取了截然不同的方法。它是一个 Rust 程序,需结合目标 Python 项目的信息从源代码进行编译。生成的结果是一个独立的二进制文件,运行时会将项目解压到目录中并从中执行。最终用户无需在系统上安装 Python 即可使用。
搭建 PyApp 环境
与其他 Python 分发解决方案不同,PyApp 既不是 Python 库,也不是直接接收程序的独立工具。相反,你需要为每一个想要分发的 Python 程序,定制化构建一个专属的 PyApp。
在使用 PyApp 部署 Python 程序之前,需要先搞定以下几个先决条件:
- PyApp 的源代码:克隆一份 PyApp 的源码,并将其放在一个独立的目录中,与其他项目隔离开。
- Rust 编译器及相关环境:如果不熟悉 Rust 或其工具链,至少需要掌握如何从源代码编译一个 Rust 程序的基础知识。
- 打包为 Wheel 格式的 Python 程序:'Wheel'(即
.whl文件)是用于打包 Python 程序及其平台特定组件的二进制格式。如果没有目标程序的 wheel 包,就需要生成一个;也可以直接使用托管在 PyPI 上的 wheel 包。
配置环境变量
PyApp 在构建过程中会读取环境变量,以确定要编译哪个 Python 项目以及如何支持它。以下是最常用的变量:
PYAPP_PROJECT_NAME:定义要打包的 Python 项目名称。如果使用pyproject.toml定义项目,它应与project.name属性匹配。这也可以是 PyPI 上某个项目的名称;如果不是,就需要定义所用.whl文件的路径。PYAPP_PROJECT_VERSION:如果需要,用它来配置项目的特定版本。PYAPP_PROJECT_PATH:指向项目.whl文件的路径(相对或绝对路径)。如果直接从 PyPI 安装 wheel 包,则可省略此变量。PYAPP_EXEC_MODULE:许多 Python 包可以通过模块形式直接运行。此变量用于声明要使用的模块。例如,如果程序通过python -m thisprogram运行,就将此变量设为thisprogram。PYAPP_EXEC_SPEC:针对具有入口点脚本的程序,可以在这里指定。它对应pyproject.toml中project.scripts部分的语法。例如,pyprogram.cmd:main会导入程序模块中的pyprogram.cmd,然后执行其中的main()函数。PYAPP_EXEC_SCRIPT:允许提供一个任意 Python 脚本的路径,该脚本会被嵌入二进制文件并在启动时执行。PYAPP_DISTRIBUTION_EMBED:通常情况下,创建 PyApp 二进制文件时,它会从互联网下载运行所需的 Python 发行版。如果将此变量设为1,PyApp 会将所需的 Python 发行版预先打包进生成的二进制文件中。结果是生成的文件体积更大,但它无需下载任何内容,可以直接解压并运行。
虽然还有许多其他选项可用,但对于大多数项目而言,以上这些已经足够了。为了方便自己,可以为每个项目创建一个 shell 脚本,用于设置这些环境变量并运行编译过程。
构建 PyApp 二进制文件
设置好环境变量后,进入 PyApp 源码的根目录,使用 Rust 编译器运行以下命令来构建 PyApp:


