[Pythonmac-SIG] py2app and PyQt: QT plugins cause loading multiple QT library versions

Ronald Oussoren ronaldoussoren at mac.com
Sun Nov 25 14:36:49 CET 2012


On 24 Nov, 2012, at 21:50, Christian Tismer <tismer at stackless.com> wrote:

> Howdy,
> 
> On 31.05.12 21:46, Michael McCracken wrote:
>> New user, so new thread, in reference to "(PyQt and py2app) Gui starts
>> in IDLE but not as app".
>> 
>> This happens when Qt loads image plugins from the
>> system location (likely set during Qt's configure), which
>> then load the system Qt.
>> 
>> The problem and a workaround are described here:
>> http://lists.trolltech.com/qt-interest/2008-09/thread00258-0.html
>> 
>> py2app's PyQt sample doesn't exercise enough of Qt to hit this problem.
>> I'm not sure exactly what part of Qt you'd need to trigger it, but
>> I guess the Color Picker might work.
>> 
>> The quick way, if you know you don't need these plugins, is to
>> create an empty qt.conf file at MyApp.app/Contents/Resources/qt.conf.
>> 
> ...
> 
> I've hit a similar problem when trying to build a stand-alone pyside.
> Starting with a modified setup.py (not yet ready), I created a working
> pyside for virtualenv.
> The missing part was support for 'setup.py --standalone', so I found
> macholib which does a great job in creating the missing bits.

I don't quite understand, does "python setup.py py2app" not work with pyside in a virtualenv?

If so: did you have to do anything special to build such a pyside? 

> 
> I simply used a few lines of Python to try out if macholib works for me,
> like so:
> 
>> from macholib.MachOStandalone import MachOStandalone
>> from macholib.util import strip_files
>> path='/Users/tismer/src/daniel/pydica/lib/python2.7/site-packages/PySide'
>> files = MachOStandalone(path).run(contents='@rpath/Contents')

You can also use "python -m macholib standalone" with recent releases 
of macholib.

> 
> This works great so far, but the generated pyside complains about duplicate libraries.
> When I uninstall Qt, it does not find its image plugins.
> 
> I guess there is a bug somewhere, which causes the following observation:

This looks like a problem that is hopefully fixed for PyQt: Qt probably uses the
wrong prefix to find its addons (the virtualenv location instead of the application bundle),
and that causes it to load an image plugin from the virtualenv which again pulls
in libQt from the virtualenv and then you end up with duplicate symbols and later
on a crash.

For PyQt this was fixed by loading a qt.conf into the application bundle, I added
simular code for pyside, but that obviously didn't work.

> 
> $ otool -L /usr/local/Cellar/qt/4.8.3/plugins/imageformats/libqtiff.dylib
> /usr/local/Cellar/qt/4.8.3/plugins/imageformats/libqtiff.dylib:
>    libqtiff.dylib (compatibility version 0.0.0, current version 0.0.0)
> /usr/local/Cellar/qt/4.8.3/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.8.0, current version 4.8.3)
> /usr/local/Cellar/qt/4.8.3/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.3)
>    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
>    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
>    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
>    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1669.0.0)
> 
> $ otool -L /Users/tismer/src/daniel/pydica/lib/python2.7/site-packages/PySide/plugins/imageformats/libqtiff.dylib 
> /Users/tismer/src/daniel/pydica/lib/python2.7/site-packages/PySide/plugins/imageformats/libqtiff.dylib:
>    @rpath/Contents/mageformats/libqtiff.dylib (compatibility version 0.0.0, current version 0.0.0)
> @rpath/Contents/Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.8.0, current version 4.8.3)
> @rpath/Contents/Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.3)
>    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
>    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
>    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
>    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1669.0.0)
> 
> The problem might be this line:
> @rpath/Contents/mageformats/libqtiff.dylib
> 
> The "i" from "imageformats" is missing!
> 
> This _might_ be related to the unusual case that "libqtiff" has no path at all, or something else
> is funny, and we end up with a name that will not be found at all.
> Then the loader finds the plugin in the installed Qt, which causes it to load everything
> again from there.
> 
> Is that a possible explaining?
> I just found that and had not the time to debug it thoroughly.

Did you use the most recent release of py2app?

If so, there is pyside support code in py2app/recipes/pyside.py and support code
for PyQt in py2app/recipes/sip.py.  The latter works with PyQt on my machine,
although with a system-wide install not an installation in a virtualenv.

Ronald



More information about the Pythonmac-SIG mailing list