PyQt 膨胀和 Pyinstaller
Posted
技术标签:
【中文标题】PyQt 膨胀和 Pyinstaller【英文标题】:PyQt Bloat and Pyinstaller 【发布时间】:2013-02-04 07:41:22 【问题描述】:我对 Qt 非常陌生,并且一直在使用 Qt-Designer 生成代码以与我用 python 编写的程序进行交互。但是,当我想使用 pyinstall 将它们编译成二进制文件时,我得到的 /dist/
大小约为 60 mb。使用 --onefile 选项时,我可以将其降低到大约 20 mb。
我确定膨胀是由于 Qt 导入了不必要的库造成的。谁能指出我减少这种令人担忧的膨胀的正确方向?我很肯定 20 mb 对于我正在编写的微不足道的应用程序来说是严重过剩的。感谢您的帮助。
使用:Python 2.6.5、pyinstaller 2.0、Qt 4.6.2.、PyQt4
dist中生成的文件列表:
bz2.so
_codecs_cn.so
_codecs_hk.so
_codecs_iso2022.so
_codecs_jp.so
_codecs_kr.so
_codecs_tw.so
datetime.so
_heapq.so
libaudio.so.2
libbz2.so.1.0
libcrypto.so.0.9.8
libexpat.so.1
libfontconfig.so.1
libfreetype.so.6
libgcc_s.so.1
libGLcore.so.1
libglib-2.0.so.0
libgobject-2.0.so.0
libgthread-2.0.so.0
libICE.so.6
libjpeg.so.62
liblcms.so.1
libmng.so.1
libncurses.so.5
libncursesw.so.5
libnvidia-tls.so.1
libpcre.so.3
libpng12.so.0
libpython2.6.so.1.0
libQt3Support.so.4
libQtCore.so.4
libQtGui.so.4
libQtNetwork.so.4
libQtOpenGL.so.4
libQtSql.so.4
libQtSvg.so.4
libQtXml.so.4
libreadline.so.6
libSM.so.6
libssl.so.0.9.8
libstdc++.so.6
libtiff.so.4
libuuid.so.1
libX11.so.6
libXau.so.6
libxcb.so.1
libXdmcp.so.6
libXext.so.6
libXrender.so.1
libXt.so.6
libz.so.1
_multibytecodec.so
PyQt4.QtCore.so
PyQt4.QtGui.so
qt4_plugins
readline.so
sip.so
【问题讨论】:
dist
里有什么文件?
@Janne Karila,嗨,我在原始问题中附加了/dist/
文件的列表。
【参考方案1】:
如果您要链接到 Qt4,那么“膨胀”是不可避免的,因为这些库是 Qt4 的依赖项。
为了验证这一点,您可以在库上使用ldd
来查看其共享依赖项。尝试运行 ldd libQtGui.so.4
并查看它依赖于多少个库。然后对所有其他共享库执行相同操作。
我个人不会太担心可执行文件的大小。正如您所注意到的,这主要取决于 Qt,这意味着生成的二进制文件的大小几乎不会随着应用程序的增长而改变。
【讨论】:
我有点明白你的意思,但你不认为,例如,... libnvidia-tls.so.1 对于需要一个微不足道的窗口、一个列表的应用程序来说有点矫枉过正盒子、字典、集合、随机数生成器和几个按钮?关键字:英伟达... libnvidia-tls.so.1 可能由 libGLcore.so.1 链接,而 libGLcore.so.1 又是 libQtOpenGL.so.4 的依赖项。就像我说的,复杂性是由 Qt 而不是你的应用程序增加的。您可以将应用程序的复杂性扩大 2 到 3 个数量级,但仍然发现生成的二进制大小与 Qt 及其依赖项相比相形见绌。如果空间如此宝贵,Qt 可能是错误的选择。 你是对的,虽然生成了许多依赖项,但这就是为什么我需要libaudio
,我的应用程序中没有任何音频。
那是因为您链接的是 libQtGui.so.4,这取决于 libaudio。使用ldd
并验证。如果你热衷于减少臃肿并只链接你需要的东西,你可以尝试自己构建 Qt 并只指定你需要的位。
@CadenOrange,好吧,我想我可以看看定制的 Qt,可惜没有其他方法可以让一切变得更精简。【参考方案2】:
仅供参考,请参阅 Hatchet,这是一个 Github 项目,用于分析应用程序中的依赖项并重建 PySide 绑定以适应。
Qt5 正朝着减少依赖的方向发展,将库分解为更小的库。也许 pyinstalled PyQt5 应用程序的臃肿程度较小。
即使您只导入您需要的模块,我也不确定 Pyinstaller 或 Hatchet 是否会像您所做的那样,分析 Python 直接绑定到的库是否依赖于 Python 不直接绑定到的库。
(对我而言)更糟糕的问题是 Pyinstaller 会冻结系统库,例如 libxcb,这些库与较新版本的操作系统上的其他库的较新版本(它不会冻结)不兼容。例如,我在 Ubuntu 13.04 上冻结的应用程序在 13.10 上崩溃,而在 13.10 上冻结的应用程序在 14.04beta 上崩溃。有解决方法。
【讨论】:
谢谢!下次我准备使用基于 PyQt 的应用程序时,我一定会看看这个。 Hatchet 是否仅适用于 PySlide?还是它也与 PyQt 兼容? Hatchet 项目可能已失效。我的猜测是它不适用于 PyQt。仅供参考,您可以研究一下 Riverside Computing 刚刚宣布的 PyQtDeploy。【参考方案3】:更好的是,我建立在 CadentOrange 的 ldd
建议的基础上,并使用了命令 ldd -u
,它实际上打印了未使用的直接依赖项。使用这种分析方法,我能够确定上面列出的大部分列表都是完全垃圾,并将列表缩减为区区 5 个文件。对于应用程序的单个目录部署,我能够将膨胀减少到 ~10 mb!希望对可能遇到同样问题的其他人有所帮助。
【讨论】:
我知道这是很老的帖子,但我也遇到了同样的问题。你能列出那些measly 5 files
@sundar_ima 这真的取决于你的程序正在使用什么。就我而言,这是一个非常简约的程序,只需要 pyqt4.*、libpython2.* 和必需品。例如,如果您的程序不需要datetime
,则不要导入datetime.so
。 Python 有一种方法可以只导入模块的某个子集,但我并没有想到它。我希望这有点清楚吗?基本上对我来说,它大约是 5 个文件,但其他人可能是 10 个。对你来说,它可能是任何东西,但我不能告诉你,因为对我有用的可能不适合你。
您能否发布您的工作/脚本以造福所有人:-)
我没有脚本;尝试在您的主应用程序文件上运行ldd -u
。这应该打印未使用的依赖项;这有帮助吗?
我已经这样做了。这是否意味着我可以从最终的可执行文件中排除那些未使用的依赖项?忍受我,我没有得到它。以上是关于PyQt 膨胀和 Pyinstaller的主要内容,如果未能解决你的问题,请参考以下文章