Skip to content

Pillow 11.3.0 iOS wheel contains dynamically linked libjpeg reference #9079

Description

@freakboy3742

What did you do?

Added the iOS wheel for Pillow 11.3.0 to an iOS project, then attempt an import of:

from PIL import _imaging

What did you expect to happen?

Import should succeed.

What actually happened?

An import error is raised:

ImportError: dlopen(/Users/rkm/Library/Developer/CoreSimulator/Devices/FD7EA28A-6D72-4064-9D8A-53CC8308BB6F/data/Containers/Bundle/Application/80811937-657D-46A5-8C25-94E3163059D5/Testbed.app/Frameworks/PIL._imaging.framework/PIL._imaging, 0x0002): Library not loaded: /Users/runner/work/Pillow/Pillow/build/deps/iphonesimulator/lib/libjpeg.62.dylib
Referenced from: <8FEC979F-CB01-34F9-B8FC-C55000FF15A0> /Users/rkm/Library/Developer/CoreSimulator/Devices/FD7EA28A-6D72-4064-9D8A-53CC8308BB6F/data/Containers/Bundle/Application/80811937-657D-46A5-8C25-94E3163059D5/Testbed.app/Frameworks/PIL._imaging.framework/PIL._imaging
Reason: tried: '/Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/Users/runner/work/Pillow/Pillow/build/deps/iphonesimulator/lib/libjpeg.62.dylib' (no such file), '/Users/runner/work/Pillow/Pillow/build/deps/iphonesimulator/lib/libjpeg.62.dylib' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libjpeg.62.dylib' (no such file)

What are your OS, Python and Pillow versions?

  • OS: iOS 18.5
  • Python: 3.13.4 (BeeWare support package b9)
  • Pillow: 11.3.0

PIL.report can't be executed, because PIL._imaging fails to load.

Activity

  1. freakboy3742 commented on Jul 10, 2025

    @freakboy3742
    ContributorAuthor

    This appears to have slipped through testing for 2 compounding reasons:

    1. There's not currently an analog of the auditwheel step for iOS; there shouldn't be any dynamic libraries, so there shouldn't be a need to audit anything. Clearly there is a need for a "check there are no dynamic libraries" audit.
    2. In a CI or local build scenario, the file that is linked does exist - on the build filesystem. If you run otool -L PIL._imaging.cpython-313-iphonesimulator.so on the official wheel version of the binary, you get:
    % otool -L PIL/_imaging.cpython-313-iphonesimulator.so 
    PIL/_imaging.cpython-313-iphonesimulator.so:
            build/lib.ios-13.0-arm64-iphonesimulator-cpython-313/PIL/_imaging.cpython-313-iphonesimulator.so (compatibility version 0.0.0, current version 0.0.0)
            @rpath/Python.framework/Python (compatibility version 3.13.0, current version 3.13.0)
            /Users/runner/work/Pillow/Pillow/build/deps/iphonesimulator/lib/libjpeg.62.dylib (compatibility version 62.0.0, current version 62.4.0)
            /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.120.2)
    

    That betrays the location of the build machine's working directory. That path exists during the CI run - even though its "on a simulator", the simulator is just an executable in a weird filesystem location from the perspective of macOS, so the dlopen succeeds. The same will also be true for local builds. It's only when the wheel was built on a foreign machine (or you delete your local build folder) that the problem becomes apparent.

    The short term fix is to ensure that there are no .dylibs in the build/deps/ folder that could be inadvertently linked, either by preventing them from being built, or by purging them manually.

    The longer term fix/protection is to add an auditwheel analog to cibuildwheel's iOS backend. I've logged pypa/cibuildwheel#2493 to track this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions