使用pynsist打包PyGObject Python 3程序?

时间:2015-03-01 14:04:42

标签: packaging gtk3 pygobject pynsist

我想用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之一)是什么?

编辑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很奇怪,因为在_gi.pyd

的同一目录(gi)中有__init__.py个文件

这是当前的布局:

 - 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我可以看到缺少2个DLL:GPSVC.DLLIESHIMS.DLL

编辑3:

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

编辑4:

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

1 个答案:

答案 0 :(得分:2)

我与pynsist的作者Thomas K一起解决这个问题。我确实想宣传它是一个很好的工具,有很好的支持,而且我认为它的包装订单更容易。

我的方法中存在许多错误(请参阅问题),因此描述正确的方法可能更容易:

下载依赖项

仅导入程序所需的唯一依赖项:

 from gi.repository import Gtk

是可以在此处下载的最新pygi-aio(当前pygi-aio-3.14)捆绑包(pynsist-repository中的示例具有下载脚本,但我可能需要针对较新版本进行更新) :

提取依赖项

现在已经合并到pynsist-repository的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文件(随捆绑包一起提供)并将编译后的文件复制回构建目录。我描述了我在这里遇到的唯一问题:

此处有一个错误报告,其中包含更多信息:

工作示例

您可以在此处获取示例: