Skip to content

Bump to 4.4.0: dart_bridge as a dynamic framework on Apple platforms#240

Merged
FeodorFitsner merged 2 commits into
mainfrom
bump-4.4.0
Jul 25, 2026
Merged

Bump to 4.4.0: dart_bridge as a dynamic framework on Apple platforms#240
FeodorFitsner merged 2 commits into
mainfrom
bump-4.4.0

Conversation

@FeodorFitsner

Copy link
Copy Markdown
Contributor

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.sh download dart_bridge-apple.xcframework.zip from the v1.6.0 tag.

The fix: dart_bridge ships as a dynamic framework on Apple platforms

Built iOS apps crashed 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_InitDartApiDL, DartBridge_EnqueueMessage, 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. 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 — its dart_bridge is a dynamic .so, which exports its symbols.

dart_bridge 1.6.0 builds dart_bridge.xcframework as a dynamic framework, so it's embedded + signed into the app (like Python.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_load from OTHER_LDFLAGS (kept -ObjC -lc++); refreshed the stale "vendored xcframeworks contain static archives" comment.
  • SeriousPythonPlugin.swift: the dead-strip keep-alive @_silgen_name block 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_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) unchanged — all platform CPython runtimes are byte-identical to 20260720.

Also

  • .fvmrc → Flutter 3.44.8.

Verified

Built a Flet iOS release app against these changes: it boots on a real device and serious_python_run resolves (previously crashed at startup). The embedded dart_bridge.framework is signed, has install_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.

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.
@FeodorFitsner
FeodorFitsner merged commit d0c8f9d into main Jul 25, 2026
27 of 58 checks passed
@FeodorFitsner
FeodorFitsner deleted the bump-4.4.0 branch July 25, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant