Skip to content

项目打包教程

概述

UnifyPy 2.0是一个企业级跨平台Python应用打包解决方案,支持将Python项目打包为Windows、macOS、Linux平台的原生安装包。相比1.0版本,2.0版本引入了并行构建、智能路径处理、企业级回滚系统等新特性。小智客户端已配置了相应的打包配置文件,本教程将指导您如何使用UnifyPy 2.0进行打包。

✨ UnifyPy 2.0 新特性

  • 🔄 跨平台支持: Windows (EXE)、macOS (DMG)、Linux (DEB)
  • 🛡️ 企业级功能: 自动回滚、会话管理、智能错误处理
  • 🎨 优秀体验: Rich进度条、分阶段显示、详细日志
  • 📊 智能路径处理: 相对路径自动解析为绝对路径
  • 🍎 macOS权限管理: 自动生成权限文件、代码签名支持

准备工作

1. 安装py-xiaozhi项目依赖

首先确保您已激活了py-xiaozhi项目的Python环境,并安装所有项目依赖:

bash
# 进入py-xiaozhi项目目录
cd /path/to/py-xiaozhi

# 根据平台安装项目依赖
pip install -r requirements.txt        # Windows/Linux
# 或
pip install -r requirements_mac.txt    # macOS

2. 在项目环境中安装UnifyPy依赖

在同一个环境中安装UnifyPy所需的依赖:

  • 理论上安装py-xiaozhi的环境默认就自带了,如果不行就重新执行下
bash
# 一键安装UnifyPy所需的所有依赖
pip install pyinstaller==6.15.0 rich==14.1.0 requests==2.32.3 packaging==25.0 pillow==11.3.0

3. 获取UnifyPy 2.0

bash
# 克隆UnifyPy仓库(建议放在和py-xiaozhi同级目录)
git clone https://github.com/huangjunsen0406/UnifyPy.git

4. 验证环境配置

验证所有依赖都在当前环境中正常工作:

bash
# 验证UnifyPy依赖
python -c "import pyinstaller, rich, requests, packaging, pillow; print('✅ UnifyPy依赖安装成功')"

# 验证py-xiaozhi项目依赖(根据实际情况调整)
python -c "import numpy, PyQt5; print('✅ py-xiaozhi项目依赖可用')"

# 显示当前环境信息
echo "当前环境: $(which python)"
echo "Python版本: $(python --version)"

为什么要在同一环境安装?

UnifyPy使用PyInstaller打包,需要访问当前环境中的所有Python包进行依赖分析。如果依赖分散在不同环境中,PyInstaller无法正确打包。

3. 安装平台特定工具

Windows平台

  • 安装Inno Setup(用于创建安装程序)
  • 安装后,在build.json中配置Inno Setup路径,或设置环境变量INNO_SETUP_PATH
  • 把UnifyPy下的ChineseSimplified.isl复制到inno setup安装目录下language里 (windows)

macOS平台

  • UnifyPy 2.0内置了create-dmg工具,无需单独安装

Linux平台

安装DEB打包工具:

bash
# DEB格式(Debian/Ubuntu)
sudo apt-get install dpkg-dev fakeroot

Linux编译环境准备(重要):

bash
# 安装必要的开发工具和库
sudo apt update
sudo apt install -y build-essential python3-dev python3-pip python3-setuptools \
    libopenblas-dev liblapack-dev gfortran patchelf autoconf automake \
    libtool cmake libssl-dev libatlas-base-dev

# 安装现代构建系统
pip install meson ninja
sudo apt install -y meson ninja-build

打包配置详解

小智客户端已经提供了预配置的build.json文件。UnifyPy 2.0支持更丰富的配置选项和智能路径处理,以下是各配置项的详细说明:

智能路径处理

UnifyPy 2.0引入了智能路径处理功能,配置文件中的相对路径会自动解析为相对于目标项目目录的绝对路径:

  • "icon": "assets/icon.png"/path/to/project/assets/icon.png
  • "add_data": ["data:data"]/path/to/project/data:data
  • ✅ 支持嵌套配置和平台特定路径

基本配置

json
{
    "name": "xiaozhi",                  // 应用程序名称,将用于可执行文件和安装程序名称
    "version": "1.0.0",                 // 应用程序版本号
    "publisher": "Junsen",              // 发布者名称
    "entry": "main.py",                 // 程序入口文件
    "icon": "assets/xiaozhi_icon.ico",  // 应用图标路径
    "hooks": "hooks",                   // PyInstaller钩子目录
    "onefile": false,                   // 是否生成单文件模式的可执行文件
    
    // PyInstaller通用参数,适用于所有平台
    "additional_pyinstaller_args": "--add-data assets;assets --add-data libs;libs --add-data src;src --add-data models;models --hidden-import=PyQt5",
    
    // Inno Setup路径(Windows平台需要)
    "inno_setup_path": "E:\\application\\Inno Setup 6\\ISCC.exe",
    
    // 其他配置...
}

注意:JSON文件不支持注释,上述代码中的注释仅用于说明,实际配置文件中不应包含注释。

平台特定配置

Windows平台配置

json
"windows": {
    "format": "exe",                  // 输出格式
    "additional_pyinstaller_args": "--add-data assets;assets --add-data libs;libs --add-data src;src --add-data models;models --hidden-import=PyQt5 --noconsole",
    "desktop_entry": true,            // 是否创建桌面快捷方式
    "installer_options": {
        "languages": ["ChineseSimplified", "English"],  // 安装程序支持的语言
        "license_file": "LICENSE",                      // 许可证文件
        "readme_file": "README.md",                     // 自述文件
        "create_desktop_icon": true,                    // 是否创建桌面图标
        "allow_run_after_install": true                 // 安装后是否允许立即运行
    }
}

Linux平台配置

json
"linux": {
    "format": "deb",                  // 输出格式:deb
    "desktop_entry": true,            // 是否创建桌面快捷方式
    "categories": "Utility;Development;",  // 应用程序类别
    "description": "小智Ai客户端",          // 应用描述
    "requires": "libc6,libgtk-3-0,libx11-6,libopenblas-dev",  // 依赖项
    "additional_pyinstaller_args": "--add-data assets:assets --add-data libs:libs --add-data src:src --add-data models:models --hidden-import=PyQt5"
}

macOS平台配置

json
"macos": {
    "format": "app",                  // 输出格式,可选值:app, dmg
    "additional_pyinstaller_args": "--add-data assets:assets --add-data libs:libs --add-data src:src --add-data models:models --hidden-import=PyQt5 --windowed",
    "app_bundle_name": "XiaoZhi.app", // 应用包名称
    "bundle_identifier": "com.junsen.xiaozhi",  // 应用标识符
    "sign_bundle": false,             // 是否签名应用包
    "create_dmg": true,               // 是否创建DMG镜像
    "installer_options": {
        "license_file": "LICENSE",    // 许可证文件
        "readme_file": "README.md"    // 自述文件
    }
}

其他重要配置项

json
"build_installer": true  // 是否构建安装程序,设为false只生成可执行文件

提示:UnifyPy自动生成的.unifypy文件夹包含所有平台的打包配置,无需手动维护。如需自定义,可直接编辑对应平台的配置文件。

Windows应用程序标识符(AppId)管理

UnifyPy 2.0会自动管理Windows安装程序的AppId,无需手动修改模板文件。

自动生成机制

第一次打包时,UnifyPy会在项目根目录自动创建.unifypy文件夹,包含各平台的配置文件:

项目目录/
├── .unifypy/
│   ├── cache/             # 构建缓存
│   ├── linux/
│   │   ├── app.desktop    # Linux桌面文件
│   │   └── control        # DEB包控制文件
│   ├── macos/
│   │   ├── dmg_config.json # DMG配置
│   │   └── Info.plist     # macOS应用信息
│   ├── windows/
│   │   └── setup.iss      # Inno Setup脚本(包含AppId)
│   ├── .gitignore         # Git忽略规则
│   └── metadata.json      # 项目元数据
├── build.json
└── main.py

自定义AppId(可选)

如果需要使用企业特定的AppId,可以在首次打包前手动编辑.unifypy/windows/setup.iss文件:

ini
[Setup]
AppId={{{您的企业GUID}}}  ; 替换为企业自定义GUID
AppName=小智
AppVersion=1.0.0
; ...(其他配置)

或者在metadata.json中配置

json
{
  "project_name": "xiaozhi",
  "app_id": "{您的企业GUID}",
  "created_date": "2024-01-01T00:00:00Z",
  "last_modified": "2024-01-01T00:00:00Z"
}

获取企业GUID的方式

  • 在线生成工具:Online GUID Generator
  • Visual Studio命令:Tools > Create GUID
  • PowerShell命令:[System.Guid]::NewGuid()

文件管理建议

  1. 版本控制:将.unifypy文件夹加入Git版本控制,但排除缓存目录:

    gitignore
    # 在项目根目录的.gitignore中添加
    .unifypy/cache/
  2. AppId管理:一旦生成AppId,建议不要随意更改,以避免安装程序升级时的冲突问题

  3. 团队协作:确保所有团队成员使用相同UnifyPy配置,特别是Windows的AppId

执行打包

环境准备

重要:打包前确保UnifyPy和目标项目在同一环境中:

bash
# 激活统一环境
conda activate packaging-env  # 或 source build_env/bin/activate

# 验证环境
which python
python -c "import rich, requests, numpy, PyQt5; print('Environment ready')"

UnifyPy 2.0 基本打包命令

建议UnifyPy放在和py-xiaozhi项目同级目录下:

bash
# 基本打包(推荐)
python ../UnifyPy/main.py . --config build.json

# 详细输出模式
python ../UnifyPy/main.py . --config build.json --verbose

# 清理重新构建
python ../UnifyPy/main.py . --config build.json --clean --verbose

# 只生成可执行文件,跳过安装包
python ../UnifyPy/main.py . --config build.json --skip-installer

# 指定特定格式
python ../UnifyPy/main.py . --config build.json --format exe   # Windows
python ../UnifyPy/main.py . --config build.json --format dmg   # macOS  
python ../UnifyPy/main.py . --config build.json --format deb   # Linux

主要命令行选项

参数说明示例
--clean清理之前的构建文件--clean
--skip-exe跳过可执行文件构建--skip-exe
--skip-installer跳过安装程序构建--skip-installer
--format FORMAT指定输出格式(exe/dmg/deb)--format deb
--developmentmacOS开发模式(自动权限配置)--development
--list-rollback列出可用的回滚会话--list-rollback
--rollback SESSION_ID执行指定会话的回滚--rollback abc123

针对不同平台的打包命令

Windows平台

bash
python C:\路\到\UnifyPy\main.py . --config build.json

macOS平台

bash
python /路径/到/UnifyPy/main.py . --config build.json

Linux平台(DEB格式)

  1. 准备环境

    bash
    # 更新系统并安装必要的依赖
    sudo apt update
    sudo apt install -y build-essential python3-dev python3-pip python3-setuptools libopenblas-dev liblapack-dev gfortran patchelf autoconf automake libtool cmake libssl-dev libatlas-base-dev
  2. 执行打包

    确保build.json中linux.format设置为"deb",然后执行:

    bash
    python3 /路径/到/UnifyPy/main.py . --config build.json

Linux平台依赖处理注意事项

NumPy编译环境配置(重要)

⚠️ 重要提醒: 不要删除NumPy!正确的做法是确保编译环境配置正确。

bash
# 方案1: 推荐方案 - 确保NumPy依赖正确编译
# 设置环境变量
export BLAS=openblas
export LAPACK=openblas
export NPY_NUM_BUILD_JOBS=$(nproc)  # 使用所有CPU核心加速编译

# 验证当前NumPy是否可用
python -c "import numpy; print('NumPy version:', numpy.__version__); print('BLAS info:', numpy.show_config())"

# 如果上述命令成功,则无需重新编译

替代方案: 使用conda管理依赖(推荐用于复杂环境):

bash
# 安装conda/miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

# 创建环境并安装依赖
conda create -n build_env python=3.9
conda activate build_env
conda install numpy scipy openblas-devel
pip install -r requirements.txt

打包输出

成功打包后,将在项目根目录下的dist文件夹中找到打包的应用程序:

  • Windows:

    • 可执行文件(.exe)位于dist/xiaozhi目录
    • 安装程序位于dist/installer目录,命名为xiaozhi-1.0.0-setup.exe
  • macOS:

    • 应用程序包(.app)位于dist/xiaozhi目录
    • 磁盘镜像(.dmg)位于dist/installer目录,命名为xiaozhi-1.0.0.dmg
  • Linux:

    • 可执行文件位于dist/xiaozhi目录
    • DEB安装包位于dist/installer目录:xiaozhi-1.0.0.deb

高级配置选项

PyInstaller参数

additional_pyinstaller_args字段中,您可以添加任何PyInstaller支持的参数。以下是一些常用参数:

  • --noconsole: 不显示控制台窗口(仅适用于图形界面程序)
  • --windowed: 等同于--noconsole
  • --hidden-import=MODULE: 添加隐式导入的模块
  • --add-data SRC;DEST: 添加数据文件(Windows平台使用分号分隔)
  • --add-data SRC:DEST: 添加数据文件(macOS/Linux平台使用冒号分隔)
  • --icon=FILE.ico: 设置应用程序图标

处理特殊依赖

某些Python库可能需要特殊处理才能正确打包,可以通过以下方式解决:

  1. 使用钩子文件:在hooks目录中创建自定义钩子,处理特殊导入情况
  2. 添加隐式导入:使用--hidden-import参数显式包含隐式导入的模块
  3. 添加数据文件:使用--add-data参数包含程序运行所需的数据文件

UnifyPy 2.0 新功能详解

🔄 回滚系统

UnifyPy 2.0引入了企业级回滚系统,自动跟踪构建操作:

bash
# 列出可用的回滚会话
python ../UnifyPy/main.py . --list-rollback

# 执行回滚到指定会话
python ../UnifyPy/main.py . --rollback SESSION_ID

# 禁用自动回滚(提升性能)
python ../UnifyPy/main.py . --config build.json --no-rollback

🍎 macOS自动权限管理

UnifyPy 2.0为macOS应用提供完整的权限管理方案:

bash
# 开发模式 - 自动生成权限文件,适合开发和测试
python ../UnifyPy/main.py . --config build.json --development

# 生产模式 - 用于已签名应用
python ../UnifyPy/main.py . --config build.json --production

自动化功能

  • ✅ 自动生成 entitlements.plist
  • ✅ 自动更新 Info.plist 权限描述
  • ✅ 自动 ad-hoc 代码签名
  • ✅ 自动图标格式转换(PNG → ICNS)

常见问题及解决方案

Windows平台常见问题

  1. 找不到Inno Setup

    解决方案:确保已安装Inno Setup,并在build.json中正确配置路径,或设置环境变量INNO_SETUP_PATH

  2. 缺少隐式导入的模块

    解决方案:在additional_pyinstaller_args中添加--hidden-import=模块名称

  3. 打包后无法找到资源文件

    解决方案:确保使用相对路径访问资源文件,并使用--add-data参数正确包含资源文件

macOS平台常见问题

  1. 创建DMG出错

    解决方案:UnifyPy 2.0内置create-dmg工具,如果仍有问题请检查macOS权限设置

  2. 签名问题

    解决方案:如果需要签名,在配置文件中启用sign_bundle并提供有效的开发者身份

  3. 动态库加载问题

    解决方案:确保代码中正确处理库路径,特别是使用sys._MEIPASS路径

Linux平台常见问题

  1. 缺少依赖库

    解决方案:在Linux配置中的requires字段中添加所需的系统依赖

  2. 打包工具不可用

    解决方案:确保已安装DEB打包工具(dpkg-dev, fakeroot)

  3. 权限问题

    解决方案:确保脚本有正确的执行权限,对某些资源目录可能需要特别处理

  4. NumPy编译失败(Linux特有问题)

    症状: 出现编译错误、缺少BLAS/LAPACK库等

    解决方案:

    bash
    # 方案1: 检查并安装缺失的开发库
    sudo apt install -y libopenblas-dev liblapack-dev gfortran
    
    # 方案2: 使用预编译的wheel包(推荐)
    pip install numpy --force-reinstall
    
    # 方案3: 设置正确的环境变量
    export BLAS=openblas
    export LAPACK=openblas
    export NPY_NUM_BUILD_JOBS=4
    
    # 方案4: 使用conda环境(最稳定)
    conda install numpy scipy openblas-devel
  5. PyInstaller在Linux上的依赖问题

    症状: 打包后的程序在其他Linux系统上无法运行

    解决方案:

    bash
    # 使用静态链接
    pip install staticx
    
    # 或者在较老的Linux发行版上构建
    # 推荐使用Ubuntu 18.04或CentOS 7作为构建环境
  6. 依赖冲突处理(最常见问题)

    症状: 打包过程中出现模块导入错误、版本冲突或PyInstaller分析失败

    根本原因: UnifyPy和目标项目的依赖版本不兼容或环境不统一

    解决方案:

    bash
    # 方案1: 统一conda环境(强烈推荐)
    conda create -n unified-packaging python=3.9
    conda activate unified-packaging
    
    # 先安装UnifyPy依赖
    cd /path/to/UnifyPy
    pip install -r requirements.txt
    
    # 再安装目标项目依赖
    cd /path/to/py-xiaozhi
    pip install -r requirements.txt
    
    # 验证环境完整性
    python -c "import rich, requests, packaging, pillow, numpy, PyQt5; print('✅ All dependencies OK')"
    
    # 方案2: 在目标项目环境中补充UnifyPy依赖
    pip install rich>=12.0 requests>=2.28 packaging>=21.0 pillow>=8.0
    
    # 方案3: 使用requirements合并文件
    cat /path/to/UnifyPy/requirements.txt requirements.txt > combined_requirements.txt
    pip install -r combined_requirements.txt

最佳实践

通用最佳实践

  1. 环境统一管理:使用conda创建专用打包环境,避免依赖冲突

    bash
    conda create -n packaging-env python=3.9
    conda activate packaging-env
    # 安装UnifyPy和目标项目的所有依赖
  2. 清理项目:打包前移除临时文件、缓存和不必要的大型文件

  3. 依赖验证:确保UnifyPy和目标项目的依赖都在同一环境中正确安装

    bash
    # 验证关键依赖
    python -c "import rich, requests, packaging; print('UnifyPy dependencies OK')"
    python -c "import numpy, PyQt5; print('Target project dependencies OK')"
  4. 智能路径管理:利用UnifyPy 2.0的智能路径处理,配置文件中使用相对路径

  5. 验证配置:确保build.json中的配置与您的环境一致

  6. 多平台测试:如果条件允许,在多个平台上测试打包的应用程序

  7. 保存配置:为不同的打包场景保存不同版本的配置文件,方便复用

  8. 版本管理:每次发布前更新版本号,保持版本一致性

UnifyPy 2.0 特定最佳实践

  1. 启用详细日志:使用--verbose参数便于问题排查

    bash
    python ../UnifyPy/main.py . --config build.json --verbose
  2. 利用回滚系统:构建前了解回滚功能,必要时快速恢复

    bash
    # 构建前查看可用会话
    python ../UnifyPy/main.py . --list-rollback
  3. macOS权限配置:使用自动权限管理简化macOS打包

    bash
    # 开发阶段使用开发模式
    python ../UnifyPy/main.py . --config build.json --development

Linux平台特定最佳实践

  1. 统一打包环境:在同一conda环境中安装UnifyPy和目标项目依赖

    bash
    # 创建专用打包环境(推荐)
    conda create -n packaging-env python=3.9
    conda activate packaging-env
    
    # 按顺序安装依赖,避免冲突
    pip install -r /path/to/UnifyPy/requirements.txt
    pip install -r /path/to/py-xiaozhi/requirements.txt
    
    # 验证关键依赖
    python -c "import rich, numpy, PyQt5; print('Dependencies OK')"
  2. NumPy处理策略:优先使用预编译包,避免不必要的源码编译

    bash
    # 检查NumPy状态
    python -c "import numpy; print(numpy.__version__, numpy.show_config())"
  3. Linux打包注意事项

    • DEB格式: 适用于Debian/Ubuntu系统的正式分发
    • 构建环境: 使用较老的Linux发行版构建以确保兼容性
    • 推荐:Ubuntu 18.04 LTS 或 Ubuntu 20.04 LTS
    • 避免:过新的发行版可能导致兼容性问题