使用pynsist打包PyGObject Python 3程序?

3
我希望使用pynsist打包一个Python3-PyGObject程序。该存储库有一个PyGTK示例,这让我认为更改示例不应该太难。
示例可以在此处找到: 在这个文件中 (https://github.com/takluyver/pynsist/blob/master/examples/pygtk/grab_files.sh),我认为只需要获取针对GTK 3的文件 (http://www.gtk.org/download/win32.php)。
wget -O gtkbundle.zip http://win32builder.gnome.org/gtk+-bundle_3.6.4-20130921_win32.zip
wget -O pygobject.exe http://sourceforge.net/projects/pygobjectwin32/files/pygi-aio-3.14.0_rev12-setup.exe/download
wget -O pycairo.zip http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/cairo_1.10.2-2_win32.zip

我不确定如何处理第四行,因为我目前的理解是这些绑定应该已经包含在gtk或pygobject捆绑包中:

 wget -O pygtk.exe http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.24/pygtk-2.24.0.win32-py2.7.exe

我尝试自定义这个文件(https://github.com/takluyver/pynsist/blob/master/examples/pygtk/installer.cfg),以包含(使用gi而不是gi.repository):
[Include]
packages=gi

这个错误的原因是: raise ExtensionModuleMismatch(extensionmod_errmsg % ('Windows', path)) nsist.copymodules.ExtensionModuleMismatch: Found an extension module that will not be usable on Windows: /usr/lib/python3/dist-packages/gi/_gi.cpython-34m-x86_64-linux-gnu.so Put Windows packages in pynsist_pkgs/ to avoid this. 有人知道像https://python-gtk-3-tutorial.readthedocs.org这样的程序在Windows上的正确方法吗?

编辑 1

在Windows上打包和安装程序后,启动测试程序会产生以下回溯:
Traceback (most recent call last):
  File "C:\Program Files (x86)\hellogtk\hellogtk.launch.pyw", line 31, in <module>
    from gtk_test import main
  File "C:\Program Files (x86)\hellogtk\pkgs\gtk_test.py", line 3, in <module>
    from gi.repository import Gtk
  File "C:\Program Files (x86)\hellogtk\pkgs\gi\__init__.py", line 42, in <module>
    from . import _gi
ImportError: DLL load failed: The specified module could not be found.

这个 ImportError 出现很奇怪,因为在与 __init__.py 同一目录(gi)中有一个 _gi.pyd 文件。
当前布局如下:
 - directory
 |- pynsist_pkgs
 |-- cairo
 |--- _cairo.pyd
 |--- __init__.py
 |-- gi
 |--- _gobject
 |--- overrides
 |--- repository
 |--- __init__.py
 |--- _gi.pyd
 |--- ...
 |-- gtk
 |--- bin
 |--- etc
 |--- lib
 |--- manifest
 |--- share
 |-- dbus
 |--- __init__.py
 |--- ...
 |-- gnome
 |--- ...
 |-- pygtkcompat
 |--- ...
 |-- _dbus_bindings.pyd
 |-- _dbus_glib_bindings.pyd
 |-- ...
 |- gtk_test.py
 |- grab_files.sh
 |- installer.cfg
 |- gtk_preamble.py

我使用了pygobject绑定的py-3.4-64文件夹。我正在创建包的Linux是64位的,我运行程序的Windows也是64位的。

编辑2:

使用Dependency-Walker,我可以看到缺少两个DLL文件:GPSVC.DLLIESHIMS.DLL

编辑3:

我在系统中找到了这两个DLL文件,并将它们复制到测试程序的不同目录中,但没有起作用。

编辑4:

这可能对于导入错误有用:


1
没错。这个想法是你先运行 ./grab-files.sh,它会把那些库的 Windows 版本放在 pynsist_pkgs 中,这样它们就会被用来代替你的 Linux 库。我已经弄清楚了,可以使用 7z(在 Ubuntu 系统上使用 apt-get install p7zip-full)来解压缩 pygi 安装程序。这会在几个目录中解压出 1.5 GB 的文件!看起来你需要找出哪些部分是你需要的,然后进行第二轮解压缩以获取实际的文件。 - Thomas K
1
如果您成功安装并尝试运行应用程序,但它崩溃了,那么它应该会将回溯信息写入到 %APPDATA% 中的日志文件中。在 Windows 7 系统上,通常是 C:\Users\{username}\AppData\Roaming。这应该有助于告诉您出了什么问题。或者您可以启动命令提示符,cd 到 Program Files 中安装目录并运行 py MyApp.launch.pyw - Thomas K
那个错误信息('DLL load failed')意味着它无法找到另一个DLL,而该DLL(.pyd文件是Python DLLs)需要。Dependency walker 可能会帮助你找出问题所在。 - Thomas K
@ThomasK:使用dw我找到了2个缺失的dll。仍需阅读原因。其实,解决问题非常有趣,但是打包对我来说总觉得很困难。我应该在大学多选一些编程课程 :) - tobias47n9e
说实话,我认为为Windows打包PyGObject应用程序对于任何人来说都很难。你有找到需要的DLL吗?这个示例是一个用cx_Freeze冻结应用程序的脚本,可能会有帮助。 - Thomas K
显示剩余16条评论
1个回答

2
我与pynsist的作者Thomas K合作解决了这个问题。我想宣传一下pynsist是一个非常好的工具,有很好的支持,我认为它可以使打包变得更容易。

我的方法存在一些错误(见问题),因此描述正确的方法可能更容易:

下载依赖项

对于仅导入的程序,唯一需要的依赖项是:

 from gi.repository import Gtk

这是最新的pygi-aio(目前为pygi-aio-3.14)捆绑包,可以在此处下载(pynsist存储库中的示例有一个下载脚本,但可能需要更新以适应较新的版本):

提取依赖项

现在已合并到pynsist存储库中的PyGObject/PyGI示例,附带一个脚本,可以从捆绑包中提取必要的依赖项 (参见: https://github.com/takluyver/pynsist/tree/master/examples/pygi_mpl_numpy)。

最重要的是,它提取了绑定 zip 文件的内容(修改脚本以适配目标 Python 版本和位数),并将其复制到 pynsist_pkgs 文件夹中:

  - cairo
  - dbus
  - gi
  - gnome
  - pygtkcompat

然后它会提取并复制子依赖项到pynsist_pkgs/gnome/文件夹中。正如lazka所指出的那样,一个典型的最小Gtk程序的最低要求是(每个库都有一个pygi/noarchpygi/[TargetedArchitecture] zip文件):
 - ATK
 - Base
 - Gdk
 - GDKPixbuf
 - GTK
 - JPEG
 - Pango
 - WebP
 - TIFF

构建安装程序

在我的情况下,使用以下命令构建安装程序:

 python3 -m nsist installer.cfg

安装程序文件installer.cfg也在存储库示例文件夹中。它只需要列出gnome(gnome文件夹中的子依赖项行为像一个单元)。

关于pygi-aio捆绑包的注意事项

当在Windows机器上安装pygi-aio时,安装程序会执行一些后安装编译步骤。如果您使用此方法可能会出现问题,因为它仅提取依赖项。在某些情况下,您可能需要运行一个exe文件(随捆绑包提供),并将编译后的文件复制回您的构建目录中。我在这里描述了我遇到的唯一问题:

这里有一个更详细的错误报告:

工作示例

您可以在此处获取示例:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接