Bump to 4.4.0: dart_bridge as a dynamic framework on Apple platforms#240
Merged
Conversation
Fixes built iOS apps crashing at startup with 'Failed to lookup symbol serious_python_run: dlsym(RTLD_DEFAULT, serious_python_run): symbol not found'. dart_bridge's FFI entry points (serious_python_run, DartBridge_*, PyInit_dart_bridge) are resolved at runtime via dlsym -- from Dart through DynamicLibrary.process() and from Python through 'import dart_bridge'. It previously shipped as a static archive linked into the host app executable, and an iOS executable exports nothing to the dynamic symbol table by default (release builds also strip local symbols), so those lookups failed. Only release/archive device builds were affected: debug/simulator don't dead-strip. Android was never affected -- its dart_bridge is a dynamic .so. dart_bridge 1.6.0 now builds dart_bridge.xcframework as a dynamic framework (flet-dev/dart-bridge#11), so it is embedded + signed into the app like Python.xcframework and its symbols stay exported. Removes what a loaded image no longer needs: the SwiftPM -all_load/-force_load retention, the CocoaPods -all_load, and the plugin's dead-strip keep-alive references. Re-pins the bundled python-build snapshot to 20260725 (dart_bridge 1.5.1 -> 1.6.0, Pyodide 3.14 314.0.2 -> 314.0.3). Python versions (3.12.13 / 3.13.14 / 3.14.6) are unchanged and all platform runtimes are byte-identical to 20260720. Also bumps .fvmrc to Flutter 3.44.8.
python-build's 20260725 manifest was updated in place to dart_bridge 1.6.1,
so regenerate the version tables against it.
1.6.1 zips the Apple xcframework with -y so the macOS slice's versioned
framework symlinks (Versions/Current -> A, dart_bridge and Resources ->
Versions/Current/...) survive publishing. Under 1.6.0 they were followed and
stored as real files/directories, producing a malformed bundle that macOS
codesign rejected ('Couldn't resolve framework symlink for
.../Versions/Current', 'code object is not signed at all'). iOS was
unaffected -- its slices use a flat layout with no symlinks. See
flet-dev/dart-bridge#12.
Binaries are unchanged from 1.6.0; only the artifact packaging differs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps all six packages to 4.4.0 and re-pins the bundled python-build snapshot to 20260725.
Depends on flet-dev/dart-bridge#11 (dart_bridge 1.6.0) being released first —
prepare_ios.sh/prepare_macos.shdownloaddart_bridge-apple.xcframework.zipfrom thev1.6.0tag.The fix:
dart_bridgeships as a dynamic framework on Apple platformsBuilt iOS apps crashed at startup with:
dart_bridge's FFI entry points (serious_python_run,DartBridge_InitDartApiDL,DartBridge_EnqueueMessage,PyInit_dart_bridge) are resolved at runtime viadlsym— from Dart throughDynamicLibrary.process(), and from Python throughimport dart_bridge.It previously shipped as a static archive linked into the host app executable. An iOS executable exports nothing to the dynamic symbol table by default, and the release build strips local symbols — so
dlsym(RTLD_DEFAULT, ...)could not find them. Only release/archive (device) builds were affected; debug/simulator builds don't dead-strip, so it didn't reproduce there. Android was never affected — itsdart_bridgeis a dynamic.so, which exports its symbols.dart_bridge 1.6.0 builds
dart_bridge.xcframeworkas a dynamic framework, so it's embedded + signed into the app (likePython.xcframework) and its symbols stay exported.Removed, now that it's a loaded image rather than archive members
Package.swift: the SwiftPM-all_load(iOS) /-force_load(macOS) retention, and the filesystem probing that resolved the macOS slice path.serious_python_darwin.podspec:-all_loadfromOTHER_LDFLAGS(kept-ObjC -lc++); refreshed the stale "vendored xcframeworks contain static archives" comment.SeriousPythonPlugin.swift: the dead-strip keep-alive@_silgen_nameblock and its unreachable call site.python-build snapshot 20260720 → 20260725
Regenerated with
dart run serious_python:gen_version_tables --release-date 20260725; verified idempotent (the no-arg re-run produces no further diff, matching the CI drift check).dart_bridge1.5.1 → 1.6.0Also
.fvmrc→ Flutter 3.44.8.Verified
Built a Flet iOS release app against these changes: it boots on a real device and
serious_python_runresolves (previously crashed at startup). The embeddeddart_bridge.frameworkis signed, hasinstall_name @rpath/dart_bridge.framework/dart_bridge, and its export trie contains all four FFI entry points.Not tagged/published — per the repo's release process, that's a separate explicit step.