You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b38989f
Browse filesBrowse the repository at this point in the historyBrowse files
recipe: cffi 2.1.1 with working ffi.callback() on iOS (#129)
## What
`cffi` 2.1.1 with `ffi.callback()` working on iOS, plus two CI fixes: testing rebuilt `flet-lib*` wheels, and pinned Ubuntu runners.
## Why
On iOS every `ffi.callback()` raised `MemoryError: Cannot allocate write+execute memory for ffi.callback()`, and variadic ABI-mode calls returned garbage on arm64. cffi uses libffi's closure API on Apple only when `FFI_AVAILABLE_APPLE` is defined, which only Apple's own macOS `ffi.h` does. With the upstream libffi our iOS builds use, cffi falls back to its own allocator, which maps writable+executable memory, and iOS refuses. libffi itself needs no such memory there (arm64 uses trampoline tables, which is why CPython's ctypes callbacks work).
Upstream fixed this in python-cffi/cffi#265, merged but not in any release yet.
## Changes
- **`recipes/cffi`**: 2.1.1, build 1, new `ios-ffi-closure-alloc.patch` enabling `ffi_closure_alloc` / `ffi_prep_closure_loc` / `ffi_prep_cif_var` under `TARGET_OS_IPHONE` (Android's preprocessed source is byte-identical). `mobile.patch` regenerated for 2.1.1, no behaviour change.
- 2.1.1 rather than rebuilding 2.0.0: PyPI ships official cffi 2.1.1 iOS wheels (cp313-cp315) without the fix, and they outrank 2.0.0. At the same version, our build tag wins.
- The patch is a `TARGET_OS_IPHONE` variant rather than #265 verbatim: forge's non-interactive `patch` reverse-applies a hunk it sees as already present, so a future bump to a release containing #265 would silently remove the fix. This variant lands as dead code instead. Drop it once a release includes #265.
- Tests: a C-invoked callback (`qsort`), a callback from a native thread, 3000 closures allocated and freed, and a variadic `snprintf`. Four of five fail on the old wheels.
- **`recipes/soundfile`**: file-object reads (`sf.read(io.BytesIO(...))`) now work on iOS. Removed the test asserting the iOS `MemoryError`, dropped the iOS skip, updated README, example README and a comment.
- **CI**: `dist-test/` now bumps `py3-none` (build.sh `flet-lib*`) wheels to build 9999 too, and Android's loop also matches `abi3`. Before, a rebuilt `flet-lib*` at an already-published version and build number could lose to its published copy in the device test.
- **CI**: Ubuntu runners pinned to `ubuntu-24.04` (what `ubuntu-latest` resolves to today). `ubuntu-latest` will move to 26.04, which would change the Android lane (NDK builds, KVM emulator) for every recipe at once; macOS is already pinned to `macos-26`.
## Validation
- On-device CI, Android + iOS, Python 3.12/3.13/3.14 (`packages=cffi:,soundfile:`, `prebuild_recipes=cffi`): all green on the fork. Note soundfile's iOS tests need the new cffi, so they only pass when cffi is built in the same run or published.
- iOS simulator, before/after: callbacks raise `MemoryError` and `snprintf` returns garbage on forge 2.0.0-1 and PyPI 2.1.1; all pass with this build.
- Not run: physical iOS devices, x86_64 simulator.
## Consumer notes
Apps get working `ffi.callback()` on iOS automatically once cffi 2.1.1-1 is on pypi.flet.dev; for soundfile that means in-memory reads work on both platforms. Details: [`recipes/soundfile/README.md`](recipes/soundfile/README.md).
0 commit comments