OSX Lion including dylibs

299 views
Skip to first unread message

scottbvfx

unread,
May 7, 2012, 2:53:52 PM5/7/12
to PyInstaller
I'm trying to build a Pyinstaller app (current dev release) on OSX
Lion (10.7) that includes ImageMagicks convert utility. I thought that
including all of convert's dependencies (dylibs) that it would work on
other machines that don't have Imagemagick installed.

When the app runs convert looks for the dylibs in their original
directories:

dyld: Library not loaded: /opt/local/lib/liblcms2.2.dylib
Referenced from: /Users/scottb08/Desktop/test_application/convert
Reason: image not found

Is there a way to get convert to look for the dylibs in the _MEIPASS2
directory for them?

I'm doing a --onedir build and adding: [('liblcms2.2.dylib', '/opt/
local/lib/liblcms2.2.dylib', 'BINARY')], to COLLECT.

Cheers,
-Scott

Martin Zibricky

unread,
May 8, 2012, 5:28:01 AM5/8/12
to pyins...@googlegroups.com
scottbvfx píše v Po 07. 05. 2012 v 11:53 -0700:
Have you heard about '@loader_path' or '@executable_path'?

To examine, where a binary is looking for dylibs use command

otool -L binary

You need to replace those paths with '@loader_path' - the same way as
pyinstaller does it.

You could use for that function 'mac_set_relative_dylib_deps()' from
file

./PyInstaller/depend/dylib.py


Scott Ballard

unread,
May 8, 2012, 12:02:45 PM5/8/12
to pyins...@googlegroups.com
Thank you for the quick response Martin!

I did notice those functions and have been using otool to find the dependencies.

Is there a hook or place in Pyinstaller that I can give it a binary (Imagemagick) I want to include and it will use 'mac_set_relative_dylib_deps()' to set the dependencies relative to the archive? Or do I have to implement it myself? Do I need to create a Pyinstaller hook like PyQt is being hooked?

I'm just not sure of the exact steps it will take to include Imagemagicks dependencies using mac_set_relative_dylib_deps().

Thank you again for your time!
-Scott

Martin Zibricky

unread,
May 8, 2012, 1:55:40 PM5/8/12
to pyins...@googlegroups.com
Scott Ballard píše v Út 08. 05. 2012 v 09:02 -0700:
> Is there a hook or place in Pyinstaller that I can give it a binary
> (Imagemagick) I want to include and it will use
> 'mac_set_relative_dylib_deps()' to set the dependencies relative to
> the archive? Or do I have to implement it myself? Do I need to create
> a Pyinstaller hook like PyQt is being hooked?

Hi Scott,

You need to create a hook like PyQt hooks. You need to add the 'convert'
utility in 'hook()' function to other binary dependencies, as it is done
with qt4 plugins. For example see hook-PyQt4.QtCore.py.

You need to add to your hook code like:

def hook(mod):
mod.binaries.extend([
(PATH_TO_CONVERT_ON_FILESYSTEM, NAME_OF_THE_FILE_IN_DIST_DIR)
])
return mod



Scott Ballard

unread,
May 8, 2012, 3:09:22 PM5/8/12
to pyins...@googlegroups.com
Isn't creating a hook produce the same results as adding it to the COLLECT (see below)? Do the dylib files that are collected need to be modified by 'mac_set_relative_dylib_deps()'? Sorry the intricacies of the process are eluding me.

Thank you again,
-Scott

coll = COLLECT(exe,
               a.binaries,
               [('ui/%s.ui' % APP_NAME, './ui/%s.ui' % APP_NAME, 'DATA')],
               [('convert', '../utilities/convert', 'DATA')],
               [('libMagickCore.5.dylib', '/opt/local/lib/libMagickCore.5.dylib', 'BINARY')],
               [('libMagickWand.5.dylib', '/opt/local/lib/libMagickWand.5.dylib', 'BINARY')],
               [('liblcms2.2.dylib', '/opt/local/lib/liblcms2.2.dylib', 'BINARY')],
               [('libtiff.3.dylib', '/opt/local/lib/libtiff.3.dylib', 'BINARY')],
               [('libSystem.B.dylib', '/usr/lib/libSystem.B.dylib', 'BINARY')],
               [('libjpeg.8.dylib', '/opt/local/lib/libjpeg.8.dylib', 'BINARY')],
               [('libfontconfig.1.dylib', '/opt/local/lib/libfontconfig.1.dylib', 'BINARY')],
               [('libiconv.2.dylib', '/opt/local/lib/libiconv.2.dylib', 'BINARY')],
               [('libfreetype.6.dylib', '/opt/local/lib/libfreetype.6.dylib', 'BINARY')],
               [('libexpat.1.dylib', '/opt/local/lib/libexpat.1.dylib', 'BINARY')],
               [('libXext.6.dylib', '/opt/local/lib/libXext.6.dylib', 'BINARY')],
               [('libXt.6.dylib', '/opt/local/lib/libXt.6.dylib', 'BINARY')],
               [('liblzma.5.dylib', '/opt/local/lib/liblzma.5.dylib', 'BINARY')],
               [('libbz2.1.0.dylib', '/opt/local/lib/libbz2.1.0.dylib', 'BINARY')],
               [('libz.1.dylib', '/opt/local/lib/libz.1.dylib', 'BINARY')],
               [('libltdl.7.dylib', '/opt/local/lib/libltdl.7.dylib', 'BINARY')],
               [('libSM.6.dylib', '/opt/local/lib/libSM.6.dylib', 'BINARY')],
               [('libICE.6.dylib', '/opt/local/lib/libICE.6.dylib', 'BINARY')],
               [('libX11.6.dylib', '/opt/local/lib/libX11.6.dylib', 'BINARY')],
               [('libxcb.1.dylib', '/opt/local/lib/libxcb.1.dylib', 'BINARY')],
               [('libXau.6.dylib', '/opt/local/lib/libXau.6.dylib', 'BINARY')],
               [('libXdmcp.6.dylib', '/opt/local/lib/libXdmcp.6.dylib', 'BINARY')],
               a.zipfiles,
               a.datas,
               strip=None,
               upx=False,
               name=os.path.join('dist/osx', APP_NAME))

Martin Zibricky

unread,
May 8, 2012, 3:37:02 PM5/8/12
to pyins...@googlegroups.com
Scott Ballard píše v Út 08. 05. 2012 v 12:09 -0700:
> Isn't creating a hook produce the same results as adding it to the
> COLLECT (see below)? Do the dylib files that are collected need to be
> modified by 'mac_set_relative_dylib_deps()'? Sorry the intricacies of
> the process are eluding me.

I'm not sure about the .spec syntax.

But in the hook the other dylibs necessary for 'convert' utility will be
collected automatically and 'mac_set_relative_dylib_deps()' will be
applied to all of them.

Martin Zibricky

unread,
May 8, 2012, 4:15:34 PM5/8/12
to pyins...@googlegroups.com
Scott Ballard píše v Út 08. 05. 2012 v 12:09 -0700:
> Isn't creating a hook produce the same results as adding it to the
> COLLECT (see below)?

If the COLLECT should work as the hook, then you should be just fine
with the following:

coll = COLLECT(exe,
a.binaries,
[('ui/%s.ui' % APP_NAME, './ui/%s.ui' % APP_NAME,
'DATA')],
[('convert', '../utilities/convert', 'BINARY')],

Scott Ballard

unread,
May 8, 2012, 9:09:07 PM5/8/12
to pyins...@googlegroups.com
Martin,

I created a hook-convert.py file in the Pyinstaller/hooks directory but it doesn't seem to be getting called. Imagemagick's convert utility ISNT a Python module so it never gets imported in my script but called from subprocess instead. How do I get the hook-convert.py file to get called? Is there a standard method are adding standalone utility apps and their dependencies in Pyinstaller that aren't Python packages?

My COLLECT looks like this:
coll = COLLECT(exe,
               a.binaries,
               [('ui/%s.ui' % APP_NAME, './ui/%s.ui' % APP_NAME, 'DATA')],
               [('convert', './convert', 'DATA')],

Thanks!
-Scott
Reply all
Reply to author
Forward
0 new messages