I'm stuck again with the next issue: starting the PyQt4 app on a pristine
mac results in:
Mac OS X Version 10.4.11 (Build 8S165)
2009-07-02 10:06:59 +0200
2009-07-02 10:07:03.260 SystemUIServer[120] lang is:de
Workaround Bonjour: Unknown error: 0
Traceback (most recent call last):
File "<string>", line 34, in <module>
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 480, in importHook
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 498, in doimport
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 300, in getmod
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/archive.py", line 468, in getmod
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 109, in getmod
ImportError: dlopen(/Applications/CReport.app/Contents/MacOS/PyQt4.QtCore.so, 2): Library not loaded: QtCore.framework/Versions/4/QtCore
Referenced from: /Applications/CReport.app/Contents/MacOS/PyQt4.QtCore.so
Reason: image not found
Apart from the devel path leaking into the app, it obviously cannot
locate the QtCore library. BTW, there where issues with BUNDLE(), I examine
later. For now, the manually created bundle with .app/Contents/MacOS containing
everything from the one-dir run should be sufficient. Here the MacOS folder
content:
$ ls -l /Applications/CReport.app/Contents/MacOS/
total 100352
-rwxrwxr-x 1 root admin 1331492 Jul 2 00:21 CReport
-rwxrwxr-x 1 root admin 85876 Apr 16 09:23 MacOS.so
-rwxrwxr-x 1 root admin 118528 Apr 16 09:23 Nav.so
-rwxrwxr-x 1 root admin 2078692 Jul 1 23:47 PyQt4.QtCore.so
-rwxrwxr-x 1 root admin 9433500 Jul 1 23:47 PyQt4.QtGui.so
-rwxrwxr-x 1 root admin 9367288 Apr 16 09:28 Python
-rwxrwxr-x 1 root admin 131676 Apr 16 09:24 _AE.so
-rwxrwxr-x 1 root admin 426328 Apr 16 09:24 _Ctl.so
-rwxrwxr-x 1 root admin 148036 Apr 16 09:24 _Dlg.so
-rwxrwxr-x 1 root admin 78336 Apr 16 09:25 _Evt.so
-rwxrwxr-x 1 root admin 260632 Apr 16 09:25 _File.so
-rwxrwxr-x 1 root admin 246392 Apr 16 09:26 _Menu.so
-rwxrwxr-x 1 root admin 458268 Apr 16 09:26 _Qd.so
-rwxrwxr-x 1 root admin 147044 Apr 16 09:26 _Res.so
-rwxrwxr-x 1 root admin 258092 Apr 16 09:27 _Win.so
-rwxrwxr-x 1 root admin 54644 Apr 16 09:18 _bisect.so
-rwxrwxr-x 1 root admin 150336 Apr 16 09:18 _collections.so
-rwxrwxr-x 1 root admin 653552 Apr 16 09:28 _ctypes.so
-rwxrwxr-x 1 root admin 59956 Apr 16 09:18 _functools.so
-rwxrwxr-x 1 root admin 77520 Apr 16 09:20 _hashlib.so
-rwxrwxr-x 1 root admin 81136 Apr 16 09:18 _heapq.so
-rwxrwxr-x 1 root admin 75780 Apr 16 09:19 _locale.so
-rwxrwxr-x 1 root admin 142620 Apr 16 09:22 _multibytecodec.so
-rwxrwxr-x 1 root admin 159072 Apr 16 09:23 _multiprocessing.so
-rwxrwxr-x 1 root admin 70516 Apr 16 09:18 _random.so
-rwxrwxr-x 1 root admin 96432 Apr 16 09:20 _sha256.so
-rwxrwxr-x 1 root admin 179272 Apr 16 09:20 _sha512.so
-rwxrwxr-x 1 root admin 234228 Apr 16 09:20 _socket.so
-rwxrwxr-x 1 root admin 189384 Apr 16 09:20 _ssl.so
-rwxrwxr-x 1 root admin 166232 Apr 16 09:17 _struct.so
-rwxrwxr-x 1 root admin 48208 Apr 16 09:17 _weakref.so
-rwxrwxr-x 1 root admin 178168 Apr 16 09:17 array.so
-rwxrwxr-x 1 root admin 116096 Apr 16 09:21 binascii.so
-rwxrwxr-x 1 root admin 344800 Apr 16 09:21 bz2.so
-rwxrwxr-x 1 root admin 359340 Apr 16 09:19 cPickle.so
-rwxrwxr-x 1 root admin 91936 Apr 16 09:19 cStringIO.so
-rwxrwxr-x 1 root admin 395388 Apr 16 09:18 datetime.so
-rwxrwxr-x 1 root admin 71444 Apr 16 09:19 fcntl.so
drwxrwxr-x 4 root admin 136 Jul 2 03:07 i18n
-rwxrwxr-x 1 root admin 73416 Apr 16 09:24 icglue.so
-rwxrwxr-x 1 root admin 211632 Apr 16 09:18 itertools.so
-rwxrwxr-x 1 root admin 7895472 Apr 1 07:45 libSystem.B.dylib
-rwxrwxr-x 1 root admin 4606384 Feb 11 04:18 libcrypto.0.9.7.dylib
-rwxrwxr-x 1 root admin 264016 Oct 6 2007 libgcc_s.1.dylib
-rwxrwxr-x 1 root admin 142400 Jan 26 09:49 libmathCommon.A.dylib
-rwxrwxr-x 1 root admin 373984 Jan 26 10:15 libmx.A.dylib
-rwxrwxr-x 1 root admin 714756 Apr 16 09:01 libncurses.5.dylib
-rwxrwxr-x 1 root admin 915632 Feb 11 04:18 libssl.0.9.7.dylib
-rwxrwxr-x 1 root admin 3035296 Sep 24 2007 libstdc++.6.dylib
-rwxrwxr-x 1 root admin 346144 Sep 24 2007 libz.1.dylib
-rwxrwxr-x 1 root admin 103616 Apr 16 09:18 math.so
-rwxrwxr-x 1 root admin 104328 Apr 16 09:19 mmap.so
-rwxrwxr-x 1 root admin 117904 Apr 16 09:18 operator.so
-rwxrwxr-x 1 root admin 1220768 Apr 16 09:22 pyexpat.so
drwxrwxr-x 6 root admin 204 Jul 2 00:20 qt4_plugins
-rwxrwxr-x 1 root admin 577320 Apr 16 09:19 readline.so
-rwxrwxr-x 1 root admin 116492 Apr 16 09:19 select.so
-rwxrwxr-x 1 root admin 80364 Jul 1 23:15 sip.so
-rwxrwxr-x 1 root admin 130364 Apr 16 09:18 strop.so
-rwxrwxr-x 1 root admin 69568 Apr 16 09:21 termios.so
-rwxrwxr-x 1 root admin 88328 Apr 16 09:18 time.so
-rwxrwxr-x 1 root admin 1253792 Apr 16 09:19 unicodedata.so
-rwxrwxr-x 1 root admin 250064 Apr 16 09:21 zlib.so
Looks like the PyQt modules try to access QtCore.framework/Versions/4
which seem to be missing:
$ otool -L CReport.app/Contents/MacOS/PyQt4.Qt*
CReport.app/Contents/MacOS/PyQt4.QtCore.so:
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current
version 34.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
CReport.app/Contents/MacOS/PyQt4.QtGui.so:
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.46.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.4.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
Shouldn't this work out of the box? I would very much like to keep the
original Qt build, I'm using here. Needless to say, running it with
Qt installed, works fine. (There seem to be similar issues with the
qt4_plugins location which gets picked up from the systems Qt
installation, rather then those incuded in the package.
Current packages installed on the developer machine:
xcode313_2736_developerdvd.dmg
python-2.6.2-macosx2009-04-16.dmg
qt-sdk-mac-opensource-2009.03.dmg
sip-4.8.1.tar.gz
PyQt-mac-gpl-4.5.1.tar.gz (with minor Configure.py patch for Qt 4.5.2 compatibility)
http://svn.pyinstaller.org/trunk:685
Any ideas on what's going wrong here?
Thanks in advance,
Pete
Okay, found it: http://doc.trolltech.com/4.5/deployment-mac.html
Seems to me, that there's quite a bit of way to go before this all is usable
painlessly.
Pete
Giovanni, if I add code for Qt library relocation/inclusion for PyInstaller,
could you please briefly outline the way, you would do it (in order that
you can accept these patches later?
Pete
> Shouldn't this work out of the box? I would very much like to keep the
> original Qt build, I'm using here. Needless to say, running it with
> Qt installed, works fine.
Yes, it should work out of the box, and I have sucessfully managed to
ship PyQt applications on Mac.
It might be related to the fact that PyInstaller seems not to set
DYLD_LIBRARY_PATH correctly in one-dir mode.
Does it work in one-file mode? If so, it's should be easy to fix.
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com
Hmm, given that the libs are missing, how could setting a environment
variable fix that problem?
> Does it work in one-file mode? If so, it's should be easy to fix.
No, it doesn't, but since the analyse part is the same, it cannot.
Did you really shipped apps, based on a current Qt framework build, and it
worked out of the box (without Qt installed on the target systems)?!?
Here's what I did (hopefully complete):
cd .app/Contents
md Framework
cp -R /Library/Frameworks/Qt{Core,Gui}.framework Framework
find Framework -depth -name Headers -exec rm -r {} \;
find Framework -depth -name \*_debug\* -exec rm -r {} \;
# treat QtCore
install_name_tool -id \
@executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore \
QtCore.framework/Versions/4.0/QtCore
install_name_tool -change QtCore.framework/Versions/4/QtCore \
@executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore \
QtCore.framework/Versions/4.0/QtCore
# treat QtGui
install_name_tool -id \
@executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui \
QtGui.framework/Versions/4.0/QtGui
install_name_tool -change QtCore.framework/Versions/4/QtCore \
@executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore \
QtGui.framework/Versions/4.0/QtGui
# treat PyQt4.QtCore
install_name_tool -change QtCore.framework/Versions/4/QtCore \
@executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore ../MacOS/PyQt4.QtCore.so
# treat PyQt4.QtGui
install_name_tool -change QtCore.framework/Versions/4/QtCore \
@executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore ../MacOS/PyQt4.QtGui.so
install_name_tool -change QtGui.framework/Versions/4/QtGui \
@executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui ../MacOS/PyQt4.QtGui.so
# check, if something is still missing
otool -L ../MacOS/PyQt4.Qt*.so QtCore.framework/QtCore QtGui.framework/QtGui
You see, the whole mess is asking for automatic treatment. What I'm thinking
about, is getting rid of the Framework junk, and simply throw the lib files
QtCore, QtGui, etc into "the" dir (renaming them to Qt*.so), and do the
adjustments as outlined above, but I haven't tried this yet.
I think, this deserves a mac related option (one may don't want to ship
Qt), but by default the libs should be included. Using qt4_plugins may
deserve another option, since they need the same treatment as above, and
on that way pull nearly the full distribution into the bundle. Thus I may
decide to do without them, and spare a lot of space. BTW, do you know,
what codecs are shipped in libqtwcodecs.dylib? They can't be essential,
since my simple app works without them at least (due to missing "the"
treatment ATM).
Pete
Sorry, I had misread your original mail.
> > Does it work in one-file mode? If so, it's should be easy to fix.
>
> No, it doesn't, but since the analyse part is the same, it cannot.
>
> Did you really shipped apps, based on a current Qt framework build, and it
> worked out of the box (without Qt installed on the target systems)?!?
Yes. I'm not 100% sure my deployment Mac has the standard Qt framework
though; I'll have to check.
I still can't see what it is going on. mf.py (which is the dependency
analyzer) should be able to find the Qt libraries from the PyQt4 ones.
What happens if you run "bindepend.py PyQt4.QtCore4.so"? Does it list Qt
dependencies? Under what path?
Yes it would be better to just put everything inside the output
directory, like we do on other platforms (unless dyld makes this really
impossible -- which I hope it does not).
The install_name_tool trick shouldn't be necessary: I used to do it
automatically in PyInstaller, but it turned out to have compatibility
problems across different Mac OSX versions (I don't recall details) and
setting DYLD_LIBRARY_PATH instead was just as effective.
You don't need to rename Qt libraries to ".so". If I recall correctly,
they can stay as-is. Just try copying them within the output directory
and see what happens (and set DYLD_LIBRARY_PATH to point to that
directory as well).
> I think, this deserves a mac related option (one may don't want to ship
> Qt), but by default the libs should be included. Using qt4_plugins may
> deserve another option, since they need the same treatment as above, and
> on that way pull nearly the full distribution into the bundle.
This is a totally different topic, as PyInstaller treats qt4_plugins
mostly as data files. We'll have to find out why hook-PyQt4.Qt*.py don't
find the Qt4 plugins directory.
> Thus I may
> decide to do without them, and spare a lot of space. BTW, do you know,
> what codecs are shipped in libqtwcodecs.dylib? They can't be essential,
> since my simple app works without them at least (due to missing "the"
> treatment ATM).
I don't know.
Am Freitag, 3. Juli 2009 schrieb Giovanni Bajo:
> On gio, 2009-07-02 at 21:56 +0200, Hans-Peter Jansen wrote:
> > Am Donnerstag, 2. Juli 2009 schrieb Giovanni Bajo:
> > > On 7/2/2009 11:23 AM, Hans-Peter Jansen wrote:
> > > > Shouldn't this work out of the box? I would very much like to keep
> > > > the original Qt build, I'm using here. Needless to say, running it
> > > > with Qt installed, works fine.
> > >
> > > Yes, it should work out of the box, and I have sucessfully managed to
> > > ship PyQt applications on Mac.
> > >
> > > It might be related to the fact that PyInstaller seems not to set
> > > DYLD_LIBRARY_PATH correctly in one-dir mode.
> >
> > Hmm, given that the libs are missing, how could setting a environment
> > variable fix that problem?
>
> Sorry, I had misread your original mail.
Excuse me, I don't wanted to sound rude. I tend to be explicite sometimes..
> > > Does it work in one-file mode? If so, it's should be easy to fix.
> >
> > No, it doesn't, but since the analyse part is the same, it cannot.
> >
> > Did you really shipped apps, based on a current Qt framework build, and
> > it worked out of the box (without Qt installed on the target
> > systems)?!?
>
> Yes. I'm not 100% sure my deployment Mac has the standard Qt framework
> though; I'll have to check.
>
> I still can't see what it is going on. mf.py (which is the dependency
> analyzer) should be able to find the Qt libraries from the PyQt4 ones.
> What happens if you run "bindepend.py PyQt4.QtCore4.so"? Does it list Qt
> dependencies? Under what path?
$ tools/pyinstaller/bindepend.py dist/CReport/PyQt4.QtCore.so
dist/CReport/PyQt4.QtCore.so E: cannot find path QtCore.framework/Versions/4/QtCore
(needed by dist/CReport/PyQt4.QtCore.so)
['/usr/lib/libz.1.dylib', '/usr/lib/libSystem.B.dylib',
'/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices',
'/usr/lib/libstdc++.6.dylib', '/usr/lib/libgcc_s.1.dylib']
Obviously, Qt uses a path relative to /Library/Frameworks.
With the gross hack appended, pyinstaller got rid of the error and added Qt{Core,Gui}:
$ python tools/pyinstaller/bindepend.py dist/CReport/PyQt4.QtCore.so
dist/CReport/PyQt4.QtCore.so ['/Library/Frameworks/QtCore.framework/Versions/4/QtCore',
'/usr/lib/libz.1.dylib', '/usr/lib/libSystem.B.dylib',
'/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices',
'/usr/lib/libstdc++.6.dylib', '/usr/lib/libgcc_s.1.dylib']
Okay, that's missing as well:
output from print os.environ
{'SHELL': '/bin/bash', 'QT_PLUGIN_PATH': 'qt4_plugins:',
'PYTHONPATH': '/Applications/CReport.app/Contents/MacOS',
'SECURITYSESSIONID': '6052c0', '__CF_USER_TEXT_ENCODING': '0x1F5:0:3',
'USER': 'hp', 'HOME': '/Users/hp', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin'}
Traceback (most recent call last):
File "<string>", line 36, in <module>
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 480, in importHook
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 498, in doimport
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 300, in getmod
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/archive.py", line 468, in getmod
File "/Users/hp/Desktop/PyQt-Devel/creport/tools/pyinstaller/iu.py", line 109, in getmod
ImportError: dlopen(/Applications/CReport.app/Contents/MacOS/PyQt4.QtCore.so, 2):
Library not loaded: QtCore.framework/Versions/4/QtCore
Referenced from: /Applications/CReport.app/Contents/MacOS/PyQt4.QtCore.so
Reason: image not found
I tried to find the right spot for adding it, but failed. source/linux/main.s
looks to me, like it should appear (as long as workpath is not empty).
> You don't need to rename Qt libraries to ".so". If I recall correctly,
> they can stay as-is. Just try copying them within the output directory
> and see what happens (and set DYLD_LIBRARY_PATH to point to that
> directory as well).
Could you give me the hint, where DYLD_LIBRARY_PATH is missing, and I'm
testing it right away.
> > I think, this deserves a mac related option (one may don't want to ship
> > Qt), but by default the libs should be included. Using qt4_plugins may
> > deserve another option, since they need the same treatment as above,
> > and on that way pull nearly the full distribution into the bundle.
>
> This is a totally different topic, as PyInstaller treats qt4_plugins
> mostly as data files. We'll have to find out why hook-PyQt4.Qt*.py don't
> find the Qt4 plugins directory.
It looks like QT_PLUGIN_PATH is set correctly, and they also appear
altogether, but those plugins bind with nearly all Qt libs in existence,
and this dependancy is not handled correctly, yet.
$ find . -name \*.dylib -exec otool -L {} \; | grep -i qt
./accessible/libqtaccessiblecompatwidgets.dylib:
libqtaccessiblecompatwidgets.dylib (compatibility version 0.0.0, current version 0.0.0)
Qt3Support.framework/Versions/4/Qt3Support (compatibility version 4.5.0, current version 4.5.2)
QtSql.framework/Versions/4/QtSql (compatibility version 4.5.0, current version 4.5.2)
QtXml.framework/Versions/4/QtXml (compatibility version 4.5.0, current version 4.5.2)
QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./accessible/libqtaccessiblewidgets.dylib:
libqtaccessiblewidgets.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./codecs/libqtwcodecs.dylib:
libqtwcodecs.dylib (compatibility version 0.0.0, current version 0.0.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtSvg.framework/Versions/4/QtSvg (compatibility version 4.5.0, current version 4.5.2)
QtXml.framework/Versions/4/QtXml (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
QtSvg.framework/Versions/4/QtSvg (compatibility version 4.5.0, current version 4.5.2)
QtXml.framework/Versions/4/QtXml (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqtiff.dylib:
libqtiff.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
> > Thus I may
> > decide to do without them, and spare a lot of space. BTW, do you know,
> > what codecs are shipped in libqtwcodecs.dylib? They can't be essential,
> > since my simple app works without them at least (due to missing "the"
> > treatment ATM).
Hopefully, my point is clearer now.
Thanks for your support, Giovanni. I really appreciate that.
Pete
Oops, not complete:
$ find . -name \*.dylib -exec otool -L {} \; | egrep -i 'qt|libq'
./accessible/libqtaccessiblecompatwidgets.dylib:
libqtaccessiblecompatwidgets.dylib (compatibility version 0.0.0, current version 0.0.0)
Qt3Support.framework/Versions/4/Qt3Support (compatibility version 4.5.0, current version 4.5.2)
QtSql.framework/Versions/4/QtSql (compatibility version 4.5.0, current version 4.5.2)
QtXml.framework/Versions/4/QtXml (compatibility version 4.5.0, current version 4.5.2)
QtNetwork.framework/Versions/4/QtNetwork (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./accessible/libqtaccessiblewidgets.dylib:
libqtaccessiblewidgets.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./codecs/libqcncodecs.dylib:
libqcncodecs.dylib (compatibility version 0.0.0, current version 0.0.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./codecs/libqjpcodecs.dylib:
libqjpcodecs.dylib (compatibility version 0.0.0, current version 0.0.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./codecs/libqkrcodecs.dylib:
libqkrcodecs.dylib (compatibility version 0.0.0, current version 0.0.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./codecs/libqtwcodecs.dylib:
libqtwcodecs.dylib (compatibility version 0.0.0, current version 0.0.0)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./iconengines/libqsvgicon.dylib:
libqsvgicon.dylib (compatibility version 0.0.0, current version 0.0.0)
QtSvg.framework/Versions/4/QtSvg (compatibility version 4.5.0, current version 4.5.2)
QtXml.framework/Versions/4/QtXml (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqgif.dylib:
libqgif.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqico.dylib:
libqico.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqjpeg.dylib:
libqjpeg.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqmng.dylib:
libqmng.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqsvg.dylib:
libqsvg.dylib (compatibility version 0.0.0, current version 0.0.0)
QtSvg.framework/Versions/4/QtSvg (compatibility version 4.5.0, current version 4.5.2)
QtXml.framework/Versions/4/QtXml (compatibility version 4.5.0, current version 4.5.2)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
./imageformats/libqtiff.dylib:
libqtiff.dylib (compatibility version 0.0.0, current version 0.0.0)
QtGui.framework/Versions/4/QtGui (compatibility version 4.5.0, current version 4.5.2)
QtCore.framework/Versions/4/QtCore (compatibility version 4.5.0, current version 4.5.2)
Pete
Am Freitag, 3. Juli 2009 schrieb Hans-Peter Jansen:
> >
> > Yes it would be better to just put everything inside the output
> > directory, like we do on other platforms (unless dyld makes this really
> > impossible -- which I hope it does not).
No, at least with lib relocation via install_name_tool all is well. Just
tested. I guess, that setting DYLD_LIBRARY_PATH will be fine, too. Will
test as soon as you give me the hint on how to get this going.
And now for something completely different: why get checkable group boxes
rendered different between Mac OS-X 10.4 and 10.5 and why is the font
kerning damaged on the latter.. Oh well. Let's see what the trolls say!
Have a nice weekend,
Pete
Don't worry, no offense taken :)
>>>> Does it work in one-file mode? If so, it's should be easy to fix.
>>> No, it doesn't, but since the analyse part is the same, it cannot.
>>>
>>> Did you really shipped apps, based on a current Qt framework build, and
>>> it worked out of the box (without Qt installed on the target
>>> systems)?!?
>> Yes. I'm not 100% sure my deployment Mac has the standard Qt framework
>> though; I'll have to check.
>>
>> I still can't see what it is going on. mf.py (which is the dependency
>> analyzer) should be able to find the Qt libraries from the PyQt4 ones.
>> What happens if you run "bindepend.py PyQt4.QtCore4.so"? Does it list Qt
>> dependencies? Under what path?
>
> $ tools/pyinstaller/bindepend.py dist/CReport/PyQt4.QtCore.so
> dist/CReport/PyQt4.QtCore.so E: cannot find path QtCore.framework/Versions/4/QtCore
> (needed by dist/CReport/PyQt4.QtCore.so)
> ['/usr/lib/libz.1.dylib', '/usr/lib/libSystem.B.dylib',
> '/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices',
> '/usr/lib/libstdc++.6.dylib', '/usr/lib/libgcc_s.1.dylib']
>
> Obviously, Qt uses a path relative to /Library/Frameworks.
>
> With the gross hack appended, pyinstaller got rid of the error and added Qt{Core,Gui}:
>
> $ python tools/pyinstaller/bindepend.py dist/CReport/PyQt4.QtCore.so
> dist/CReport/PyQt4.QtCore.so ['/Library/Frameworks/QtCore.framework/Versions/4/QtCore',
> '/usr/lib/libz.1.dylib', '/usr/lib/libSystem.B.dylib',
> '/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices',
> '/usr/lib/libstdc++.6.dylib', '/usr/lib/libgcc_s.1.dylib']
OK, this requires some Mac Guru to tell us how dyld resolves the
dependencies at runtime. I thought otool -L always output absolute
paths, but if that's not the case, how are we supposed to find out the
absolute paths?
I don't have a Mac right now. Maybe someone can chime in?
In one-dir mode, I *believe* that workpath is empty (I'm not sure I
fully understand the code in there). Try putting some debug messages in
there to debug.
Anyway, to test if it's the right approach, it is of course sufficient
to manually set DYLD_LIBRARY_PATH:
$ DYLD_LIBRARY_PATH=`pwd` ./myapp
If this works, at least we know that we don't need to play any
install_name_tool game.
>>> I think, this deserves a mac related option (one may don't want to ship
>>> Qt), but by default the libs should be included. Using qt4_plugins may
>>> deserve another option, since they need the same treatment as above,
>>> and on that way pull nearly the full distribution into the bundle.
>> This is a totally different topic, as PyInstaller treats qt4_plugins
>> mostly as data files. We'll have to find out why hook-PyQt4.Qt*.py don't
>> find the Qt4 plugins directory.
>
> It looks like QT_PLUGIN_PATH is set correctly, and they also appear
> altogether, but those plugins bind with nearly all Qt libs in existence,
> and this dependancy is not handled correctly, yet.
This should be fixed wherever we fix the PyQt <-> Qt dependency, that is
with DYLD_LIBRARY_PATH (hopefully).
As you know, I'm in no way a Mac Guru, but I'am able to read man pages,
which ought to be sufficient in this case:
DYLD_FRAMEWORK_PATH
This is a colon separated list of directories that contain frameworks.
The dynamic linker searches these directories before it searches for
the framework by its install name. It allows you to test new versions
of existing frameworks. (A framework is a library install name that
ends in the form XXX.framework/Versions/YYY/XXX or XXX.framework/XXX,
where XXX and YYY are any name.)
For each framework that a program uses, the dynamic linker looks for
the framework in each directory in DYLD_FRAMEWORK_PATH in turn. If it
looks in all the directories and can't find the framework, it searches
the directories in DYLD_LIBRARY_PATH in turn. If it still can't find
the framework, it then searches DYLD_FALLBACK_FRAMEWORK_PATH and
DYLD_FALLBACK_LIBRARY_PATH in turn.
Use the -L option to otool(1). to discover the frameworks and shared
libraries that the executable is linked against.
DYLD_FALLBACK_FRAMEWORK_PATH
This is a colon separated list of directories that contain frameworks.
It is used as the default location for frameworks not found in their
install path.
By default, it is set to /Library/Frameworks:/Network/Library/Frame-
works:/System/Library/Frameworks
Given that info, and leaving DYLD_LIBRARY_PATH, DYLD_FALLBACK_LIBRARY_PATH
and DYLD_ROOT_PATH alone, it boils down to this patch:
Index: bindepend.py
===================================================================
--- bindepend.py (Revision 59)
+++ bindepend.py (Arbeitskopie)
@@ -354,6 +354,12 @@
"""Find the binary dependencies of PTH.
This implementation is for otool platforms"""
+ # dyld searches these paths for framework libs
+ # we ignore DYLD_FALLBACK_LIBRARY_PATH for now (man dyld)
+ fwpaths = ['/Library/Frameworks', '/Network/Library/Frameworks', '/System/Library/Frameworks']
+ for p in reversed(os.environ.get('DYLD_FRAMEWORK_PATH', '').split(':')):
+ if p:
+ fwpaths.insert(0, p)
rslt = []
for line in os.popen('otool -L "%s"' % pth).readlines():
m = re.search(r"\s+(.*?)\s+\(.*\)", line)
@@ -363,6 +369,13 @@
rel_path = lib.replace("@executable_path",".")
rel_path = os.path.join(os.path.dirname(pth), rel_path)
lib = os.path.abspath(rel_path)
+ elif not os.path.isabs(lib):
+ # lookup matching framework path, if relative pathname
+ for p in fwpaths:
+ fwlib = os.path.join(p, lib)
+ if os.path.exists(fwlib):
+ lib = fwlib
+ break
if os.path.exists(lib):
rslt.append(lib)
else:
For your convenience, it's also attached.
>
> In one-dir mode, I *believe* that workpath is empty (I'm not sure I
> fully understand the code in there). Try putting some debug messages in
> there to debug.
>
> Anyway, to test if it's the right approach, it is of course sufficient
> to manually set DYLD_LIBRARY_PATH:
>
> $ DYLD_LIBRARY_PATH=`pwd` ./myapp
>
> If this works, at least we know that we don't need to play any
> install_name_tool game.
I'm pretty confident, taht it will, given that all this is documented:
DYLD_LIBRARY_PATH
This is a colon separated list of directories that contain libraries.
The dynamic linker searches these directories before it searches the
default locations for libraries. It allows you to test new versions of
existing libraries.
For each library that a program uses, the dynamic linker looks for it
in each directory in DYLD_LIBRARY_PATH in turn. If it still can't find
the library, it then searches DYLD_FALLBACK_FRAMEWORK_PATH and
DYLD_FALLBACK_LIBRARY_PATH in turn.
Use the -L option to otool(1). to discover the frameworks and shared
libraries that the executable is linked against.
> >>> I think, this deserves a mac related option (one may don't want to
> >>> ship Qt), but by default the libs should be included. Using
> >>> qt4_plugins may deserve another option, since they need the same
> >>> treatment as above, and on that way pull nearly the full distribution
> >>> into the bundle.
> >>
> >> This is a totally different topic, as PyInstaller treats qt4_plugins
> >> mostly as data files.
That's the culprit!
> >> We'll have to find out why hook-PyQt4.Qt*.py
> >> don't find the Qt4 plugins directory.
> >
> > It looks like QT_PLUGIN_PATH is set correctly, and they also appear
> > altogether, but those plugins bind with nearly all Qt libs in
> > existence, and this dependancy is not handled correctly, yet.
>
> This should be fixed wherever we fix the PyQt <-> Qt dependency, that is
> with DYLD_LIBRARY_PATH (hopefully).
Of course it won't, since you _still_ cannot fix a _missing_ library with
playing environmental games ;-) The PyQt <-> Qt dependency is resolved with
the attached patch.
You will notice, when this starts to work, because the size of your app
will grow considerably (as long as your app doesn't use QtNetwork, QtSql,
QtXml, QtSvg, or Qt3Support, yet). They all get pulled with the full
qt4_plugins support (see my list), but as you said before, they're handled
as data files ATM, which is the root of the problem.
Pete
Thanks. I have committed this patch since it seems correct, given the
manpage.
I have also fixed the {DY}LD_LIBRARY_PATH issue in one-dir mode. Now
one-dir mode builds correctly set the environment variable and fork+exec
to make sure it is honored (exactly what one-file builds do).
This should fix all your problems. Does it?
> > >> We'll have to find out why hook-PyQt4.Qt*.py
> > >> don't find the Qt4 plugins directory.
> > >
> > > It looks like QT_PLUGIN_PATH is set correctly, and they also appear
> > > altogether, but those plugins bind with nearly all Qt libs in
> > > existence, and this dependancy is not handled correctly, yet.
> >
> > This should be fixed wherever we fix the PyQt <-> Qt dependency, that is
> > with DYLD_LIBRARY_PATH (hopefully).
>
> Of course it won't, since you _still_ cannot fix a _missing_ library with
> playing environmental games ;-) The PyQt <-> Qt dependency is resolved with
> the attached patch.
> You will notice, when this starts to work, because the size of your app
> will grow considerably (as long as your app doesn't use QtNetwork, QtSql,
> QtXml, QtSvg, or Qt3Support, yet). They all get pulled with the full
> qt4_plugins support (see my list), but as you said before, they're handled
> as data files ATM, which is the root of the problem.
Ah, so you're basically saying that the plugins *themselves* bring in
additional dependencies, so, if we don't make them go through
bindepend.py, we might miss some library. Interesting, I had not thought
of that :)
BTW, I would like the plugin support to be exposed somehow to the suer.
For instance, I would like PyInstaller users to be able to specify in
their spec files which plugins they do really need. I'm not sure how it
could work though. I'll think of something.