ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Kivy macOS 应用打包指南:Kivy SDK、Buildozer 与 PyInstaller 三种方案详解

Kivy macOS 应用打包指南:Kivy SDK、Buildozer 与 PyInstaller 三种方案详解 跨平台移动开发桌面应用UI组件【免费下载链接】kivyOpen source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS项目地址https://gitcode.com/gh_mirrors/ki/kivy点击查看免费下载本篇技术指南基于 Kivy 官方文档 doc/sources/guide/packaging-osx.rst系统讲解在 macOS 上打包 Kivy 应用的三种主流方案官方推荐的 Kivy SDK、Buildozer 一键打包以及 PyInstaller配合或不配合 Homebrew的深度定制方案。读完本文你将掌握从安装依赖、编写 spec 文件到最终生成.app与 DMG 安装镜像的完整流程并能结合仓库源码理解 Kivy 为 PyInstaller 提供的 hook 机制按需裁剪打包体积。打包方式总览Kivy 官方为 macOS 提供了多条打包路径它们各有适用场景方案适用场景特点Kivy SDKKivy.app常规应用、追求稳定所有依赖打包在虚拟环境中不引用系统二进制官方推荐Buildozer快速出包、自动化一条命令完成打包底层仍调用 Kivy SDKPyInstaller Homebrew需要精细控制依赖从源码编译可在任意机器运行需手动编辑 specPyInstaller无 Homebrew已自行安装依赖完全手写 spec灵活度最高工作量也最大下文逐一展开。其中示例应用使用仓库自带的 Touch Tracer 演示程序其源码位于 examples/demo/touchtracer/main.py配套的 touchtracer.kv 与 particle.png 会在打包时一并收集是贯穿全文的实战对象。方案一使用 Kivy SDK推荐Kivy 官方发布一个名为Kivy.app的 DMG 安装包其中内置了一个虚拟环境既包含完整的 Python 解释器也包含 SDL、GStreamer 等全部二进制依赖可直接作为打包 Kivy 应用的基础。这是最安全的打包方式原因在于打包出的应用只引用 DMG 内的 framework 或二进制不包含任何对打包机器上系统二进制文件的引用与之相对PyInstaller 会从本地 Python 安装中复制二进制产物容易受打包机环境影响。使用该方案时请注意两个版本前提该方式仅适用于 Kivy v2.0.0 及之后版本Kivy.app 以MACOSX_DEPLOYMENT_TARGET10.9构建即默认支持 macOS 10.9 及以上系统。值得注意的是当前仓库的 tools/build_macos_dependencies.sh 中依赖构建脚本已使用MACOSX_DEPLOYMENT_TARGET10.15调用xcodebuild同时 changelog.rst 也记录了 Xcode 14.3 在MACOSX_DEPLOYMENT_TARGET 10.13时无法构建 SDL 的兼容性问题——若你自行构建依赖建议按新脚本的部署目标执行。具体操作分两条路线一是直接基于已安装的 Kivy.app 打包二是从零开始构建。两种方式的完整指令均记录在官方维护的kivy-sdk-packager 仓库osx目录的 README 中文档只给出指引不重复贴出全部命令。方案二使用 Buildozer 一键打包Buildozer 是 Kivy 官方提供的跨平台打包工具其 macOS 支持流程如下pip install githttp://github.com/kivy/buildozer cd /to/where/I/Want/to/package buildozer initbuildozer init会在当前目录生成buildozer.spec配置文件。仓库中的 examples/audio/buildozer.spec 是一份完整的参考示例其中与 macOS 打包直接相关的关键项包括[app] # (str) Title of your application title Audio Example # (str) Package name package.name audio # (str) Source code where the main.py live source.dir . # (list) Source files to include (let empty to include all the files) source.include_exts py,png,jpg,kv,atlas,wav # (list) Application requirements # comma separated e.g. requirements sqlite3,kivy requirements kivy编辑 spec 文件时请根据你的应用填写标题、包名、源码目录并在requirements一节追加额外依赖例如requirements kivy,pygame。关于requirements有两个值得注意的默认行为默认情况下requirements中指定的kivy 版本号会被忽略打包时Buildozer 优先使用位于/Applications/Kivy.app的本地 Kivy.app如果该目录不存在则自动下载 kivy.org 上基于 Kivy master 分支的最新构建。配置完成后执行打包命令buildozer osx debug打包完成后如果希望减小体积可以手动移除应用运行所不需要的多余包将产物精简到最小可用状态。Buildozer 目前底层仍然调用 Kivy SDK 完成打包。如果你需要比 Buildozer 现有选项更精细的控制可直接使用 SDK 方式见方案一。方案三PyInstaller Homebrew 完整指南当需要精细控制打包行为时PyInstaller 是更灵活的选择。官方文档给出了一条经过验证的完整路线。重要原则请在你希望支持的最低 macOS 版本上进行打包这样产物的兼容范围最广。1. 安装 Homebrew 与 Python首先安装 HomebrewmacOS 包管理器然后安装 Python$ brew install python若要使用 Python 3请执行brew install python3并将下文所有pip替换为pip3。2. 从源码重装依赖为了让产物可以在其他机器上运行需要确保依赖二进制不以链接形式引用本机 Homebrew 的库因此要用--build-from-source重新安装 SDL 系依赖$ brew reinstall --build-from-source sdl3 sdl3_image sdl3_ttf sdl3_mixer如果项目还依赖 GStreamer 或其他附加库同样需要用--build-from-source重装详见下文附加库一节。3. 安装 Cython 与 Kivy$ pip install Cython $ pip install -U kivyCython是 Kivy 的编译依赖Kivy 大量使用 Cython 编写扩展模块必须先于 Kivy 安装-U确保升级到最新版本。4. 安装 PyInstaller$ pip install -U pyinstaller5. 打包应用使用pyinstaller直接指向应用的main.py$ pyinstaller -y --clean --windowed --name touchtracer \ --exclude-module _tkinter \ --exclude-module Tkinter \ --exclude-module enchant \ --exclude-module twisted \ /usr/local/share/kivy-examples/demo/touchtracer/main.py各参数含义如下参数作用-y覆盖输出目录中已有文件--clean打包前清理缓存--windowed不弹出终端窗口适合 GUI 应用--name touchtracer指定应用名--exclude-module ...显式排除 Kivy 用不到的模块减小体积被排除的_tkinter/TkinterTk GUI、enchant拼写检查、twisted异步框架都是 Kivy 应用常见的冗余依赖。当前仓库的 kivy/tools/packaging/pyinstaller_hooks/init.py 中同样定义了excludedimports [tkinter, _tkinter, twisted]与这里的命令行排除逻辑相互印证。注意以上命令还不会复制图片、声音等附加资源文件这一步需要在生成的.spec文件中手动补充。6. 编辑 spec 文件执行上述命令后当前目录会生成touchtracer.spec。需要修改其中的COLLECT()调用把 Touch Tracer 的数据文件touchtracer.kv、particle.png等加入最终包。方法是在COLLECT中增加一个Tree()对象——它会递归搜索并打包指定目录下的所有文件coll COLLECT(exe, Tree(/usr/local/share/kivy-examples/demo/touchtracer/), a.binaries, a.zipfiles, a.datas, stripNone, upxTrue, nametouchtracer)Tree()的路径应替换为实际示例目录对你自己的应用而言就是存放.kv、图片、音频等资源的目录。Tree会递归包含全部文件因此要确认该目录下没有不想发布的敏感文件。7. 构建 spec 并生成 DMG$ pyinstaller -y --clean --windowed touchtracer.spec构建完成后进入dist目录用 macOS 自带的hdiutil把.app封装成 DMG 镜像$ pushd dist $ hdiutil create ./Touchtracer.dmg -srcfolder touchtracer.app -ov $ popd-srcfolder touchtracer.app指定被封装的应用-ov允许覆盖已存在的同名 DMG。完成后dist目录下就会出现Touchtracer.dmg可直接分发安装。附加库GStreamer如果项目依赖 GStreamer如视频播放需要以源码方式重装相关组件$ brew reinstall --build-from-source gstreamer gst-plugins-{base,good,bad,ugly}若项目需要 Ogg Vorbis 支持请在上述命令中追加--with-libvorbis选项。此外如果你使用的是 Homebrew 提供的 Python在官方 Homebrew formula 合入相应改动之前还需要手动安装带--with-python的gst-pythonformula。GStreamer 与打包的关联在源码中也有体现pyi_rth_kivy.py见 kivy/tools/packaging/pyinstaller_hooks/pyi_rth_kivy.py会在运行时把sys._MEIPASS与gst-plugins子目录写入GST_PLUGIN_PATH并把GST_REGISTRY重定向到包内确保解包后的应用能找到 GStreamer 插件而 hook-kivy.py 对应的__init__.py中_find_gst_binaries()会通过gst-inspect-1.0探测插件路径收集libgst*插件及其依赖库作为binaries传入Analysis。方案四不使用 Homebrew 的 PyInstaller 手写 spec如果你不希望依赖 Homebrew例如已按 Kivy 官方开发版安装指南自行编译了 Kivy 及其依赖可以完全手写 spec 文件。官方文档以testpackaging目录为例cd testpackaging git clone https://github.com/pyinstaller/pyinstaller在该目录创建touchtracer.spec写入以下内容# -*- mode: python -*- block_cipher None from kivy.tools.packaging.pyinstaller_hooks import get_deps_all, hookspath, runtime_hooks a Analysis([/path/to/yout/folder/containing/examples/demo/touchtracer/main.py], pathex[/path/to/yout/folder/containing/testpackaging], binariesNone, win_no_prefer_redirectsFalse, win_private_assembliesFalse, cipherblock_cipher, hookspathhookspath(), runtime_hooksruntime_hooks(), **get_deps_all()) pyz PYZ(a.pure, a.zipped_data, cipherblock_cipher) exe EXE(pyz, a.scripts, exclude_binariesTrue, nametouchtracer, debugFalse, stripFalse, upxTrue, consoleFalse ) coll COLLECT(exe, Tree(../kivy/examples/demo/touchtracer/), Tree(/Library/Frameworks/SDL3_ttf.framework/Versions/A/Frameworks/FreeType.framework), a.binaries, a.zipfiles, a.datas, stripFalse, upxTrue, nametouchtracer) app BUNDLE(coll, nametouchtracer.app, iconNone, bundle_identifierNone)使用前必须把以下路径替换为你的实际路径Analysis中的主脚本路径/path/to/yout/folder/containing/examples/demo/touchtracer/main.pypathex中的工程目录/path/to/yout/folder/containing/testpackagingCOLLECT中Tree(../kivy/examples/demo/touchtracer/)的资源目录Tree()中 FreeType framework 的路径该路径随你的 SDL_ttf 安装位置而定。该 spec 的核心是利用 Kivy 官方提供的 PyInstaller 辅助模块见 kivy/tools/packaging/pyinstaller_hooks/init.pyhookspath()返回包含 Kivy 自定义 hookhook-kivy.py的目录供Analysis使用runtime_hooks()返回 Kivy 运行时 hookpyi_rth_kivy.py路径负责在启动时设置KIVY_DATA_DIR、KIVY_MODULES_DIR、GST_PLUGIN_PATH等环境变量get_deps_all()返回所有可能被间接导入的 Kivy 模块含全部 core provider、GStreamer 二进制与排除项以字典形式展开为Analysis的hiddenimports/excludes/binaries参数。随后执行pyinstaller/pyinstaller.py touchtracer.spec将touchtracer替换为你的应用名即可。完成后dist/目录下会出现yourapp.app。注意BUNDLE()中的iconNone表示暂未设置图标如需自定义应用图标可在此指定.icns文件。源码级补充理解 Kivy 的 PyInstaller hook 机制方案四中使用的get_deps_all()只是冰山一角。Kivy 的 pyinstaller hooks 模块还提供了更精细的控制能力理解它们有助于你进一步压缩打包体积、规避缺模块问题。get_deps_minimal按 core 模块裁剪 provider与get_deps_all()打包所有 provider不同get_deps_minimal(exclude_ignoredTrue, **kwargs)允许你按核心模块粒度控制打包内容。其关键字参数对应 Kivy 的 core 模块audio、camera、clipboard、image、spelling、text、video、window取值规则取值行为True默认包含本系统当前加载的 providerNone完全排除该 core 模块exclude_ignoredTrue时还会加入 excludes防止被意外带入字符串或字符串列表只包含指定的 provider如audio[gstplayer, ffpyplayer]、spellingenchant官方示例a Analysis([..\\kivy\\examples\\demo\\touchtracer\\main.py], ... hookspathhookspath(), runtime_hooks[], win_no_prefer_redirectsFalse, win_private_assembliesFalse, cipherblock_cipher, **get_deps_minimal(videoNone, audioNone))为什么需要 hiddenimportsPyInstaller 通过静态分析 import 语句收集依赖但 Kivy 的大量核心模块如视频 provider是通过__import__等方式间接导入的PyInstaller 无法感知必须通过hiddenimports显式声明。get_deps_all()/get_deps_minimal()返回的字典正是为此服务的。覆盖默认 hookPyInstaller 自带一个 Kivy hook它会列出所有 provider 作为 hidden imports导致体积偏大。你可以通过hookspath()指向仓库内置的替代 hookkivy/tools/packaging/pyinstaller_hooks/hook-kivy.py它只保留get_factory_modules()所有注册进 Kivy Factory 的模块与基础kivy_modules把 provider 的取舍完全交给get_deps_minimal()/get_deps_all()决定。也可以在命令行加--additional-hooks-dirHOOKSPATH覆盖默认 hook 中的hiddenimports、excludedimports全局变量。生成自定义 hook 清单如果想手动逐个勾选 provider可以借助模块自带的生成器python -m kivy.tools.packaging.pyinstaller_hooks hook filename该命令实现见 kivy/tools/packaging/pyinstaller_hooks/main.py会把get_deps_all()得到的全部模块以列表形式写入filename指定的 hook 文件不传filename则直接打印到终端你只需注释掉不需要的 provider 即可。打包注意事项汇总在最低支持的 macOS 版本上打包PyInstaller 产物通常向下兼容有限选择过新的构建系统可能使旧系统用户无法运行源码编译依赖使用 Homebrew 方案时务必对 SDL、GStreamer 等执行--build-from-source重装否则产物会携带对打包机 Homebrew 库的路径引用资源文件不会自动收集图片、音频、.kv文件必须通过 spec 中的Tree()或datas显式加入GStreamer 需要额外配置依赖视频播放时除重装gstreamer及 plugins 外运行时还需GST_PLUGIN_PATH等环境变量配合Kivy 的 runtime hook 已自动处理Kivy SDK 方案无需关心上述二进制细节DMG 内虚拟环境已包含全部依赖这也是官方推荐它的根本原因版本前提Kivy SDK 打包方式仅适用于 Kivy v2.0.0 及以上且 Kivy.app 基于MACOSX_DEPLOYMENT_TARGET10.9构建。至此你可以根据项目对稳定性与可控性的需求在 Kivy SDK、Buildozer 与 PyInstaller 之间做出选择并依据本文的完整命令与 spec 模板在 macOS 上产出可分发的.app与 DMG。赞分享跨平台移动开发桌面应用UI组件【免费下载链接】kivyOpen source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS项目地址https://gitcode.com/gh_mirrors/ki/kivy点击查看免费下载相关推荐Kivy Buildozer终极指南一键打包Python移动应用Kivy Buildozer终极指南一键打包Python移动应用 Kivy Buildozer是Python开发者将应用部署到Android和iOS平台的终极开发工具移动开发Kivy/Buildozer 跨平台应用打包工具安装指南Kivy/Buildozer 跨平台应用打包工具安装指南 工具简介 Buildozer 是一个强大的自动化工具专门用于将 Python 应用打包为移动平台的原开发工具移动开发Kivy Buildozer终极指南简单快速的跨平台应用打包方案Kivy Buildozer终极指南简单快速的跨平台应用打包方案 Kivy Buildozer是Python开发者构建跨平台应用的终极工具能够将Python开发工具移动开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表