1. Ronald Oussoren
  2. py2app
  3. Issues


Issue #133 resolved

Packaged dylib can't be found by ctypes.find_library()

Johannes Dewender
created an issue

Dynamic libraries (*.dylib) files are added to the app bundle with in the Frameworks folder.

When these are linked from other binary code this works fine, but when using ctypes.find_library() it doesn't work, since the library can't be found.

According to the ctypes code (python 2.7) the following environment variables are checked (for non-frameworks) DYLD_LIBRARY_PATH, DYLD_FALLBACK_LIBRARY_PATH

So the solution would probably be to append the app bundle's Framework path to one of these.

Of course, the workaround is to patch the python code using ctypes to also look in ../Frameworks. It would be much better if that wouldn't be necessary though.

The issue came up here: https://github.com/JonnyJD/python-discid/pull/42 (and has a workaround implemented)

Comments (9)

  1. Ronald Oussoren repo owner

    I'd rather not set those environment variables because those could the dynamic linker as well.

    That said, it shouldn't be too hard to write a recipe that detects that ctypes is used and then patches ctypes.macholib.dyld_find: that contains a couple of lists with paths used for finding libraries and frameworks, adding the application bundle framework directory to those lists would also fix the issue.

    I think it would be best to add ../Frameworks to the front of the search path, do you agree?

  2. Johannes Dewender reporter

    I'd rather not set those environment variables because those could [change?] the dynamic linker as well.

    Not sure if I follow. We are talking about changing environment variables only for the app bundle, right? And for that bundle you want to use the dylibs in the Framework folder anyways? So adding that path to the environment variable(s) would be fine, I'd say.

    then patches ctypes.macholib.dyld_find [...] best to add ../Frameworks to the front of the search path

    Since that patch only changes ctypes for the bundle that would be fine.

    I'd guess maintaining that patch is more difficult since ctypes' code might change. Monkey-patching might not work in this case, but maybe it would. That is up to you of course.

    The file to patch would be ctypes/macholib/dyld.py I'd say. Note that normal dylib files might not be considered frameworks so the Framework path is not used. Changing DEFAULT_LIBRARY_FALLBACK might not always work since it is not used when DYLD_FALLBACK_LIBRARY_PATH (environment) is set. So changing dyld_override_search() or dyld_default_search() seems reasonable.

    Although I still don't understand why just changing the environment variables just for the bundle (possibly in a wrapper, that is how I do things on Linux) wouldn't work. Possibly it is difficult in these circumstances, though. I don't know much about app bundles.

  3. Johannes Dewender reporter

    Well, to be precise: For a name %s ctypes also tries to find %s.framework/%s.dylib in the framework path, but that won't find anything if we save the dylib directly in the framework path (of the bundle) (without extra %s.framework folder). So basically we have to add our Framework path to the library search path (with patching ctypes or changing environment variables) or change the way we save dyld files (and change the framework search patch).

  4. Log in to comment