Am Freitag, 3. Juli 2009 schrieb Giovanni Bajo:
> On 7/3/2009 3:42 PM, Hans-Peter Jansen wrote:
> > Hi Giovanni,
> >
> > $ 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/Ap
> >plicationServices', '/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?
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
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"PyInstaller" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/PyInstaller?hl=en
-~----------~----~----~----~------~----~------~--~---
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: