写点什么

一种 PyInstaller 中优雅的控制包大小的方法

  • 2024-08-28
    福建
  • 本文字数:1399 字

    阅读完需:约 5 分钟

PyInstaller 会在打包时自动为我们收集一些依赖项,特别是我们在打包 PyQt/PySide 相关的应用时,PyInstaller 会自动包含我们程序通常不需要的文件,如'tanslations'文件夹,'plugins/imageformats'等,通常这些文件会使我们最终的 exe 文件变大。在网上没有找任何好的方法来排除这些文件,从这个 Issue https://github.com/pyinstaller/pyinstaller/issues/5503 里我们可以看到一种方法就是在打包之前先删除 PyQt 安装目录中的不需要文件,这种做法能达到目的,但在我看来实在是不够优雅。


PyInstaller 其实最终都依靠 spec 文件来获取依赖及其它配置项,而生成 spec 文件内容是由一个模板(https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/building/templates.py)控制, 所以我们可以在生成之前去修改(patch)下这个模板,就可以达到控制依赖项的目的。

以下假设我们是通过代码方式来调用 Pyinstaller,并使用 onefile 模式(onedir 模块可参照修改).


注意以下Analysis语句后面的代码即为处理 datas 和 binaries 的代码,在这里可以添加任何过滤逻辑


import PyInsatller.building.templates as pyi_spec_templatesfrom PyInstaller.__main__ import run as pyi_build
# copy from PyInsatller.building.templates.py# add datas and binaries filter after Analysisonefiletmplate = """# -*- mode: python ; coding: utf-8 -*-%(preamble)s
a = Analysis( %(scripts)s, pathex=%(pathex)s, binaries=%(binaries)s, datas=%(datas)s, hiddenimports=%(hiddenimports)s, hookspath=%(hookspath)r, hooksconfig={}, runtime_hooks=%(runtime_hooks)r, excludes=%(excludes)s, noarchive=%(noarchive)s, optimize=%(optimize)r,)
# begin filter any datas you wantdatas = []for dest_name, src_name, res_type in a.datas: # 在这里添加过滤逻辑 datas.append((dest_name, src_name, res_type))a.datas = datas# end filter datas
# begin filter any binaries you wantbinaries = []for dest_name, src_name, res_type in a.binaries: # 在这里添加过滤逻辑 binaries.append((dest_name, src_name, res_type))a.binaries = binaries# end filter datas
pyz = PYZ(a.pure)%(splash_init)sexe = EXE( pyz, a.scripts, a.binaries, a.datas,%(splash_target)s%(splash_binaries)s %(options)s, name='%(name)s', debug=%(debug_bootloader)s, bootloader_ignore_signals=%(bootloader_ignore_signals)s, strip=%(strip)s, upx=%(upx)s, upx_exclude=%(upx_exclude)s, runtime_tmpdir=%(runtime_tmpdir)r, console=%(console)s, disable_windowed_traceback=%(disable_windowed_traceback)s, argv_emulation=%(argv_emulation)r, target_arch=%(target_arch)r, codesign_identity=%(codesign_identity)r, entitlements_file=%(entitlements_file)r,%(exe_options)s)"""
pyi_spec_templates.onefiletmplt = onefiletmplate # ==> patch the template string here
# build exepyi_build(['main.py', '--onefile', ...])
复制代码


文章转载自:Thinking110

原文链接:https://www.cnblogs.com/FocusNet/p/18382397

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
一种PyInstaller中优雅的控制包大小的方法_Java_不在线第一只蜗牛_InfoQ写作社区