dart-lang / dart-lang/native

Missing symbols in static Flutter plugin builds

Open
#1,475 2 comments 1 reaction 1 assignee Claimed by @liamappelbe View on GitHub
package:objective_c
Dominant language
Dart
Stars
275
Forks
144
Avg merge
2d 10h
Merged PRs (30d)
47

Description

When adding some new usage of `.listener` for blocks, I started hitting this error at runtime:

>Unhandled Exception: Invalid argument(s): Couldn't resolve native function 'disposeObjCBlockWithClosure' in 'objective_c.framework/objective_c' : No asset with id 'objective_c.framework/objective_c' found. No available native assets. Attempted to fallback to process lookup. dlsym(RTLD_DEFAULT, disposeObjCBlockWithClosure): symbol not found.

It looks like there's nothing guaranteeing that this symbol is preserved, so in certain build configurations it's being dead-code stripped. For some important context here, CocoaPod-based plugins can be built in two configurations: as frameworks that are bundled into the app bundle, or as static libraries that are linked directly into the Runner. This depends on both plugin-level settings and app-level settings. `flutter create` using a Swift app template defaults to [forcing framework builds](https://github.com/flutter/flutter/blob/a782869b342953ef15769999cbdc5f3caf5de0d8/packages/flutter_tools/templates/cocoapods/Podfile-ios-swift#L31) (for somewhat complicated and mostly legacy reasons), while an Obj-C app template [does not](https://github.com/flutter/flutter/blob/a782869b342953ef15769999cbdc5f3caf5de0d8/packages/flutter_tools/templates/cocoapods/Podfile-ios-objc#L30). In the new SPM-based system Flutter is moving to, there is a similar divergence in build types depending on whether it's a release build.

I'm currently working on a plugin old enough that its example app is Obj-C, so it uses static library builds. In that app, `disposeObjCBlockWithClosure` is not present anywhere in my final build; the plugin is being built statically and linked in, but the symbol isn't in the resulting binary, so presumably it's been stripped. I was able to fix my app by adding `use_frameworks!`, but plugins need to support both modes.

I assume this will be migrating to native assets at some point; I'm not sure how far out that is, and if we need another workaround in the short term.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.