# uos_python_installer **Repository Path**: open_soft_bhy/uos_python_installer ## Basic Information - **Project Name**: uos_python_installer - **Description**: uos系统python部署实例 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-30 - **Last Updated**: 2026-07-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # uos_python_installer > PyInstaller 多平台打包示例,适配统信 UOS / 国产 CPU 架构 本项目演示如何使用 [PyInstaller](https://pyinstaller.org/) 把 Python + PySide6 应用打包为可在 **统信 UOS / 麒麟 / deepin / 通用 Linux / Windows / macOS** 上原生运行的可执行文件,并特别处理国产 CPU 架构(x86_64 / aarch64 / loongarch64 / mips64el)下的常见兼容性问题。 ## 目录结构 ``` uos_python_installer/ ├── src/myapp/ # 示例应用源码 (PySide6 GUI) │ ├── __init__.py │ ├── __main__.py # 入口:python -m myapp │ ├── env.py # 运行时环境探测 (平台/架构/UOS) │ ├── main_window.py # 主窗口 │ └── assets/ # 资源文件 (图标等) │ ├── icon.svg │ └── README.md ├── build/ │ ├── myapp.spec # PyInstaller spec (多平台分支) │ ├── build.py # 统一打包入口 (跨平台) │ ├── build.sh # Linux/macOS 薄封装 │ ├── build.bat # Windows 薄封装 │ ├── hooks/ │ │ └── uos_runtime_hook.py # UOS 运行时适配 hook │ └── platform/ │ └── linux/ │ ├── myapp.desktop # UOS/DDE 桌面集成 │ ├── install-deps-uos.sh# 安装系统依赖 │ └── install-uos.sh # 安装应用到系统菜单 ├── .github/workflows/build.yml # 多平台 CI 示例 ├── pyproject.toml # 项目元数据 ├── requirements.txt # 运行时依赖 ├── requirements-build.txt # 打包依赖 └── README.md / README.en.md ``` ## 支持的目标平台 | 操作系统 | 架构 | 支持状态 | 备注 | |---|---|---|---| | 统信 UOS | x86_64 | ✅ 完整 | 主要目标 | | 统信 UOS | aarch64 (鲲鹏/飞腾) | ✅ 完整 | 需在对应 UOS 机构建 | | 统信 UOS | loongarch64 (龙芯) | ⚠️ 需自构建 | PyInstaller 无预编译 bootloader,见下文 | | 统信 UOS | mips64el (龙芯旧指令集) | ⚠️ 需自构建 | 同上 | | 麒麟 / deepin / 通用 Debian | x86_64, aarch64 | ✅ | 与 UOS 流程一致 | | Windows | x86_64 | ✅ | | | macOS | x86_64, arm64 | ✅ | Apple Silicon 原生 | ## 快速开始 ### 1. 准备环境 ```bash # 开发依赖 (运行时 + 打包) pip install -r requirements.txt pip install -r requirements-build.txt ``` ### 2. 开发模式运行 ```bash python -m myapp ``` ### 3. 打包 ```bash # Linux / UOS / macOS bash build/build.sh # onedir (默认) bash build/build.sh --onefile # 单文件 bash build/build.sh --clean # 清理后打包 # Windows build\build.bat build\build.bat --onefile # 或直接调用跨平台入口 python build/build.py ``` 产物输出到 `dist/myapp/` (onedir) 或 `dist/myapp` (onefile)。 ### 4. 在 UOS 上安装到开始菜单 ```bash # 先安装系统依赖 (一次性) sudo bash build/platform/linux/install-deps-uos.sh # 安装应用到系统菜单 sudo bash build/platform/linux/install-uos.sh dist/myapp ``` 之后在 UOS 开始菜单中搜索 "myapp" 即可启动。卸载: ```bash sudo bash build/platform/linux/install-uos.sh dist/myapp --uninstall ``` ## 国产架构构建说明 ### x86_64 / aarch64 PyInstaller 官方 wheel 提供这两个架构的预编译 bootloader,直接 `pip install pyinstaller` 即可。 ### loongarch64 / mips64el PyInstaller **官方不提供** 这两个架构的预编译 bootloader。在龙芯 UOS 上需要从源码构建 bootloader: ```bash # 1. 安装编译工具 sudo apt-get install -y build-essential python3-dev zlib1g-dev # 2. 从源码安装 PyInstaller (会自动编译当前架构的 bootloader) pip install --no-binary pyinstaller pyinstaller # 验证 bootloader 已编译 python3 -c "from PyInstaller.config import CONF; print('bootloader ok')" ``` 如果上述 `pip install` 未自动触发 bootloader 编译(部分版本),手动执行: ```bash python3 -m PyInstaller.utils.cli build_bootloader # 或 cd $(python3 -c "import PyInstaller; import os; print(os.path.dirname(PyInstaller.__file__))") python3 bootloader/waf configure build install ``` ### 跨架构构建的不可行性 PyInstaller **不能交叉打包**——必须在目标架构的 UOS 机器上执行打包。这是 PyInstaller 的固有限制(它需要扫描当前 Python 环境的 .so 依赖)。因此国产架构产物需在对应的 UOS 物理机或 QEMU 虚拟机中构建。 ## UOS 适配细节 本项目针对 UOS 做了以下适配: ### 1. PySide6 / Qt 平台插件 - spec 中通过 `collect_data_files('PySide6')` 完整收集 Qt 插件(platforms、imageformats、platformthemes 等) - runtime hook 设置 `QT_QPA_PLATFORM_PLUGIN_PATH`,避免 "could not load Qt platform plugin xcb" - 默认 `QT_QPA_PLATFORM=xcb`(UOS DDE 默认 X11 会话) ### 2. 字体与中文显示 - 不打包系统字体(避免版权与体积问题),依赖宿主 UOS 预装字体(思源黑体 / Noto Sans CJK) - spec 打包 `/etc/fonts/fonts.conf`,runtime hook 设置 `FONTCONFIG_FILE` 指向 bundle 内副本 - `install-deps-uos.sh` 兜底安装 `fonts-noto-cjk` `fonts-wqy-zenhei` ### 3. 系统库依赖 - 国产架构上 Qt 的 xcb 平台插件依赖大量 `libxcb-*` 库 - `install-deps-uos.sh` 一键安装全部运行时系统库 ### 4. DDE 桌面集成 - `.desktop` 文件遵循 [freedesktop.org Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/latest/) - 安装到 `/usr/share/applications/`,图标到 `/usr/share/icons/hicolor/scalable/apps/` - `StartupWMClass` 设为应用名,确保 UOS 任务栏正确分组 - `install-uos.sh` 自动调用 `update-desktop-database` 与 `gtk-update-icon-cache` 刷新缓存 ### 5. UPX 压缩 - **默认关闭**。`upx` 在 loongarch64 / mips64el 上对国产架构 ELF 二进制有兼容性问题,可能产生运行时崩溃 - x86_64 / aarch64 如需减小体积,可通过 `python build/build.py --upx` 启用 ## glibc 兼容性建议 Linux 二进制的跨发行版可移植性受 glibc 版本约束:**在低版本 glibc 上构建的产物可运行于高版本,反之不行**。 - UOS 1060 (基于 Debian 10) glibc ≈ 2.28 - UOS 1070 (基于 Debian 11) glibc ≈ 2.31 - Ubuntu 22.04 glibc ≈ 2.35 为获得最佳兼容性,**建议在最低目标 glibc 版本的 UOS 上构建**。如需同时支持多个 UOS 版本,在最旧的 UOS 机器上打包即可。 ## CI 多平台构建 `.github/workflows/build.yml` 演示了: - GitHub 托管 runner:linux-x86_64 / linux-aarch64 / macos-x86_64 / macos-arm64 / windows-x86_64 - 自托管 runner:loongarch64 / mips64el(需自建 UOS 构建机,打 label `self-hosted`) - tag 触发时自动上传到 GitHub Release Gitee 用户可参考此工作流改写为 [Gitee Go](https://gitee.com/help/categories/79) 流水线。 ## 常见问题 **Q: 打包后启动报 "could not find or load the Qt platform plugin xcb"?** A: 运行 `sudo bash build/platform/linux/install-deps-uos.sh` 安装系统 xcb 依赖;确认 spec 中 `collect_data_files('PySide6')` 已执行。 **Q: GUI 中文显示为方框?** A: 安装中文字体:`sudo apt-get install fonts-noto-cjk`;UOS 通常预装,自建精简系统需手动装。 **Q: loongarch64 上 `pip install pyinstaller` 报 "no matching distribution"?** A: PyInstaller 无该架构预编译 wheel,需源码安装见上文「国产架构构建说明」。 **Q: onefile 模式启动慢?** A: onefile 每次启动需解压到 /tmp,正常现象。生产环境推荐 onedir。 ## 技术资料:UOS / 国产 Linux 上 PyInstaller 打包要点 > 本章节汇总在本项目实践中验证有效的 PyInstaller + UOS 适配要点,供二次开发与故障排查参考。部分内容基于 PyInstaller 官方文档、GitHub issues 与国产 Linux 社区经验整理;标注「⚠️ 待核实」的内容建议在目标环境实测确认。 ### 1. PyInstaller 工作原理速览 PyInstaller 把 Python 应用与解释器、依赖库打包为自包含可执行文件,分两阶段: 1. **构建期**:扫描入口脚本导入树,收集 `.py`、`.so`、数据文件,写入 `Analysis`;再用 `PYZ` 归档字节码、`EXE` 生成入口、`COLLECT` 拼装 onedir 目录(onefile 模式额外把 COLLECT 结果压缩进单文件,运行时解压到 `/tmp/_MEIxxxxxx`)。 2. **运行期**:自带的 bootloader(C 程序)启动,设置 `sys._MEIPASS` 指向解压根,初始化 Python,执行 `runtime_hooks`,最后运行入口脚本。 关键含义: - **bootloader 必须与目标架构匹配** → 国产架构需本架构编译 bootloader。 - **运行时 hook 在应用代码前执行** → 本项目用它修正 Qt/字体/库路径。 - **`sys._MEIPASS` 是资源根** → `myapp.env.resource_path()` 据此定位打包内资源。 ### 2. glibc 版本兼容性表 Linux 二进制跨发行版可移植性受 glibc 约束:**低版本 glibc 上构建的产物可运行于高版本,反之报 `GLIBC_2.xx not found`**。常见国产/通用发行版 glibc 版本: | 发行版 | 基于 | glibc 版本 | 备注 | |---|---|---|---| | UOS 1060 | Debian 10 (buster) | 2.28 | 最低目标,在此构建兼容性最广 | | UOS 1070 | Debian 11 (bullseye) | 2.31 | 当前主流 | | UOS V20 SP1/SP3 | Debian 10 | 2.28 | 企业版常见 | | 麒麟 V10 SP1 | Ubuntu 20.04 | 2.31 | | | 麒麟 V10 SP3 | Ubuntu 22.04 | 2.35 | | | deepin 20.x | Debian 10 | 2.28 | | | deepin 23 | Debian 12 | 2.36 | | | Ubuntu 22.04 | - | 2.35 | GitHub Actions ubuntu-latest | | Ubuntu 24.04 | - | 2.39 | | **实践建议**:需同时支持多个 UOS 版本时,在最旧的 UOS 1060 / deepin 20 上构建,产物可向前兼容 UOS 1070、麒麟 V10 等。在 Ubuntu 22.04+ 上构建的产物无法在 UOS 1060 上运行。 ### 3. 国产架构 PyInstaller 安装 PyInstaller 官方 wheel 覆盖范围(截至 PyInstaller 6.x): | 架构 | 预编译 bootloader | 安装方式 | |---|---|---| | x86_64 | ✅ | `pip install pyinstaller` | | aarch64 | ✅ | `pip install pyinstaller` | | loongarch64 | ❌ | 源码编译(见下) | | mips64el | ❌ | 源码编译(见下) | **loongarch64 / mips64el 源码安装**: ```bash # 1. 安装编译工具链 sudo apt-get install -y build-essential python3-dev zlib1g-dev # 2. 源码安装 (pip 会自动调用 waf 编译 bootloader) pip install --no-binary pyinstaller pyinstaller # 3. 验证 bootloader python3 -c "import PyInstaller; print(PyInstaller.__version__)" ls $(python3 -c "import PyInstaller,os;print(os.path.dirname(PyInstaller.__file__))")/PyInstaller/bootloader/Linux-*/ # 应看到 run 与 run_d 二进制 # 4. 若步骤 2 未自动编译,手动执行 python3 -m PyInstaller.utils.cli build_bootloader ``` ⚠️ 待核实:部分龙芯 UOS 的 Python 可能需 `loongnix` 源提供的定制 PyInstaller,建议先尝试官方源码安装,失败再查 loongnix 源。 ### 4. PySide6 / Qt 在 UOS 上的典型问题与诊断 #### 4.1 "could not find or load the Qt platform plugin xcb" 最常见崩溃。原因:Qt 的 `plugins/platforms/libqxcb.so` 未被打包,或其依赖的系统 xcb 库缺失。 **诊断步骤**: ```bash # 1. 确认打包产物含平台插件 ls dist/myapp/PySide6/plugins/platforms/ # 应有 libqxcb.so, libqwayland-*.so 等 # 2. 确认 libqxcb.so 的系统依赖全部满足 ldd dist/myapp/PySide6/plugins/platforms/libqxcb.so | grep "not found" # 列出的 "not found" 即缺失的系统库 # 3. 用 QT_DEBUG_PLUGINS 看详细加载日志 QT_DEBUG_PLUGINS=1 ./dist/myapp/myapp 2>&1 | grep -i xcb ``` **修复**: - spec 中确保 `collect_data_files('PySide6')` 与 `collect_dynamic_libs('PySide6')` 已执行(本项目已默认)。 - 运行 `sudo bash build/platform/linux/install-deps-uos.sh` 安装 `libxcb-*` 系列。 - runtime hook 设置 `QT_QPA_PLATFORM_PLUGIN_PATH` 指向 bundle 内 platforms 目录(本项目已实现)。 #### 4.2 Wayland vs X11 会话 UOS 1070+ DDE 支持 Wayland 会话。Qt 默认尝试 xcb 平台插件,Wayland 会话下可能需要 `wayland` 插件: ```bash # 检测当前会话 echo $XDG_SESSION_TYPE # x11 或 wayland # 强制使用 wayland QT_QPA_PLATFORM=wayland ./dist/myapp/myapp # 强制使用 xcb (兼容性最稳) QT_QPA_PLATFORM=xcb ./dist/myapp/myapp ``` 本项目 runtime hook 默认设 `QT_QPA_PLATFORM=xcb`(UOS DDE 默认 X11 会话,兼容性最佳)。如目标环境为 Wayland,可覆盖此环境变量。 #### 4.3 中文显示为方框 (豆腐块) 原因:fontconfig 找不到中文字体。UOS 通常预装思源黑体(Source Han Sans)/ Noto Sans CJK,但精简安装或容器环境可能缺失。 **诊断**: ```bash fc-list :lang=zh | head # 无输出 = 系统缺中文字体 ``` **修复**: ```bash sudo apt-get install -y fonts-noto-cjk fonts-wqy-zenhei ``` 如需应用自带字体(避免依赖宿主),把 `.ttf` 放到 `src/myapp/assets/fonts/`,spec 已通过 `datas` 整体打包,runtime hook 中可扩展注册到 fontconfig。本项目默认不打包字体以规避版权与体积问题。 #### 4.4 OpenGL / EGL 问题(国产 GPU) 国产 GPU(景嘉微、摩尔线程、芯动等)驱动成熟度参差,Qt 的 OpenGL 依赖可能崩溃。临时规避: ```bash # 强制软件渲染 LIBGL_ALWAYS_SOFTWARE=1 ./dist/myapp/myapp # 或禁用 Qt OpenGL QT_OPENGL=software ./dist/myapp/myapp ``` ### 5. PyInstaller spec 多平台分支模式 本项目 `build/myapp.spec` 采用的分支模式: ```python import sys, platform THIS_PLATFORM = sys.platform # 'linux' / 'win32' / 'darwin' THIS_ARCH = platform.machine().lower() # 标准化: x86_64 / aarch64 / loongarch64 / mips64el IS_LINUX = THIS_PLATFORM == 'linux' datas, binaries, hiddenimports = [], [], [] # 全平台通用收集 hiddenimports += collect_submodules('PySide6') datas += collect_data_files('PySide6') binaries += collect_dynamic_libs('PySide6') # 平台特定补丁 if IS_LINUX: # fontconfig 配置、xcb 依赖兜底 ... ``` 要点: - **单 spec 多平台**:通过 `sys.platform` / `platform.machine()` 运行时分支,无需为每个平台维护独立 spec。 - **不能交叉打包**:PyInstaller 扫描当前 Python 环境的 `.so` 依赖,必须在目标平台/架构的机器上执行打包。 - **`collect_*` 三件套**:`collect_submodules`(hiddenimports)、`collect_data_files`(datas:Qt 插件、QML、翻译)、`collect_dynamic_libs`(binaries:.so 文件)缺一不可。 ### 6. UOS DDE 桌面集成规范 #### 6.1 `.desktop` 文件 UOS DDE 遵循 [freedesktop.org Desktop Entry Specification](https://specifications.freedesktop.org/desktop-entry-spec/latest/)。关键字段: ```ini [Desktop Entry] Type=Application Name=应用名 Name[en]=English Name # 本地化 GenericName=通用名 # 分类描述 Comment=注释 Exec=/usr/local/bin/myapp %f # 绝对路径,%f 接收文件参数 Icon=myapp # 图标名(不带扩展名,从 hicolor 主题查找) Terminal=false # GUI 应用设 false Categories=Development;Utility; # 菜单分类,分号分隔 Keywords=pyinstaller;uos; # 搜索关键词 StartupNotify=true StartupWMClass=myapp # 关键:窗口类名,确保任务栏正确分组 MimeType=application/x-myapp; # 可选:关联文件类型 ``` #### 6.2 安装路径 | 资源 | 系统级路径 | 用户级路径 | |---|---|---| | `.desktop` | `/usr/share/applications/` | `~/.local/share/applications/` | | 图标 (SVG) | `/usr/share/icons/hicolor/scalable/apps/` | `~/.local/share/icons/hicolor/scalable/apps/` | | 图标 (PNG) | `/usr/share/icons/hicolor//apps/` | `~/.local/share/icons/hicolor//apps/` | | 可执行文件 | `/opt//` 或 `/usr/bin/` | `~/.local/bin/` | 图标名 `Icon=myapp` 对应 `myapp.svg` 或 `myapp.png`(不带扩展名,系统按主题查找)。 #### 6.3 刷新缓存 安装/卸载后刷新桌面数据库与图标缓存: ```bash update-desktop-database /usr/share/applications gtk-update-icon-cache /usr/share/icons/hicolor ``` 本项目的 `install-uos.sh` 已自动执行。 ### 7. UPX 压缩在国产架构上的风险 UPX 是可执行文件压缩器,可减小 PyInstaller 产物体积 30-50%。但在国产架构上有已知问题: | 架构 | UPX 兼容性 | 建议 | |---|---|---| | x86_64 | ✅ 稳定 | 可启用 | | aarch64 | ⚠️ 多数可用,偶发崩溃 | 测试后启用 | | loongarch64 | ❌ 不支持 / 损坏二进制 | 禁用 | | mips64el | ❌ 不支持 / 损坏二进制 | 禁用 | 本项目 spec 默认 `upx=False`。x86_64/aarch64 可通过 `python build/build.py --upx` 启用,但需先安装 upx(`sudo apt-get install upx-ucl`)。 ### 8. onedir vs onefile 模式选型 | 维度 | onedir | onefile | |---|---|---| | 启动速度 | 快(无解压) | 慢(每次解压到 /tmp) | | 磁盘占用 | 大(独立目录) | 小(单文件,但运行时解压占同等空间) | | 资源更新 | 可替换目录内文件 | 需重新打包 | | 杀软误报 | 低 | 高(单文件 + 自解压特征易误报) | | UOS 兼容性 | ✅ 推荐 | ✅ 可用 | | 调试 | 方便(可见文件结构) | 困难 | **生产环境推荐 onedir**。本项目默认 onedir,`--onefile` 切换单文件。 ### 9. 多平台 CI 策略 | 目标 | 构建方式 | 示例 | |---|---|---| | linux x86_64 | GitHub Actions `ubuntu-latest` | 本项目 `build.yml` | | linux aarch64 | GitHub Actions `ubuntu-24.04-arm`(2024 GA)或 QEMU binfmt | 本项目 `build.yml` | | linux loongarch64/mips64el | **自托管 UOS 构建机** | 本项目 `build.yml` 的 `build-domestic` job | | macOS x86_64/arm64 | GitHub Actions `macos-13`/`macos-latest` | 本项目 `build.yml` | | windows x86_64 | GitHub Actions `windows-latest` | 本项目 `build.yml` | **国产架构为何不能在 GitHub 托管 runner 上构建**: 1. PyInstaller 不能交叉打包(需目标架构的 Python + .so)。 2. QEMU 用户态模拟(binfmt)理论上可跑目标架构 Python,但 PyInstaller 扫描 `.so` 依赖时调用 `ldd`,在非原生环境下行为不可靠。 3. 龙芯等架构的 glibc/工具链与 QEMU 模拟有微妙差异,产物可能运行即崩。 **推荐做法**:在对应架构的 UOS 物理机或 KVM 虚拟机上配置 self-hosted runner,运行 `bash build/build.sh`。 ### 10. 系统依赖清单(install-deps-uos.sh 已覆盖) PySide6 打包应用在 UOS 上运行所需的系统库: ``` # Qt xcb 平台插件依赖 libxcb1 libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-sync1 libxcb-util1 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon0 libxkbcommon-x11-0 # OpenGL / EGL libgl1 libegl1 libgles2 libglx0 # 字体渲染 fontconfig libfontconfig1 libfreetype6 # 网络 (Qt Network, 如用 HTTPS) libnss3 libnspr4 # 音频 (Qt Multimedia, 可选) libpulse0 # Wayland (UOS 1070+ Wayland 会话) libwayland-client0 libwayland-server0 # 中文字体 fonts-noto-cjk fonts-wqy-zenhei ``` ### 11. 参考资源 - **PyInstaller 官方文档**:https://pyinstaller.org/en/stable/ - [Runtime Hooks](https://pyinstaller.org/en/stable/hooks.html) - 本项目 `uos_runtime_hook.py` 基于此 - [Spec Files](https://pyinstaller.org/en/stable/spec-files.html) - 本项目 `myapp.spec` 基于此 - [Bootloader build](https://pyinstaller.org/en/stable/bootloader-building.html) - 国产架构编译 bootloader - **PyInstaller GitHub Issues**:https://github.com/pyinstaller/pyinstaller/issues - 搜索 `loongarch` / `mips` / `aarch64` 获取国产架构已知问题 - **freedesktop.org Desktop Entry Spec**:https://specifications.freedesktop.org/desktop-entry-spec/latest/ - **统信 UOS 开发者文档**:https://doc.chinauos.com/ - **Qt 平台插件调试**:设置 `QT_DEBUG_PLUGINS=1` 输出插件加载日志 - **glibc 版本查询**:`ldd --version` 查看当前系统 glibc 版本 - **OSS 参考**(PyInstaller + Qt + 国产 Linux 打包实践): - [QGIS](https://github.com/qgis/QGIS) - 跨平台 GIS,其 PyInstaller 打包脚本对国产架构有借鉴价值 - [RPA 项目 PyInstaller 实践](https://github.com/pyinstaller/pyinstaller/wiki) - 官方 Wiki 收录的社区案例 - ⚠️ 待核实:专门的 UOS PyInstaller 开源项目较少,多数企业内部使用;如在 Gitee 搜索 "pyinstaller uos" 可找到零散案例 ## 许可证 MIT