Search code examples
pythonlinkermacos-catalinapy2appdyld

ImportError: Library not loaded, dyld linking confusion


So I'm trying to use Py2app to export a python script that uses tkinter and writes to excel, and I'm getting this error;

ImportError: dlopen(/Users/James/Documents/Python/Projects/Budget/dist/automating_finances0.app/Contents/Resources/lib/python3.8/lib-dynload/PIL/_imaging.so, 2): 
Library not loaded: @loader_path/.dylibs/libopenjp2.2.3.1.dylib
  Referenced from: /Users/James/Documents/Python/Projects/Budget/dist/automating_finances0.app/Contents/Resources/lib/python3.8/lib-dynload/PIL/_imaging.so
  Reason: image not found

When I do otool -L on contents/macOS/automating_finances0 I get this;

/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 21.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 283.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1151.16.0)

I've researched @loader_path, @rpath and dyld linking but can't seem to figure it out. I'm not sure why my app is looking for dependencies in the folders above and not myapp/contents/frameworks etc which is where libopenjp2.2.3.1.dylib is located? I've tried changing the search paths by doing;

install_name_tool -change /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa Users/James/Documents/Python/Projects/Budget/dist/automating_finances0.app/Contents/frameworks Users/James/Documents/Python/Projects/Budget/dist/automating_finances0.app/Contents/macOS/automating_finances0

but this absolutely does not work, I'm not really sure what Cocoa is? Newbie so any help much appreciated.


Solution

  • Turns out I was looking in the wrong place, the error was with _imaging.so. I hadn't taken this on board because I didn't recognise the .so file as a dynamic library. Using otool -L _imaging.so showed the dependancies that were missing and bingo, they included libopenjp2.2.3.1.dylib amongst others. I ended up just copying the contents of myapp/contents/frameworks to usr/local/lib which seems to work fine, although this doesn't seem like a robust solution.