google / webcrypto.dart

Cross-platform implementation of Web Cryptography APIs
https://pub.dev/packages/webcrypto
Apache License 2.0
81 stars 48 forks source link

boringssl lookup fails on iOS with static linkage #24

Open mityax opened 2 years ago

mityax commented 2 years ago

To use another plugin (google MLKit), I had to set :linkage => :static in the Podifle of my app. However, since I did this, I get the same error webcrypto throws if it's run in a script without having set it up for testing:

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)

I tried setting the Strip-Style to "Non-Global Symbols" in Xcode, as suggested in the docs, but it doesn't make a difference. Is there any chance to fix this?

Any help is appreciated! :)

dcharkes commented 2 years ago

There's no general solution (yet) for supporting both dynamic and static linking in FFI plugins. See investigation:

mityax commented 2 years ago

@dcharkes thanks for your reply and the analysis.

Could you help me and send the specific podspec changes I'd need to make in this plugin to make it work with static linkage for now?

I'd fork it, change the podspec and use the fork. I have some idea(s) for a more generic workaround, I could play around with that afterwards and if it works maybe suggest it/submit a PR for this plugin, in case that's of interest.

dcharkes commented 2 years ago

To make static linking working I need to build a xcframework file outside of the Flutter build, and then bundle that framework. I use CMake + lipo -create + xcodebuild -create-xcframework to make a framework files. (I would have to investigate how to do the same with cocoapods from source files.)

I can see if I can upload a script that creates the xcframeworks if you're interested. (It uses a bunch of other stuff, so it's not standlone.)

Other than that, just the podspec and putting the xcframework in the right place: image

#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint mylib_staticlib.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
  s.name             = 'mylib_staticlib'
  s.version          = '0.0.1'
  s.summary          = 'A new flutter plugin project.'
  s.description      = <<-DESC
A new flutter plugin project.
                       DESC
  s.homepage         = 'http://example.com'
  s.license          = { :file => '../LICENSE' }
  s.author           = { 'Your Company' => 'email@example.com' }
  s.source           = { :path => '.' }
  s.source_files = 'Classes/**/*'
  s.dependency 'Flutter'
  s.platform = :ios, '8.0'

  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'
  s.swift_version = '5.0'
end
mityax commented 2 years ago

I see, yes if you could provide such a script that would be really helpful.

I didn't completely get the complexity before - I thought only the podspec needed to be adapted, not that additional manual build steps were required - thanks for pointing that out.

dcharkes commented 2 years ago

Well, maybe it can be done from within CocoaPods, but I'm not familiar enough with it.

I'll try to find some time to make it a standalone script.

mityax commented 2 years ago

Hey @dcharkes have you already found some time?

For me any script to make this work again would be good for now, it doesn't need to be standalone if that takes too much time for you right now.

dcharkes commented 2 years ago

The repo has many files and is not yet in a state where I can open source it.

Here is the exact commands that the script runs:

Building for [ios_arm, ios_arm64, iossimulator_arm64, iossimulator_x64, macos_arm64, macos_x64].
Running `/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=armv7`.
Running `/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm64/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=arm64`.
Running `/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_arm64/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=arm64`.
Running `/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_x64/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=x86_64`.
Running `/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/macos_arm64/ -DCMAKE_OSX_ARCHITECTURES=arm64`.
Running `/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/macos_x64/ -DCMAKE_OSX_ARCHITECTURES=x86_64`.
Running `/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/macos_x64/ --target mylib_staticlib mybin`.
Running `/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/macos_arm64/ --target mylib_staticlib`.
Running `lipo -create /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/macos_arm64/libmylib_staticlib.a /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/macos_x64/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/macos/Frameworks/libmylib_staticlib.a`.
Running `/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm/ --target mylib_staticlib -- -sdk iphoneos`.
Running `/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm64/ --target mylib_staticlib -- -sdk iphoneos`.
Running `/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_arm64/ --target mylib_staticlib -- -sdk iphonesimulator`.
Running `/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_x64/ --target mylib_staticlib -- -sdk iphonesimulator`.
Running `lipo -create /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm/Debug-iphoneos/libmylib_staticlib.a /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm64/Debug-iphoneos/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphoneos/libmylib_staticlib.a`.
Running `lipo -create /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_arm64/Debug-iphonesimulator/libmylib_staticlib.a /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_x64/Debug-iphonesimulator/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphonesimulator/libmylib_staticlib.a`.
Running `xcodebuild -create-xcframework -library /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphoneos/libmylib_staticlib.a -library /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphonesimulator/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework`.

The CMake file is trivial:

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version")

project(mylib_staticlib_library VERSION 0.0.1 LANGUAGES C)

add_library(mylib_staticlib STATIC mylib_staticlib.c)

set_target_properties(mylib_staticlib PROPERTIES
    PUBLIC_HEADER mylib_staticlib.h
    OUTPUT_NAME "mylib_staticlib"
    XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "<...>"
)

I hope I can find some time to open source the whole thing as a sample soon.

Please let me know if you're successful building an xcframework this way.

mityax commented 2 years ago

@dcharkes seems like I'm rather not successful with this. There's just too much new things I have no clue about here :/ I even tried using a pre-built BoringSSL .framework from here and adapting the podspec as you illustrated above, but then I found out about the whole webcrypto_dart_dl thing in this project, which makes it much more complicated again...

I guess I need to migrate away from using this plugin (at least on iOS) if there's no way to make this work within the next days. It's just sad because I found it quite helpful and there seems to be no other plugin at the moment that exposes a streaming api for AES.

Thanks for your help nonetheless, I really appreciate it :pray: