极速 Python 项目打包器。
Project description
fspack
极速 Python 项目打包器(cargo 风格短命令)。
fspack 将 Python 项目打包为可执行文件与跨平台安装包:用 embed python(Windows)或 python-build-standalone(Linux)提供运行时,C loader 配置环境并调用用户脚本,NSIS 生成 Windows 安装包、dpkg-deb 生成 Linux .deb 与 tar.gz 便携包。命令风格参考 cargo,常用操作均可用两字母短命令完成。
特性
- cargo 风格短命令:
fsp b打包、fsp r运行、fsp c清理、fsp p生成安装包 - 零依赖入侵:不需修改用户源码,自动分析 import 推断第三方依赖
- embed python 运行时:Windows 用官方 embed python zip,Linux 用 indygreg python-build-standalone
- C loader 启动器:动态加载 libpython,烧入入口路径,mingw/gcc 编译为原生可执行文件
- 跨平台安装包:
fsp p按目标平台生成 Windows NSIS 安装包(含开始菜单/桌面快捷方式、卸载器、中英文双语)或 Linux .deb + tar.gz 便携包 - 双平台支持:Windows(embed + mingw 交叉编译)、Linux(python-build-standalone + gcc)
- 多入口打包:
[tool.fspack.entries]声明多个入口,单个项目生成多个 exe 共享 runtime/依赖/源码,支持 cli/gui/web 混合类型 - 国内镜像:默认阿里云 PyPI 与 embed python 镜像,
--mirror切换 - 彩色进度显示:rich 驱动的步骤进度(> 准备运行时 / √ 构建完成),错误/警告/一般消息颜色区分,
-v开启 DEBUG 日志
安装
pip install fspack
或使用 uv:
uv add fspack
快速上手
在 Python 项目根目录(含 pyproject.toml)执行:
# 打包当前项目(生成 dist/<name>.exe 与 dist/runtime/)
fsp b
# 运行已打包项目
fsp r
# 生成安装包到 dist/release/(Windows: <name>-setup.exe / Linux: <name>_<ver>_amd64.deb + <name>-<ver>-linux.tar.gz)
fsp p
# 清理 dist/
fsp c
也可指定项目目录与选项:
fsp b /path/to/project --mirror aliyun --py-version 3.11.9 --target windows
命令参考
全局选项:-V/--version 显示版本,-v/--verbose 开启 DEBUG 级别日志。
| 命令 | 别名 | 说明 |
|---|---|---|
fsp build |
fsp b |
打包项目,生成 dist/ 下可执行文件与运行时 |
fsp run |
fsp r |
运行已打包项目(Linux 原生直跑,.exe 自动用 wine) |
fsp clean |
fsp c |
清理 dist/ 目录 |
fsp package |
fsp p |
生成安装包(Windows NSIS / Linux .deb + tar.gz) |
fsp build
fsp b [project] [--mirror <name>] [--py-version <ver>] [--target <platform>]
project:项目目录,默认当前目录--mirror:镜像源(aliyun/huawei/tsinghua),默认 aliyun--py-version:embed python 版本,默认 3.11.9(Windows)/ 3.11.10(Linux,匹配 python-build-standalone release)--target:目标平台(windows/linux),默认当前平台
fsp run
fsp r [project] [--entry <name>] [--debug] [-- <args>...]
project:项目目录,默认当前目录--entry <name>:多入口项目指定要运行的入口名(与[tool.fspack.entries]键匹配),单入口项目可省略--debug:用 embed python 直跑入口脚本(绕过 GUI loader,输出可见)-- <args>:透传给目标程序的参数(--分隔)
fsp clean
fsp c [project]
fsp package
fsp p [project] [--mirror <name>] [--py-version <ver>] [--target <plat>] [--no-build]
--target:目标平台(windows/linux),默认当前平台--no-build:跳过重建,直接打包已有 dist(需先fsp b)
按目标平台分发:Windows 走 NSIS 生成 dist/release/<name>-setup.exe;Linux 走 dpkg-deb 生成 dist/release/<name>_<ver>_amd64.deb 与 dist/release/<name>-<ver>-linux.tar.gz 便携包。
工作原理
fsp b 构建流水线:
- 解析
pyproject.toml,识别项目名、版本、入口模块、CLI/GUI 类型 - 下载运行时:Windows 下载 embed python zip 并解压到
dist/runtime/;Linux 下载 python-build-standalone tar.gz 并解压到dist/runtime/python/ - 分析依赖:AST 扫描源码 import,分类标准库/本地/第三方,与
pyproject.toml声明依赖比对 - 下载 wheel:用 dev python 的
pip download拉取目标平台 wheel,解包到dist/runtime/Lib/site-packages/(Windows)或dist/runtime/python/lib/python3.X/site-packages/(Linux) - 写 _pth(仅 Windows):覆盖
runtime/python3X._pth,注册 site-packages 与..\src路径 - 复制源码:项目源码复制到
dist/src/,排除 dist/build/.venv 等构建产物 - 生成 C loader:按平台模板生成 C 源码(烧入入口脚本相对路径),mingw(Windows)或 gcc(Linux)编译为可执行文件
dist 布局:
dist/
├── <name>.exe # C loader 启动器
├── runtime/ # Python 运行时
│ ├── python311.dll # Windows embed
│ ├── python311._pth
│ └── Lib/site-packages/ # 第三方依赖
├── src/ # 用户源码
└── release/ # 安装包(fsp p 产出)
├── <name>-setup.exe # Windows NSIS
├── <name>_<ver>_amd64.deb # Linux .deb
└── <name>-<ver>-linux.tar.gz # Linux 便携包
多入口打包
单个项目可通过 [tool.fspack.entries] 声明多个入口,每个入口生成独立 exe,
共享 runtime/依赖/源码。每个入口按自身脚本 import 推断 CLI/GUI 类型,支持
cli/gui/web 混合。
[project]
name = "my_app"
version = "0.1.0"
dependencies = ["PySide2>=5.15.2", "flask"]
[tool.fspack.entries]
cli = "cli.py" # 生成 cli.exe(CLI 类型)
gui = "gui.py" # 生成 gui.exe(GUI 类型,加 -mwindows)
web = "web.py" # 生成 web.exe(CLI 类型)
fsp b # 构建:生成 cli.exe/gui.exe/web.exe 三个入口
fsp r --entry cli # 运行 cli 入口
fsp r --entry gui # 运行 gui 入口
fsp r --entry web # 运行 web 入口
多入口模式下每个入口写入 <name>.entry 文件,C loader 运行时按
<exe_basename>.entry 查找入口脚本。单入口项目(无 [tool.fspack.entries])
仍写 .entry 文件,向后兼容。
示例
examples/ 下提供多类典型项目验证打包效果(下划线命名者由 slow 端到端测试覆盖):
| 示例 | 类型 | 说明 |
|---|---|---|
| cli_helloworld | 无库 CLI | 最小示例,验证基础流水线 |
| cli_tool | 有库 CLI | requests 依赖,验证 wheel 下载与解包 |
| cli_complex | 无库 CLI | 展示型,多文件结构 |
| cli_office | 有库 CLI | pypdf 依赖,uv workspace 成员 |
| gui_calc | 有库 GUI | PySide6 依赖,验证 GUI 快捷方式与 DLL 搜索 |
| pyside2_app | 有库 GUI | PySide2 依赖,验证 requires-python 版本自动解析 |
| pyqt5_cli | 有库 GUI | PyQt5 依赖,验证 Python 3.12 兼容 |
| pygame_cli | 有库 pygame | pygame 依赖,验证多媒体库打包 |
| pygame_snake | 有库 pygame | pygame 贪吃蛇,验证 dummy 驱动运行 |
| web_app | 有库 web | flask 依赖,验证 web 框架打包 |
| multi_entry | 多入口混合 | cli+gui+web 三入口共享 runtime/依赖,验证 [tool.fspack.entries] 多入口打包 |
平台支持
| 平台 | 运行时 | 编译器 | 安装包 |
|---|---|---|---|
| Windows | embed python(python.org) | mingw-w64 交叉编译 | NSIS(.exe) |
| Linux | python-build-standalone(indygreg) | gcc | .deb + tar.gz |
Linux dev 机可交叉编译 Windows 包(fsp b --target windows),反之亦然。
已知限制
Windows 打包不支持 tkinter
fspack Windows 运行时使用 python.org 官方 embeddable package
(精简版,约 10MB),该发行版为控制体积裁剪了 tkinter 相关文件(Lib/tkinter/、
_tkinter.pyd、tcl/、tk/)。因此 import tkinter 的应用在 Windows 打包后运行会报:
ModuleNotFoundError: No module named 'tkinter'
替代方案:
- 改用 PySide2/PySide6/PyQt5/PyQt6 等 Qt 框架(fspack 已验证支持,见
examples/gui_calc、examples/pyside2_app、examples/pyqt5_cli) - 在 Linux 打包(fspack Linux 运行时用 python-build-standalone,含完整标准库,含 tkinter):
fspack b --target linux
missing 依赖误报导入名≠包名
fsp b 日志中 AST 发现未声明依赖 提示可能误报:当导入名与 PyPI 包名不一致时
(如 import yaml 对应包名 PyYAML、import PIL 对应 Pillow),即使 pyproject.toml
已正确声明依赖,missing 比较归一化包名仍会提示未声明。不影响打包功能(declared
优先下载),仅日志有误导性。
CI/CD 集成
fspack 可集成到其他 Python 项目的 CI/CD 工作流,实现自动打包与打包成功验证。提供两个可复用的 GitHub Actions workflow 模板:
templates/pack-check.yml— PR 验证打包(push/PR 触发,验证打包不破坏)templates/release-pack.yml— Release 发布安装包(tag 触发,矩阵打包 Windows + Linux 安装包附到 GitHub Release)
快速上手
-
复制模板到你的项目:
cp templates/pack-check.yml your-project/.github/workflows/ cp templates/release-pack.yml your-project/.github/workflows/
-
在仓库 Settings → Secrets and variables → Actions → Variables 配置:
变量名 说明 示例值 PROJECT_NAME项目名(与 pyproject.toml的name一致)my_appEXPECTED_OUTPUT运行打包后 exe 应输出的预期字符串 hello from my_app -
触发:push 到 main 验证打包,打 tag(
git tag v0.1.0)发布安装包。
测试打包成功的三层反馈
| 阶段 | 成功反馈 | 失败反馈 |
|---|---|---|
| 构建 | fsp b 退出码 0 + 产物断言通过 |
退出码非零,上传 dist/ 供调试 |
| 运行 | grep 命中预期字符串 | grep 失败,输出实际内容到日志 |
| 安装包 | 文件存在 + 魔数校验(MZ/!<arch>/gzip) |
文件缺失或魔数错误 |
完整集成方案见 CI/CD 集成指南。
开发
# 安装开发依赖
uv sync --extra dev
# 运行测试(含覆盖率,阈值 95%)
uv run pytest -m "not slow" --cov=fspack --cov-fail-under=95
# 类型检查
uv run pyrefly check
# 代码风格
uv run ruff check src tests
uv run ruff format --check src tests
Make 快捷命令
项目提供 Makefile 封装常用操作,运行 make help 查看全部命令:
make sync # 安装开发依赖
make check # 全套门禁 (lint + typecheck + cov)
make build # 构建分发包
make clean # 清理构建产物
make bump PART=patch # 版本号 bump
文档
文档由 Sphinx 构建,托管在 ReadTheDocs:
make doc
多版本测试
使用 tox 在多个 Python 版本(py38, py39, py310, py311, py312, py313, py314)下运行测试:
make tox
许可证
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fspack-0.1.1.tar.gz.
File metadata
- Download URL: fspack-0.1.1.tar.gz
- Upload date:
- Size: 277.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8590c812b08297666954d952a57150468ceb1fa14dc607feb4956b50b5695076
|
|
| MD5 |
72f75fbe7ead87b1e1e4607f0d992877
|
|
| BLAKE2b-256 |
a182123bc60bce8bef91eb7f336cbcbd83d162826fb5e059fba8c33dbe8ae78b
|
File details
Details for the file fspack-0.1.1-py3-none-any.whl.
File metadata
- Download URL: fspack-0.1.1-py3-none-any.whl
- Upload date:
- Size: 51.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23d94e61ddac10d0e4f703b31edbf2d5044ed60d80ecdc67e1f8f426d135b866
|
|
| MD5 |
f6dbaa4929a218e90c93e36a8cc491bf
|
|
| BLAKE2b-256 |
48fdebce547d4300c66c519c80d5e7ae939d6896421d9f65e31abe2a18243d31
|