pyinstaller gtk pixbuf problems in os x

157 views
Skip to first unread message

charles....@gmail.com

unread,
Jul 4, 2014, 12:31:21 PM7/4/14
to pyins...@googlegroups.com
Hi,

I'm pretty new to pyinstaller.  I'm having trouble running my pyinstaller-bundled gtk application under os x.  I narrowed it to a very simple file::

> """
> osx pyinstaller gtk.gdk.pixbuf_new_from_file bug demo
> """
> import sys
> import gtk
> image = gtk.gdk.pixbuf_new_from_file(sys.argv[1])
> print type(image), dir(image)

I called the file pixbuf.py.  When I run it outside of pyinstaller with a valid .png file as an argument (i.e. python pixbuf.py tmp.png), the type() statement prints <type 'gtk.gdk.Pixbuf'>, and the dir() statement returns the expected class methods of a gtk.gdk.Pixbuf.  When I bundle it with pyinstaller and execute the file in the dist directory (i.e. pyinstaller pixbuf.py; cd dist/pixbuf; ./pixbuf ../../tmp.png), the type() statement prints <class '__main__.__main__.g-option-context-error-quark'> and the dir() statement returns non-gtk.gdk.Pixbuf class methods.  That is, it does *not* return a Pixbuf.  I believe the g-option-context-error-quark is an error instance returned by gtk.gdk.pixbuf_new_from_file, but I'm not certain.

I successfully bundled with pyinstaller and ran the full application under Debian 6 and Windows 7.  The full application can be bundled and ran on OS X by commenting-out all the Pixbuf-related stuff--i.e. gtk menus, mouse, keyboard, refresh, etc. work.  I'm using OS X 10.6.8, python 2.7.7, and pyinstaller 2.1.  I used homebrew to install python and python-gtk.

Does anyone have any advice?  Yes, I've tried some of the "Find out What Went Wrong" ideas, but nothing's jumped out.

Thanks,
Charles

charles....@gmail.com

unread,
Jul 5, 2014, 10:33:23 AM7/5/14
to pyins...@googlegroups.com
As I dug deeper, it appears libgdk_pixbuf_2.0.0.dylib expects a loaders.cache file to be present which then calls the appropriate libpixbufloader-png.so file.  All of this is under /usr/local/lib/gdk-pixbuf-2.0/2.10.0 on my machine.  I could bundle that directory, but the loaders.cache would need to be modified.  I also must change libgdk_pixbuf_2.0.0.dylib to point to the new bundled directory, but I'm not sure how to do that.

It looked like a mess.  Since I already had PIL loaded, I created a workaround:

> """
> osx pyinstaller gtk.gdk.pixbuf_new_from_file bug demo
> """
>
> import sys
> import gtk
> import PIL.Image as Image
> #image = gtk.gdk.pixbuf_new_from_file(sys.argv[1])
> pilimage = Image.open(sys.argv[1])
> image = gtk.gdk.pixbuf_new_from_data(pilimage.tostring(), gtk.gdk.COLORSPACE_RGB, True, 8, pilimage.size[0], pilimage.size[1], pilimage.size[0]*4)
> print type(image), dir(image)

This is *not* the proper fix.  gtk.gdk.pixbuf_new_from_file ought to work on OS X.  If anyone knows how to modify libraries and directories under pyinstaller to get it to work, I'd still like to hear about it.

Thanks,
Charles

charles....@gmail.com

unread,
Jul 8, 2014, 12:47:00 AM7/8/14
to pyins...@googlegroups.com
I dove into the mess and came up with a working solution.  First, I generated a local copy of loaders.cache with::

gdk-pixbuf-query-loaders > loaders.cache

Then, I edited loaders.cache, removing the long path names.  For example, I changed:

"/usr/local/Cellar/gdk-pixbuf/2.30.8/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ani.so"

to:

"libpixbufloader-ani.so"

and so on.

Then, I created an rthook file called pixbuf_rthook.py to change the GDK_PIXBUF_MODULE_FILE environment variable on start-up::

> import os
> os.environ['GDK_PIXBUF_MODULE_FILE'] = os.environ['PWD'] + '/loaders.cache'

Finally, I added the rthook, libpixbufloaders*, and loaders.cache to my .spec file.  It now looks like this::

> # -*- mode: python -*-
> a = Analysis(['pixbuf.py'],
>              pathex=['/Users/apple/Downloads/test_pyinstall2'],
>              hiddenimports=['glib'],
>              hookspath=None,
>              runtime_hooks=['pixbuf_rthook.py'])
> pyz = PYZ(a.pure)
> more_binaries = []
> pixbuf_dir = '/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders'
> for pixbuf_type in os.listdir(pixbuf_dir):
>     if pixbuf_type.endswith('.so'):
>         more_binaries.append((pixbuf_type, os.path.join(pixbuf_dir, pixbuf_type), 'BINARY'))
> exe = EXE(pyz,
>           a.scripts,
>           exclude_binaries=True,
>           name='pixbuf',
>           debug=False,
>           strip=None,
>           upx=True,
>           console=True )
> coll = COLLECT(exe, [('loaders.cache', './loaders.cache', 'DATA')],
>                a.binaries + more_binaries,
>                a.zipfiles,
>                a.datas,
>                strip=None,
>                upx=True,
>                name='pixbuf')

This fixed the errors and now gtk.gdk.pixbuf_new_from_file works.

The changes to my main application were more extensive, because pango had a similar cache-type file called pango.modules and pangox.aliases which I worked in with similar methods.  If anyone would like to see the adjustments for the full application, let me know, and I can post it here.  If macports is equally as messy with gtk and pyinstaller, it probably makes sense to adjust the osx gtk hook and rthooks in PyInstaller itself so others can benefit from these findings. 

Hartmut Goebel

unread,
Jul 8, 2014, 3:42:45 AM7/8/14
to pyins...@googlegroups.com
Am 08.07.2014 06:47, schrieb charles....@gmail.com:
I dove into the mess and came up with a working solution.

Thanks. I did put your solution on <http://www.pyinstaller.org/wiki/Recipe/GtkPixbuf>. Please check if that is correct.

--
Schönen Gruß
Hartmut Goebel
Dipl.-Informatiker (univ), CISSP, CSSLP
Information Security Management, Security Governance, Secure Software Development

Goebel Consult, Landshut
http://www.goebel-consult.de

Blog: http://www.goebel-consult.de/blog/eine-millonen-aufkleber-fordern-asyl-fur-snowden
Kolumne: http://www.cissp-gefluester.de/2010-08-scheingefechte-um-rim

Goebel Consult ist Mitglied bei http://www.7-it.de/

charles....@gmail.com

unread,
Jul 10, 2014, 12:33:21 PM7/10/14
to pyins...@googlegroups.com
Hi Hartmut,

Your recipe looks correct.  However, I recommend you remove it and replace it with my more thorough recent posting Bundling a GTK application in OS X.  It covers the Pixbuf issue and other issues.  My only concern is its correctness and my newness.  It may not be the best.

- Charles
Reply all
Reply to author
Forward
0 new messages