From b29a6bc56b2da46cd4ce7b04e49f1511e44e2c8b Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Thu, 14 Jan 2021 10:15:24 -0800 Subject: [PATCH] Use SDK podhelper in add-to-app module Podfile (#73072) --- dev/devicelab/bin/tasks/module_test_ios.dart | 17 ++++++-- .../lib/src/commands/build_ios_framework.dart | 6 --- packages/flutter_tools/lib/src/project.dart | 5 ++- .../Podfile.copy.tmpl | 39 ++++++++++++++++--- .../library/Flutter.tmpl/podhelper.rb.tmpl | 16 +++++--- 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/dev/devicelab/bin/tasks/module_test_ios.dart b/dev/devicelab/bin/tasks/module_test_ios.dart index 10ec562e46..1c3ae03894 100644 --- a/dev/devicelab/bin/tasks/module_test_ios.dart +++ b/dev/devicelab/bin/tasks/module_test_ios.dart @@ -175,10 +175,10 @@ Future main() async { final File podfileLockFile = File(path.join(projectDir.path, '.ios', 'Podfile.lock')); final String podfileLockOutput = podfileLockFile.readAsStringSync(); - if (!podfileLockOutput.contains(':path: Flutter/engine') + if (!podfileLockOutput.contains(':path: Flutter') || !podfileLockOutput.contains(':path: Flutter/FlutterPluginRegistrant') - || !podfileLockOutput.contains(':path: Flutter/.symlinks/device_info/ios') - || !podfileLockOutput.contains(':path: Flutter/.symlinks/google_sign_in/ios') + || !podfileLockOutput.contains(':path: ".symlinks/plugins/device_info/ios"') + || !podfileLockOutput.contains(':path: ".symlinks/plugins/google_sign_in/ios"') || podfileLockOutput.contains('android_alarm_manager')) { return TaskResult.failure('Building ephemeral host app Podfile.lock does not contain expected pods'); } @@ -220,6 +220,17 @@ Future main() async { 'LANG': 'en_US.UTF-8', }, ); + + final File hostPodfileLockFile = File(path.join(objectiveCHostApp.path, 'Podfile.lock')); + final String hostPodfileLockOutput = hostPodfileLockFile.readAsStringSync(); + if (!hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter/engine"') + || !hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter/FlutterPluginRegistrant"') + || !hostPodfileLockOutput.contains(':path: "../hello/.ios/.symlinks/plugins/device_info/ios"') + || !hostPodfileLockOutput.contains(':path: "../hello/.ios/.symlinks/plugins/google_sign_in/ios"') + || hostPodfileLockOutput.contains('android_alarm_manager')) { + throw TaskResult.failure('Building host app Podfile.lock does not contain expected pods'); + } + await exec( 'xcodebuild', [ diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart index f67fa529bb..55cf7c5cef 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart @@ -422,12 +422,6 @@ end ' ├─Building plugins...' ); try { - // Regardless of the last "flutter build" build mode, - // copy the corresponding engine. - // A plugin framework built with bitcode must link against the bitcode version - // of Flutter.framework (Release). - _project.ios.copyEngineArtifactToProject(mode, EnvironmentType.physical); - final String bitcodeGenerationMode = mode == BuildMode.release ? 'bitcode' : 'marker'; // In release, force bitcode embedding without archiving. diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 2621b0bebe..69192b919b 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -662,11 +662,12 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { ephemeralDirectory, ); } - copyEngineArtifactToProject(BuildMode.debug, EnvironmentType.physical); + // Use release mode so host project can link on bitcode variant. + _copyEngineArtifactToProject(BuildMode.release, EnvironmentType.physical); } } - void copyEngineArtifactToProject(BuildMode mode, EnvironmentType environmentType) { + void _copyEngineArtifactToProject(BuildMode mode, EnvironmentType environmentType) { // Copy framework from engine cache. The actual build mode // doesn't actually matter as it will be overwritten by xcode_backend.sh. // However, cocoapods will run before that script and requires something diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl index 5bc82b72fc..e52930d6bc 100644 --- a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl @@ -1,11 +1,40 @@ platform :ios, '9.0' -flutter_application_path = '../' -load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' -use_frameworks! +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup target 'Runner' do - install_flutter_engine_pod - install_flutter_plugin_pods flutter_application_path + use_frameworks! + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + + pod 'FlutterPluginRegistrant', :path => File.join('Flutter', 'FlutterPluginRegistrant'), :inhibit_warnings => true +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end end diff --git a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl index 03ee057a96..2ad576df5c 100644 --- a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl +++ b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl @@ -35,8 +35,12 @@ def install_flutter_engine_pod if !File.exist?(copied_engine) # Copy the debug engine to have something to link against if the xcode backend script has not run yet. # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. - debug_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios') - FileUtils.cp_r(File.join(debug_framework_dir, framework_name), engine_dir) + release_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios-release') + unless Dir.exist?(release_framework_dir) + # iOS artifacts have not been downloaded. + raise "#{release_framework_dir} must exist. Make sure \"flutter build ios\" has been run at least once" + end + FileUtils.cp_r(File.join(release_framework_dir, framework_name), engine_dir) end # Keep pod path relative so it can be checked into Podfile.lock. @@ -63,13 +67,13 @@ def install_flutter_plugin_pods(flutter_application_path) # Keep pod path relative so it can be checked into Podfile.lock. # Process will be run from project directory. - current_directory_pathname = Pathname.new File.expand_path('..', __FILE__) + ios_project_directory_pathname = Pathname.new File.expand_path(File.join('..', '..'), __FILE__) # defined_in_file is set by CocoaPods and is a Pathname to the Podfile. project_directory_pathname = defined_in_file.dirname - relative = current_directory_pathname.relative_path_from project_directory_pathname - pod 'FlutterPluginRegistrant', :path => File.join(relative, 'FlutterPluginRegistrant'), :inhibit_warnings => true + relative = ios_project_directory_pathname.relative_path_from project_directory_pathname + pod 'FlutterPluginRegistrant', :path => File.join(relative, 'Flutter', 'FlutterPluginRegistrant'), :inhibit_warnings => true - symlinks_dir = File.join(relative, '.symlinks') + symlinks_dir = File.join(relative, '.symlinks', 'plugins') FileUtils.mkdir_p(symlinks_dir) plugins_file = File.expand_path('.flutter-plugins-dependencies', flutter_application_path)