Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symbol lookup for plugin fails on iOS with static linkage #902

Open
mityax opened this issue Jan 24, 2022 · 1 comment
Open

Symbol lookup for plugin fails on iOS with static linkage #902

mityax opened this issue Jan 24, 2022 · 1 comment

Comments

@mityax
Copy link

mityax commented Jan 24, 2022

In order to use a Google MLKit plugin in my Flutter App on iOS, I had to set :linkage => :static in my Podfile. After doing so, the webcrypto plugin (which worked fine before) fails to lookup native boringssl symbols at runtime (it uses DynamicLibrary.executable() here).

Stack trace (in case it helps):

flutter: Unsupported operation: package:webcrypto cannot be used from scripts or `flutter test` unless `flutter pub run webcrypto:setup` has been run for the current root project.
flutter: #0      lookup.<anonymous closure> (package:webcrypto/src/boringssl/lookup/lookup_symbol_flutter.dart:47:5)
flutter: dart-lang/ffi#1      lookup (package:webcrypto/src/boringssl/lookup/lookup_symbol_flutter.dart:53:2)
flutter: dart-lang/ffi#2      lookup (package:webcrypto/src/boringssl/lookup/lookup_symbol_flutter.dart)
flutter: dart-lang/ffi#3      _cachedLookup (package:webcrypto/src/boringssl/lookup/lookup.dart:26:21)
flutter: dart-lang/ffi#4      _cachedLookup (package:webcrypto/src/boringssl/lookup/lookup.dart)
flutter: dart-lang/ffi#5      ssl (package:webcrypto/src/boringssl/lookup/lookup.dart:29:44)
flutter: dart-lang/ffi#6      ssl (package:webcrypto/src/boringssl/lookup/lookup.dart)
flutter: dart-lang/ffi#7      _aesCbcEncryptOrDecrypt (package:webcrypto/src/impl_ffi/impl_ffi.aescbc.dart:41:52)

So the original exception seems to appear here.

I already tried setting the Strip-Style to "Non-Global Symbols" in Xcode, as suggested in the docs, but it doesn't make a difference.

Note: I also created an issue in the webcrypto plugin itself, but I'm not sure where it rather belongs and it currently blocks the release of our application, which is why I need to find a way to solve it fast. Hopefully here it's visible to more experts on this (I'm a noob with anything related to ffi on ios).

I'd really appreciate any help on this, as I'm completely stuck here. Please let me know if I need to provide more information.

@dcharkes
Copy link
Collaborator

I can reproduce your issue by changing flutter_app/ios/Podfile:

target 'Runner' do
  use_frameworks! :linkage => :static
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

For a FFI plugin to support static linking, I need to meddle with linker flags to avoid stripping symbols. For example in mylib_staticlib/ios/mylib_staticlib.podspec:

  s.pod_target_xcconfig = {
    'DEFINES_MODULE' => 'YES',
    'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
    "OTHER_LDFLAGS[sdk=iphoneos*]" => "-force_load $(PODS_TARGET_SRCROOT)/Frameworks/mylib_staticlib.xcframework/ios-arm64_armv7/libmylib_staticlib.a",
    "OTHER_LDFLAGS[sdk=iphonesimulator*]" => "-force_load $(PODS_TARGET_SRCROOT)/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a",
  }
  s.vendored_frameworks = 'Frameworks/mylib_staticlib.xcframework'

However, when building from source, we just depend on s.source_files in mylib_source/ios/mylib_source.podspec:

  s.source_files = 'Classes/**/*'
  s.dependency 'Flutter'
  s.platform = :ios, '10.0'

  s.pod_target_xcconfig = {
    'DEFINES_MODULE' => 'YES',
    'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386'
  }

And the lookup can be done in DynamicLibrary.open('$_libName.framework/$_libName') rather than DynamicLibrary.executable() which can fail when there's duplicate symbols in different frameworks.

This is the setup used in package:webcrypto but it still uses DynamicLibrary.executable(). If it would have been using DynamicLibrary.open('$_libName.framework/$_libName') that step would fail instead of trying to lookup the symbol.

If we were to add those linker flags, the linking would fail without :linkage => :static. So, I'm not sure which route to go here. We would need to investigate how to make cocoapods packages that work both with static and dynamic linking and when used with static linking we want to ensure the symbols are not stripped out.

(As a side note, we would in Dart code also need to fallback to DynamicLibrary.executable().)

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

No branches or pull requests

2 participants