【Python】uvpakcer:跨平台为 Python 项目打包出 Windows 应用

https://github.com/touken928/uvpacker

把标准 pyproject.toml 项目变成「拷到 Windows 机器上就能跑」的自包含应用目录------不需要目标机安装 Python,不需要 PyInstaller,甚至不需要你在 Windows 上构建。

它解决什么问题

Python 生态的打包一直是个痛点:

  • PyInstaller 体积大、启动慢、跨平台支持有限,配置复杂且产物难以预期;

  • Nuitka 需要编译,构建时间长,调试门槛高;

  • 传统方式往往要求你在 Windows 上 才能打出 Windows 包,CI/CD 流程被平台绑架。

uvpacker 走了一条不同的路:它以 uv 为依赖解析引擎,以 CPython 官方嵌入式运行时(Embedded Distribution) 为目标运行时,产出的是一个结构清晰、可压缩、可拷贝的 应用目录 ,而非单文件 exe。你可以在 Linux、macOS 或 Windows 上完成整个构建。

核心功能

功能 说明
跨平台构建 依赖解析目标锁定 win_amd64,从任意 OS 打出 Windows 包(纯 Python 项目或已有 Windows wheel 的项目均可)
自包含运行时 内嵌官方 CPython Embedded Runtime,目标机器无需安装系统 Python
声明式配置 全部基于标准 pyproject.toml[project.scripts] / [project.gui-scripts],零额外配置文件
原生启动器 由 C 编写的 console.exe / gui.exe 模板生成 <script>.exe,控制台程序和 GUI 程序各自走对应子系统
包内嵌入 你的项目包以 zip 归档形式附加到 .exe 尾部,启动时内存导入;第三方依赖留在 packages/
轻度混淆 源码 .py 编译为 .pyc 后删除原始文件(非加密,但避免明文暴露)
资源嵌入 通过 importlib.resources.files 访问包内资源,启动器的内存加载器原生支持
缓存机制 嵌入式 Python 运行时下载一次后缓存,重复构建无需重新下载

使用步骤

1. 准备项目

确保你的 pyproject.toml 符合上述要求,推荐使用uv创建。

复制代码
 uv init --package

以下是一个最小示例

复制代码
 [project]
 name = "my-app"
 version = "1.0.0"
 requires-python = "==3.12.*"
 dependencies = [
     "requests",
 ]
 ​
 [project.scripts]
 my-app = "my_app.main:main"
 ​
 [build-system]
 requires = ["uv_build>=0.11.2,<0.12.0"]
 build-backend = "uv_build"

2. 一行命令打包

推荐使用 uvx 直接运行,无需全局安装:

复制代码
 # 默认输出到 ./dist/<项目名>/
 uvx uvpacker build path/to/my-app
 ​
 # 指定输出目录
 uvx uvpacker build path/to/my-app -o path/to/output

3. 查看产物

构建完成后,输出目录结构如下:

复制代码
 dist/my-app/
   runtime/          # Windows 嵌入式 CPython 运行时
   packages/         # 第三方依赖(win_amd64)
   my-app.exe        # 控制台启动器(来自 [project.scripts])

如果你的项目声明了 [project.gui-scripts],则会额外生成无控制台窗口的 GUI 启动器。

4. 分发

将整个 dist/my-app/ 目录压缩为 zip 或直接拷贝到 Windows 机器上,双击 .exe 即可运行------无需安装任何运行时。

适用场景与限制

适合:

  • 纯 Python 项目,希望从 macOS/Linux CI 直接产出 Windows 分发包

  • 需要声明式、可预期的打包流程,不想维护复杂构建脚本

  • GUI 应用(PySide6 等)或 CLI 工具的 Windows 分发

限制:

  • 不交叉编译 C 扩展------如果你的项目自带 C 扩展源码,需在 Windows 上构建,或预先准备好 Windows wheel

  • 项目包自身若包含 .pyd / .dll 等原生二进制,当前的内存嵌入模式不支持(第三方依赖中的原生二进制不受影响,仍保留在 packages/