多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

PyOxidizer 应用分发(Distribution)概览:构建与打包之外的“最后一公里“

PyOxidizer 应用分发(Distribution)概览:构建与打包之外的“最后一公里“ 开发工具CLI【免费下载链接】PyOxidizerA modern Python application packaging and distribution tool项目地址https://gitcode.com/gh_mirrors/py/PyOxidizer点击查看免费下载PyOxidizer 不仅负责把 Python 应用构建成单个可执行文件、把 Python 资源打包进二进制还提供了一套完整的分发distribution能力帮助你把产物安装到目标机器上。本文基于 pyoxidizer_distributing_overview.rst 展开介绍 PyOxidizer 的分发架构——Tugger 工具、Starlark 分发方言、二进制可移植性评估以及 Windows 安装包生成读完后你将掌握 PyOxidizer 从产出二进制到产出可安装交付物的完整技术路径并能针对 Linux、macOS、Windows 分别规划分发策略。分发Distribution与构建、打包是两个不同的领域PyOxidizer 官方文档将应用生命周期明确划分为三个相互独立的领域构建building关心的是产出构成应用的哪些文件——运行时需要的可执行文件和支持文件打包packaging关心的是把 Python 解释器、标准库、第三方依赖等资源组织进二进制的形态这部分由PythonExecutable等类型在 pyoxidizer/docs/pyoxidizer_packaging.rst 系列文档中阐述分发distribution关心的是把这些文件安装到其他机器上——生成安装包、处理目标平台的运行时依赖、评估二进制可移植性。理解这个边界很重要一个构建得很完美的二进制如果分发环节没有处理好目标机器的运行时依赖例如缺少 Visual C Redistributable到了用户手里依然无法运行。PyOxidizer 的分发能力正是为了解决这一最后一公里问题而设计的。TuggerPyOxidizer 的分发引擎PyOxidizer 将大部分分发功能委托给Tugger工具实现见 tugger/docs/tugger.rst。Tugger 是随 PyOxidizer 同步开发的 Rust crate 与 Starlark 方言集合专注于应用分发所需的通用能力。它在技术上是一个独立项目——即使不用 PyOxidizer也可以单独使用 Tugger 来制作分发产物而 PyOxidizer 则完整继承了 Tugger 的 Starlark 功能并对其做了 Python 应用专属的扩展使分发 Python 应用更加简单。平台无关与文件中心的设计理念根据 tugger/docs/tugger_overview.rstTugger 的设计有两个显著特点平台无关、进程内实现Tugger 的目标是尽可能在进程内完成所有打包逻辑不依赖rpmbuild、debuild这类外部工具。例如RPM 和 Debian 包是通过 Rust 代码直接构造原始归档文件生成的因此理论上可以在 Windows 上生成 Linux.deb、在 macOS 上生成 Windows MSI 安装器、在 Linux 上生成 macOS DMG。文件中心视角file-centricTugger 的大多数打包设施以一组输入文件 一种输出分发格式的方式工作而不是像传统打包工具那样内置一套定制构建系统。这带来的副作用是Tugger 通常不关心文件是怎么构建出来的需要由你通过 Starlark 脚本先产出待分发的文件再交给 Tugger 组装。模块化的 Rust crate 架构Tugger 由一系列领域专属的 Rust crate文档中称为fleet组成每个 crate 提供单一领域能力。官方文档列出的核心 crate 包括Crate职责tugger-binary-analysis分析平台原生二进制查找库依赖、识别 Linux 发行版兼容性等tugger-common多个 crate 共享的基础功能文件下载、共享测试代码等tugger-debianDebian 打包原语解析/序列化 control 文件、写.deb文件tugger-rpmRPM 打包原语tugger-snapcraftSnapcraft 打包表示snapcraft.yaml、调用snapcraft产出.snaptugger-windowsWindows 专属功能定位 Microsoft SDK 与 VC Redistributable 文件、签名 Windows 二进制tugger-wix对接 WiX Toolset产出 Windows.msi与.exe安装器几乎无需了解 WiX 内部知识即可构建安装器tugger主 crate实现 Starlark 方言与驱动代码在当前仓库中可以观察到这套 crate 体系的实际布局tugger-binary-analysis/、tugger-common/、tugger-windows/、tugger-wix/、tugger-rpm/、tugger-snapcraft/、tugger-apple/、tugger-code-signing/、tugger-rust-toolchain/ 等均作为独立目录存在印证了每个 crate 独立、可复用的设计初衷。用 Starlark 方言描述分发通用原语 Python 专属扩展Tugger 使用 Starlark。PyOxidizer 配置文件pyoxidizer.bzl可以使用完整的 Tugger Starlark 方言并且有两种使用层次Tugger 提供的通用原语通常比较底层、通用与具体语言无关例如FileManifest文件清单、WiXMSIBuilder、WiXBundleBuilder、FileContent等类型PyOxidizer 提供的扩展Python 应用专属往往能让配置文件更简洁——例如不必手动组装 WiX 安装器而是直接调用PythonExecutable上的方法把它一键转换成安装器构建器。PyOxidizer 对 Tugger 方言的扩展清单根据 pyoxidizer/docs/pyoxidizer_distributing_wix.rstPyOxidizer 提供了以下关键扩展与集成FileManifest.add_python_resource向 Tugger 的FileManifest添加一个 Python 资源类型FileManifest.add_python_resources向FileManifest添加一组iterablePython 资源类型PythonExecutable.to_file_manifest把PythonExecutable转换为FileManifest从而把可执行程序/应用物化为一组文件供 Tugger 直接操作PythonExecutable.to_wix_bundle_builder把PythonExecutable转换为预先配置好的WiXBundleBuilder产出的.exe安装器开箱即用PythonExecutable.to_wix_msi_builder把PythonExecutable转换为预先配置好的WiXMSIBuilder安装 Python 应用及其全部支持文件不含系统级依赖。这些方法的签名与参数细节收录在 pyoxidizer/docs/pyoxidizer_config_type_python_executable.rst 中。源码视角这些方法是如何实现的从源码可以看到这些扩展的实际调用链pyoxidizer/src/starlark/python_executable.rs#L860-L966to_wix_msi_builder()首先调用to_file_manifest(type_values, ..to_string())把可执行程序物化为文件清单再创建WiXMsiBuilderValue最后调用builder.add_program_files_manifest(...)把文件清单注册为Program Files安装目录下的内容to_wix_bundle_builder()则在内部先调用to_wix_msi_builder()生成 MSI 构建器并可传入msi_builder_callback函数对 MSI 做二次定制随后根据目标三元组target triple自动附加 VC Redistributable目标为i686-pc-windows-msvc时附加 x86 版、x86_64-pc-windows-msvc时附加 x64 版最后把 MSI 构建器包进WiXBundleBuilder并add_wix_msi_builder(...)。这就是生成的.exe安装器会自带 VC Redistributable 安装器并自动执行的底层来源。分发前的质量关卡评估二进制可移植性二进制可移植性binary portability指在机器/环境 X 上构建的二进制能否在不做修改的情况下直接拷贝到机器/环境 Y 上运行。PyOxidizer 能构建高度可移植的二进制但具体做法因操作系统与目标平台而异官方专门编写了 pyoxidizer_distributing_binary_portability.rst 讲述通用策略。用pyoxidizer analyze评估产物pyoxidizer analyze命令是 PyOxidizer 提供的可移植性评估工具用于分析可执行文件与库的内容。以 ELF 二进制Linux 格式为例它会列出所有共享库依赖分析 glibc 符号版本打印它认为该二进制兼容的 Linux 发行版版本范围。需要说明的是官方文档提示该命令尚未在所有平台上功能完备。Linux构建环境会泄漏进产物pyoxidizer_distributing_linux.rst 给出了 Linux 分发的关键结论musl libc 是例外针对x86_64-unknown-linux-musl构建的二进制完全静态链接、自包含几乎可以在任何支持该架构的 Linux 机器上运行。如果ldd /path/to/binary输出not a dynamic executable说明二进制很可能高度可移植静态链接的构建方法见 pyoxidizer_packaging_static_linking.rst默认 Python 发行版本身很可移植*-unknown-linux-gnu构建只依赖libc.so.6且构建时校验所引用 glibc 符号版本不高于 glibc 2.192014 年发布因此兼容 Fedora 21、RHEL/CentOS 7、openSUSE 13.2、Debian 8Jessie、Ubuntu 14.04 等常见发行版但你自己的二进制不一定用 PyOxidizer 编译的新代码是在本机环境完成的构建机的编译设置会泄漏进产物。文档给出的实例是在 Ubuntu 20.10 上pyoxidizer build出的 ELF 二进制会依赖libgcc_s.so.1并引用 glibc 2.32 符号版本尽管默认 Python 发行版只要求 glibc 2.19管理策略glibc 会记录符号版本链接时采用链接机 glibc 的版本。要最大化可移植性应在较旧的 glibc 环境构建默认 Python 发行版使用 Debian 8 作为构建环境Ubuntu 14.04、openSUSE 13.2/42.1、RHEL/CentOS 7、Fedora 21 也是候选或干脆产出完全静态链接的二进制。macOSSDK 与部署目标管理pyoxidizer_distributing_macos.rst 说明默认 Python 发行版针对 x86_64 要求 macOS 10.9、针对 aarch64 要求 11.0构建机必须使用不早于 Python 发行版所用版本的 Apple SDK否则链接时可能出现未定义符号错误。PyOxidizer 会自动定位/校验 Apple SDK基于xcode-select --print-path指向的目录通常是/Applications/Xcode.app/Contents/Developer可用DEVELOPER_DIR指定替代目录或用SDKROOT强制指定某个 SDK例如DEVELOPER_DIR/Applications/Xcode-beta.app/Contents/Developer pyoxidizer build SDKROOT/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk pyoxidizer buildPyOxidizer 目前只产出单架构二进制不支持原生universal/fat二进制要让 Intel 与 ARM 机器都能运行需分别维护两份产物或在 PyOxidizer 之外制作 fat 二进制构建环境同样会向产物引入较新的 macOS SDK 特性通常通过设置MACOSX_DEPLOYMENT_TARGET指定支持的最老 macOS 版本来规避例如MACOSX_DEPLOYMENT_TARGET10.15 pyoxidizer build。PyOxidizer 会自动将部署目标设置为与所用 Python 发行版一致多数情况下无需手动设置。Windows运行时 DLL 依赖是重中之重Windows 分发的详细考量记录在 pyoxidizer_distributing_windows.rst要点如下操作系统要求默认 Python 发行版要求 Windows 8 / Windows Server 2012 或更新版本官方 Python 3.8 支持 Windows 7但 PyOxidizer 为简化支持放弃了对 Windows 7 的支持运行时依赖默认发行版依赖 Microsoft Visual C Redistributable 与 Universal CRTUCRT。standalone_dynamic默认发行版口味还依赖 OpenSSL、SQLite3 等第三方 DLL但它们是 Python 发行版的一部分PyOxidizer 会在需要时自动安装应用专属依赖安装自定义 Python 包时PyOxidizer 会尽量识别并安装其中的编译扩展与.dll依赖但仍存在边界情况官方建议用 Dependency Walker 或pyoxidizer analyze检查二进制是否有缺失 DLL 引用并在全新安装的 Windows 环境而非预装了大量软件的虚拟机中实测。Windows 安装包实战VC Redistributable 与 WiX 集成Windows 上最常见的两个分发问题是Visual C Redistributable与UCRT。Visual C Redistributable 的两种管理方式PyOxidizer 构建的二进制常依赖文件名形如vcruntime140.dll、vcruntime140_1.dll的 DLL。VC Redistributable 不是 Windows 核心组件全新安装的系统上可能缺失必须在分发时主动处理。PyOxidizer 提供两种内置方案方式一随安装器安装installer 模式PyOxidizer 内部记录了vc_redistarch.exe安装器的下载 URL 与 SHA-256。在源码 tugger-windows/src/vc_redistributable.rs#L23-L45 中可以找到这些记录VC_REDIST_X86、VC_REDIST_X64、VC_REDIST_ARM64三个常量均包含指向 Microsoft 官方下载地址的url字段与对应sha256字段。构建应用安装器时这些文件会从 Microsoft 服务器下载并内嵌进新的 meta-installer安装时如果系统缺少这些文件嵌入的安装器会被自动执行把 VC 文件安装到系统级位置供任何应用使用。若系统已存在更新版本安装器会 no-op不会降级。对应的 Starlark 入口为PythonExecutable.to_wix_bundle_builder与WiXBundleBuilder.add_vc_redistributable。方式二把 DLL 放在二进制旁边本地文件模式另一种方式是直接把vcruntime140[_1].dll拷贝到myapp.exe同目录下——Windows 会优先从可执行文件所在目录加载 DLL因此开箱即用。控制该行为的 Starlark 属性是PythonExecutable.windows_runtime_dlls_mode详见 pyoxidizer/docs/pyoxidizer_config_type_python_executable.rst支持三个取值取值行为never永不安装 Windows 运行时 DLLwhen-present能定位到 DLL 就安装找不到则不做任何事默认值always安装 Windows 运行时 DLL找不到则构建失败该模式依赖vswhere.exe定位本机 Visual Studio 安装中的Microsoft.VisualCPP.Redist.version.Latest组件version对vcruntime140.dll是14因此要求本机装有支持 C/C 开发的 Visual Studio 2017/2019找不到时可在 Visual Studio Installer → Modify → Individual Components 中勾选 redistributable 相关组件。开启后VC 文件会像普通补充文件一样被物化到文件系统也会出现在to_file_manifest、to_wix_msi_builder等方法的文件列表中。重要提示两种方式可以同时存在但属于冗余。官方建议当安装器已内嵌 VC Redistributable 时把windows_runtime_dlls_mode设为never避免重复安装本地文件通常会被优先使用。源码中的测试用例也覆盖了这三个取值与非法值的校验pyoxidizer/src/starlark/python_executable.rs#L1389-L1408。Universal CRTUCRTUCRT 是 Windows 操作系统组件在 Windows 10、Windows Server 2016 及更新版本中始终存在。结合 PyOxidizer 的 Windows 版本要求只有目标为 Windows 8 / Server 2012 时才需要额外部署 UCRT。PyOxidizer 目前不提供 UCRT 的自动物化能力需要部署时可参考 Microsoft 官方 UCRT 部署文档。选择安装器创建方式Bundle 还是 MSIpyoxidizer_distributing_wix.rst 建议按如下方式选择PythonExecutable.to_wix_bundle_builder产出.exe引导安装器会内嵌官方VC_Redist*.exe并在安装时执行适合需要系统级安装 VC 运行时的场景PythonExecutable.to_wix_msi_builder产出.msiTugger 会尝试定位本机vcruntimeXXX.dll需要安装 Visual Studio并拷贝到安装后的可执行文件旁。注意 MSI 安装器不会物化 VC 运行时 DLL 文件对 MSI 路径DLL 是以旁边文件形式处理的如果绕开上述 API 手工构造安装器则需显式调用WiXMSIBuilder.add_visual_cpp_redistributable或WiXBundleBuilder.add_vc_redistributable添加 VC Redistributable——PyOxidizer 的封装方法本质上就是在内部调用这些方法。无论选择哪种方式都建议在全新安装的目标系统上实测一遍以确认所有运行时依赖都已就位。分发指南文档导航本主题的完整分发指南目录为 pyoxidizer/docs/pyoxidizer_distributing.rst包含以下子文档pyoxidizer_distributing_overview.rst本文对应的概述讲解构建/打包/分发的领域划分与 Tugger 架构pyoxidizer_distributing_binary_portability.rst二进制可移植性通用策略与pyoxidizer analyze用法pyoxidizer_distributing_wix.rst用 WiX Toolset 构建 Windows 安装器pyoxidizer_distributing_linux.rstLinux 分发考量pyoxidizer_distributing_macos.rstmacOS 分发考量pyoxidizer_distributing_windows.rstWindows 分发考量。配套的 Tugger 文档位于 tugger/docs/tugger.rst项目总览与 tugger/docs/tugger_overview.rst设计理念与 crate 架构。若需要深入定制安装器细节可继续阅读 Tugger 的 Starlark 类型文档如WiXMSIBuilder、WiXBundleBuilder、FileManifest等类型的完整 API 参考。赞分享开发工具CLI【免费下载链接】PyOxidizerA modern Python application packaging and distribution tool项目地址https://gitcode.com/gh_mirrors/py/PyOxidizer点击查看免费下载相关推荐如何用 mediasoup-client 实现带宽自适应Consumer 码率控制 6 个实用技巧如何用 mediasoup client 实现带宽自适应Consumer 码率控制 6 个实用技巧 快速了解mediasoup client 与带宽自适应Just Player与ExoPlayer技术架构深度解析Just Player与ExoPlayer技术架构深度解析 Just Player是一款基于ExoPlayer构建的轻量级Android视频播放器它以简洁的设PyOxidizer项目Python应用打包与分发的终极解决方案PyOxidizer项目Python应用打包与分发的终极解决方案 项目概述 PyOxidizer是一个革命性的Python工具集旨在彻底改变Python应用开发工具CLI上一篇如何在5分钟内免费搭建浏览器SVG编辑器SVG-Edit完全指南下一篇释放Windows 11潜能tiny11builder打造纯净高效系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表