Executable made with pyInstaller/UPX experiences QtCore4.dll error
我使用pyInstaller编译的python程序原来超过400 MB。该程序的GUI基于htmlPY,它是"围绕PySide的QtWebKit库的包装"。该程序之所以大,部分原因是它使用了numpy,scipy和nltk,部分是由于图形库。
为了最小化程序的大小,我安装了UPX。这将程序的大小减小到略大于100MB,这虽然很大,但是可以接受。
第一个问题是pyInstaller没有检测到htmlPy,也没有将其包含在编译程序中。可以通过将Python安装中的htmlPy模块复制到pyInstaller创建的'dist'目录中来解决此问题。完成此操作后,不使用UPX编译的程序版本运行正常。
将htmlPy添加到'dist'目录后,运行可执行文件会使GUI创建时的程序崩溃。我不确定这是否是由于UPX和QT之间或UPX,QT和htmlPy之间的交互问题。 Windows"问题签名"如下:
1 2 3 4 5 6 7 8 9 10 | Problem signature: Problem Event Name: APPCRASH Application Name: main.exe Application Version: 0.0.0.0 Application Timestamp: 00000000 Fault Module Name: QtCore4.dll Fault Module Version: 4.8.7.0 Fault Module Timestamp: 561e435a Exception Code: c0000005 Exception Offset: 000000000010883a |
关于这里发生的事情以及如何解决的任何想法?
编辑:
这些是我的.spec文件的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # -*- mode: python -*- block_cipher = None added_files = [ ( 'htmlPy/binder.js', 'htmlPy' ), ( 'templates/*', 'templates' ), ] a = Analysis(['main.py'], pathex=['C:\\\\..\\\\My_App'], binaries=None, datas=added_files, hiddenimports=[], hookspath=[], runtime_hooks=['rthook_pyqt4.py'], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, exclude_binaries=True, name='My_App', debug=False, strip=False, upx=True, console=True ) coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, name='My_App') |
这些是rthook_pyqt4.py的内容:
1 2 3 4 5 6 7 8 9 | import sip sip.setapi(u'QDate', 2) sip.setapi(u'QDateTime', 2) sip.setapi(u'QString', 2) sip.setapi(u'QTextStream', 2) sip.setapi(u'QTime', 2) sip.setapi(u'QUrl', 2) sip.setapi(u'QVariant', 2) |
编辑2:
这是一些初始化代码(标准htmlPy票价):
1 2 3 4 5 6 7 | app.static_path = path.join(BASE_DIR,"static/") print"Step 1" app.template_path = path.join(BASE_DIR,"templates/") print"Step 2" app.template = ("index.html", {"username":"htmlPy_user"}) print"Step 3" ... |
程序在进入步骤3之前崩溃。
您的两个主要问题涉及:
如果该应用较小,则该应用可能对更多人有用,但如果该应用无法运行,则对没人有用。您怀疑UPX改善了关注点2,但是其交互影响了关注点1。
构建一个简单的HelloWorld应用程序,将其与pyInstaller + UPX打包,并继续使用其他依赖项(例如Qt)对其进行修饰,直到您看到它的破坏方式类似于当前的破坏方式,将是很有意思的。
放弃UPX而采用其他方法(包括NSIS)可能会更有效率。您可能会使用strace()之类的工具来监视在系统测试运行期间实际使用了哪些分布式文件,并在打包过程中修剪了未使用的文件。通过FUSE代理请求将产生类似的信息。您可能会列出已发布应用程序的依赖项,并依靠pip或conda并行下载依赖项,如果"经过的安装时间"确实是促使您将400缩小到100 MiB的愿望的话。