【发布时间】:2014-06-26 09:13:54
【问题描述】:
我最近尝试使用PyInstaller 从我的kivy 应用程序中构建一个包。我的目标是创建一个可以在我的 Linux(Ubuntu 14.04 64 位)上执行的包,并将其复制到其他 Linux 系统。
我整晚都在尝试正确执行 PyInstaller,尝试了各种方法,最终成功为我自己的系统创建了一个包。首先,我想知道我究竟做了什么来功能性地打包我的应用程序。
我的main.spec 文件如下所示:
# Part A
from kivy.tools.packaging.pyinstaller_hooks import install_hooks
install_hooks(globals())
# -*- mode: python -*-
# Part B
from PyInstaller.hooks.hookutils import exec_statement
hiddenimports = ['pysqlite2', 'MySQLdb', 'psycopg2']
databases = exec_statement("import sqlalchemy.databases;
print sqlalchemy.databases.__all__")
databases = eval(databases.strip())
for n in databases:
hiddenimports.append("sqlalchemy.databases." + n)
version = exec_statement('import sqlalchemy; print sqlalchemy.__version__')
is_alch06 = version >= '0.6'
if is_alch06:
dialects = exec_statement("import sqlalchemy.dialects; print sqlalchemy.dialects.__all__")
dialects = eval(dialects.strip())
for n in databases:
hiddenimports.append("sqlalchemy.dialects." + n)
block_cipher = None
# Part C
a = Analysis(['main.py'],
pathex=['/home/grafgustav/Python/ICCHP/accessmail/src','/'],
hiddenimports=[],
cipher=block_cipher)
pyz = PYZ(a.pure,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=None,
upx=True,
console=True )
coll = COLLECT(exe, Tree("/home/grafgustav/Python/ICCHP/accessmail"),
a.binaries, #...,
a.zipfiles,
a.datas,
strip=None,
upx=True,
name='main',
)
虽然我理解为什么 B 部分主要是多余的(我只是从 Internet 的某个地方复制了该部分)并且 A 部分获得了一些用于 kivy 的已完成挂钩,但我不太明白为什么这不会将整个应用程序打包为我愿意。
据我了解,钩子用于包含不直接导入的库,而是隐式导入或在运行时导入的库。就像隐藏进口一样。
主要问题是我生成的包中缺少的部分。在我的整个 src 目录中有一个文件夹“GUI”,其中包含特定于 kivy 的 *.kv 文件。包含此 GUI 文件夹的 src 文件夹包含在生成的包中,当我尝试启动程序时,*.kv 文件仍然丢失。因此,我尝试将 GUI 文件夹复制到我打包的“main”所在的同一文件夹中,并且 *.kv 文件不再丢失。为什么 PyInstaller 会复制整个 src 文件夹,但无法正确检测 GUI 文件夹? 我得到的下一个错误与 sqlalchemy 有关。因为我已经添加了一些 sqlalchemy 钩子,所以我认为打包的应用程序无法找到我用来存储数据的 data.db。这个位于我正在打包的 main.py 上方的一个文件夹中。它包含在结果中,但不在正确的位置。如果我将 data.db 复制到结果主目录上方的一个文件夹中,则此错误也将得到解决。 我的最后一个错误导致包无法工作,这又是由一些特定于 kivy 的东西引起的。错误消息说,文件 [包目录]/kivy/data/style.kv 丢失。实际上甚至没有文件夹“kivy”。我在 kivy 源中搜索了这个文件,将它复制到正确的目录,现在它可以在我的系统上运行。 现在我想知道,为什么我必须手动将所有这些文件复制到生成的目录中。我怎样才能告诉 PyInstaller 事先包含这些文件? 它可以在我的系统(我打包它的地方)上运行,但在我的第二个系统(Ubuntu 12.04LTS 64 位,关于错误的 OpenGL 版本的一些错误)上,在测试系统上(fedora,根本没有错误,只有@987654326 @) 或我大学的计算机上(Debian 3.2.57 64 位,`./main: /lib/x86_64-linux-gnu/libc.so.6: 未找到版本 GLIBC_2.14(/libz.所以.1).
我的朋友在他的 Windows 系统上使用了 PyInstaller,也遇到了一些问题(他还必须手动将上述文件/文件夹添加到包中),但最终它在 Win7 和 Win8 上同样适用。
如何使用 PyInstaller 为其他 Linux 系统以及我自己的系统制作可执行文件?我到底对main.spec 文件做了什么?或者有没有更好的方法来为 python 应用程序创建可执行文件?
【问题讨论】:
-
在链接pyinstaller.org/wiki/FAQ#Misc 中查看FAQ 中的第4 个问题。您必须在尽可能低的 GLIBC 版本中创建安装程序
标签: python packaging kivy pyinstaller