-
Notifications
You must be signed in to change notification settings - Fork 27k
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
Embed Flutter and App frameworks for add-to-app on iOS #102538
Conversation
86d0d33
to
2b32a72
Compare
@@ -79,32 +80,6 @@ Future<void> main() async { | |||
); | |||
} | |||
|
|||
section('Build ephemeral host app when SDK is on external disk'); | |||
|
|||
// Pretend the SDK was on an external drive with stray "._" files in the xcframework |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.ios/Flutter/engine
no longer exists
@@ -190,7 +191,7 @@ def flutter_install_ios_engine_pod(ios_application_path = nil) | |||
} | |||
|
|||
# Keep pod path relative so it can be checked into Podfile.lock. | |||
pod 'Flutter', :path => 'Flutter' | |||
pod 'Flutter', :path => flutter_relative_path_from_podfile(podspec_directory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now called from the host app Podfile script, and the fake podspec is in the Flutter module, so don't assume they are sibling paths.
derivedDir = '$projectPath/.ios/Flutter'; | ||
} | ||
|
||
// Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is already in parseFlutterBuildMode
we don't need it twice.
|
||
pod 'Flutter', :path => relative.to_s, :inhibit_warnings => true | ||
# flutter_install_ios_engine_pod is in Flutter root podhelper.rb | ||
flutter_install_ios_engine_pod(ios_application_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of duplicating logic, call the ruby script in the tool
def flutter_install_ios_engine_pod(ios_application_path = nil) |
@@ -79,33 +61,13 @@ end | |||
# MyApp/my_flutter/.ios/Flutter/../.. | |||
def install_flutter_plugin_pods(flutter_application_path) | |||
flutter_application_path ||= File.join('..', '..') | |||
ios_application_path = File.join(flutter_application_path, '.ios') | |||
# flutter_install_plugin_pods is in Flutter root podhelper.rb | |||
flutter_install_plugin_pods(ios_application_path, '.symlinks', 'ios') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicated logic, call
def flutter_install_plugin_pods(application_path = nil, relative_symlink_dir, platform) |
# Create a dummy dylib. | ||
FileUtils.mkdir_p(app_framework_dir) | ||
sdk_path = `xcrun --sdk iphoneos --show-sdk-path`.strip | ||
`echo "static const int Moo = 88;" | xcrun clang -x c -arch arm64 -dynamiclib -miphoneos-version-min=11.0 -isysroot "#{sdk_path}" -o "#{app_framework_dylib}" -` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stop making the dummy App.framework in the ephemeral module directory.
🐮
current_directory = File.expand_path('..', __FILE__) | ||
engine_dir = File.expand_path('engine', current_directory) | ||
framework_name = 'Flutter.xcframework' | ||
copied_engine = File.expand_path(framework_name, engine_dir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stop copying the engine into the module ephemeral directory. Let the tool handle copying the right version where it needs to go when assemble
is called.
|
||
# Embed App.framework AND Flutter.framework. | ||
script_phase :name => 'Embed Flutter Build {{projectName}} Script', | ||
:script => "set -e\nset -u\nsource \"#{flutter_export_environment_path}\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh embed_and_thin", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of letting CocoaPods copy/re-codesign/strip the frameworks from the ephemeral directory, instead let the tool copy it via embed_and_thin
after the rest of the app has compiled. The tool already codesigned/stripped it during assemble
.
Note this is the only real added logic to this PR, everything else is deletions or slight refactoring.
2b32a72
to
c46c66e
Compare
c46c66e
to
5de2d33
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
friendly ping @christopherfujino |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, thought I approved this, LGTM
Previously, the iOS Flutter module copied the Flutter.xcframework and created a dummy version of App.framework in the the ephemeral
.ios
directory, as well as two correspondingpodspec
s that pointed at these frameworks. On every compilation of the host app,flutter assemble
would create the real App.framework and copy the right Flutter.framework variant into the XcodeBUILT_PRODUCTS_DIR
. On the first build, CocoaPods would then copy/re-codesign/re-strip the frameworks and embed them into the app.However, since
flutter assemble
updates the frameworks inBUILT_PRODUCTS_DIR
and not the dummy frameworks in the ephemeral directory, on incremental builds CocoaPods would not run its copy script because the timestamp of the dummy ephemeral frameworks did not change. So the compiled dart code embedded in the app would not be updated, and would be stale until a hot reload.podhelper
scripts that embed the frameworks into the app.assemble
already codesigns, bitcode strips, and debug symbol strips the frameworks, so all that's left it torsync
them to the right place in the app.podhelper.rb
ruby script to use the Flutter SDKflutter_tools/bin/podhelper.rb
version of this file to push as much logic as possible into the SDK instead of the module project.Fixes #101979
Probably would have resolved parts of #94481
Follow-up to #101943
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.