From 7e27b140f0e8ee42819bd2d69e7a13eaaa095979 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 15 Sep 2020 11:10:25 -0700 Subject: [PATCH] Avoid thinning frameworks in iOS extensions (#65198) --- .../tasks/ios_app_with_extensions_test.dart | 161 ++++++++++++------ .../ios/Flutter/Debug.xcconfig | 1 + .../ios/Flutter/Release.xcconfig | 1 + .../ios_app_with_extensions/ios/Podfile | 43 +++++ .../ios/Runner.xcodeproj/project.pbxproj | 139 ++++++++++++++- .../contents.xcworkspacedata | 3 + .../ios_app_with_extensions/pubspec.yaml | 7 +- packages/flutter_tools/bin/xcode_backend.sh | 7 +- 8 files changed, 306 insertions(+), 56 deletions(-) create mode 100644 dev/integration_tests/ios_app_with_extensions/ios/Podfile diff --git a/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart b/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart index 4349a18f3b1..a47d378843d 100644 --- a/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart +++ b/dev/devicelab/bin/tasks/ios_app_with_extensions_test.dart @@ -7,12 +7,14 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/framework/ios.dart'; import 'package:flutter_devicelab/framework/utils.dart'; import 'package:path/path.dart' as path; +import 'package:meta/meta.dart'; Future main() async { await task(() async { - section('Copy test Flutter App with WatchOS Companion'); + section('Copy test Flutter App with watchOS Companion'); String watchDeviceID; String phoneDeviceID; @@ -33,22 +35,54 @@ Future main() async { await inDirectory(projectDir, () async { await flutter( 'build', - options: ['ios', '--no-codesign'], + options: ['ios', '--no-codesign', '--release'], ); }); - final bool appReleaseBuilt = exists(Directory(path.join( + final String appBundle = Directory(path.join( projectDir.path, 'build', 'ios', 'iphoneos', 'Runner.app', - ))); + )).path; - if (!appReleaseBuilt) { - return TaskResult.failure( - 'Failed to build flutter iOS app with WatchOS companion in release mode.'); - } + final String appFrameworkPath = path.join( + appBundle, + 'Frameworks', + 'App.framework', + 'App', + ); + final String flutterFrameworkPath = path.join( + appBundle, + 'Frameworks', + 'Flutter.framework', + 'Flutter', + ); + + checkDirectoryExists(appBundle); + await _checkFlutterFrameworkArchs(appFrameworkPath, isSimulator: false); + await _checkFlutterFrameworkArchs(flutterFrameworkPath, isSimulator: false); + + // Check the watch extension framework added in the Podfile + // is in place with the expected watch archs. + final String watchExtensionFrameworkPath = path.join( + appBundle, + 'Watch', + 'watch.app', + 'PlugIns', + 'watch Extension.appex', + 'Frameworks', + 'EFQRCode.framework', + 'EFQRCode', + ); + _checkWatchExtensionFrameworkArchs(watchExtensionFrameworkPath); + + section('Clean build'); + + await inDirectory(projectDir, () async { + await flutter('clean'); + }); section('Create debug build'); @@ -59,20 +93,18 @@ Future main() async { ); }); - final bool appDebugBuilt = exists(Directory(path.join( - projectDir.path, - 'build', - 'ios', - 'iphoneos', - 'Runner.app', - ))); + checkDirectoryExists(appBundle); + await _checkFlutterFrameworkArchs(appFrameworkPath, isSimulator: false); + await _checkFlutterFrameworkArchs(flutterFrameworkPath, isSimulator: false); + _checkWatchExtensionFrameworkArchs(watchExtensionFrameworkPath); - if (!appDebugBuilt) { - return TaskResult.failure( - 'Failed to build flutter iOS app with WatchOS companion in debug mode.'); - } + section('Clean build'); - section('Create build for a simulator device'); + await inDirectory(projectDir, () async { + await flutter('clean'); + }); + + section('Run app on simulator device'); // Xcode 11.4 simctl create makes the runtime argument optional, and defaults to latest. // TODO(jmagman): Remove runtime parsing when devicelab upgrades to Xcode 11.4 https://github.com/flutter/flutter/issues/54889 @@ -160,34 +192,6 @@ Future main() async { workingDirectory: flutterDirectory.path, ); - await inDirectory(projectDir, () async { - await flutter( - 'build', - options: [ - 'ios', - '--debug', - '--no-codesign', - '-d', - phoneDeviceID - ], - ); - }); - - final bool appSimulatorBuilt = exists(Directory(path.join( - projectDir.path, - 'build', - 'ios', - 'iphoneos', - 'Runner.app', - ))); - - if (!appSimulatorBuilt) { - return TaskResult.failure( - 'Failed to build flutter iOS app with WatchOS companion in debug mode for simulated device.'); - } - - section('Run app on simulator device'); - // Boot simulator devices. await eval( 'xcrun', @@ -227,9 +231,36 @@ Future main() async { final int exitCode = await process.exitCode; - if (exitCode != 0) + if (exitCode != 0) { return TaskResult.failure( 'Failed to start flutter iOS app with WatchOS companion on simulated device.'); + } + + final String simulatorAppBundle = Directory(path.join( + projectDir.path, + 'build', + 'ios', + 'iphonesimulator', + 'Runner.app', + )).path; + + checkDirectoryExists(simulatorAppBundle); + + final String simulatorAppFrameworkPath = path.join( + simulatorAppBundle, + 'Frameworks', + 'App.framework', + 'App', + ); + final String simulatorFlutterFrameworkPath = path.join( + simulatorAppBundle, + 'Frameworks', + 'Flutter.framework', + 'Flutter', + ); + + await _checkFlutterFrameworkArchs(simulatorAppFrameworkPath, isSimulator: true); + await _checkFlutterFrameworkArchs(simulatorFlutterFrameworkPath, isSimulator: true); return TaskResult.success(null); } catch (e) { @@ -268,3 +299,35 @@ Future main() async { } }); } + +Future _checkFlutterFrameworkArchs(String frameworkPath, { + @required bool isSimulator +}) async { + checkFileExists(frameworkPath); + + final String archs = await fileType(frameworkPath); + if (isSimulator == archs.contains('armv7')) { + throw TaskResult.failure('$frameworkPath armv7 architecture unexpected'); + } + + if (isSimulator == archs.contains('arm64')) { + throw TaskResult.failure('$frameworkPath arm64 architecture unexpected'); + } + + if (isSimulator != archs.contains('x86_64')) { + throw TaskResult.failure( + '$frameworkPath x86_64 architecture unexpected'); + } +} + +Future _checkWatchExtensionFrameworkArchs(String frameworkPath) async { + checkFileExists(frameworkPath); + final String archs = await fileType(frameworkPath); + if (!archs.contains('armv7k')) { + throw TaskResult.failure('$frameworkPath armv7k architecture missing'); + } + + if (!archs.contains('arm64_32')) { + throw TaskResult.failure('$frameworkPath arm64_32 architecture missing'); + } +} diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Debug.xcconfig b/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Debug.xcconfig index 592ceee85b8..e8efba11468 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Debug.xcconfig +++ b/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Release.xcconfig b/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Release.xcconfig index 592ceee85b8..399e9340e6f 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Release.xcconfig +++ b/dev/integration_tests/ios_app_with_extensions/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Podfile b/dev/integration_tests/ios_app_with_extensions/ios/Podfile new file mode 100644 index 00000000000..7ced0feb038 --- /dev/null +++ b/dev/integration_tests/ios_app_with_extensions/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +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 + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +target 'watch Extension' do + platform :watchos + use_frameworks! + use_modular_headers! + + pod 'EFQRCode/watchOS', '5.1.6' +end diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj index 2e18f9e8023..8e7a9988226 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcodeproj/project.pbxproj @@ -3,12 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3E9BA895D09CB79E387C1344 /* Pods_watch_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1055F86985F96260A366C181 /* Pods_watch_Extension.framework */; }; 49C15B4E243E340B0025F804 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 49C15B4C243E340B0025F804 /* Interface.storyboard */; }; 49C15B50243E340E0025F804 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 49C15B4F243E340E0025F804 /* Assets.xcassets */; }; 49C15B57243E340E0025F804 /* watch Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 49C15B56243E340E0025F804 /* watch Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -22,6 +23,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + F070ECA5890D54F6F05C28D1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696CA539DDC2E5BAE7BE6E30 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -77,8 +79,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1055F86985F96260A366C181 /* Pods_watch_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_watch_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2030A05F5F3BE734A8070E46 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 203CB464AF16CE89225F7813 /* Pods-AbsPROJECT_NAMEWatch-watch Extension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AbsPROJECT_NAMEWatch-watch Extension.profile.xcconfig"; path = "Target Support Files/Pods-AbsPROJECT_NAMEWatch-watch Extension/Pods-AbsPROJECT_NAMEWatch-watch Extension.profile.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 49C15B4A243E340B0025F804 /* watch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = watch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49C15B4D243E340B0025F804 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; @@ -91,9 +96,14 @@ 49C15B61243E340F0025F804 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49C15B64243E340F0025F804 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 49C15B66243E340F0025F804 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 696CA539DDC2E5BAE7BE6E30 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 71E8E97FA3A197DCEB51D55C /* Pods-watch Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watch Extension.release.xcconfig"; path = "Target Support Files/Pods-watch Extension/Pods-watch Extension.release.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8AA421E0363D82BA724B0CDC /* Pods-watch Extension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watch Extension.profile.xcconfig"; path = "Target Support Files/Pods-watch Extension/Pods-watch Extension.profile.xcconfig"; sourceTree = ""; }; + 900233269AEC1A38F27EEDB8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 95DB968C9BF258092FCFD9BD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -101,6 +111,9 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D715AE6242E1A4DAD04A29F4 /* Pods-AbsPROJECT_NAMEWatch-watch Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AbsPROJECT_NAMEWatch-watch Extension.release.xcconfig"; path = "Target Support Files/Pods-AbsPROJECT_NAMEWatch-watch Extension/Pods-AbsPROJECT_NAMEWatch-watch Extension.release.xcconfig"; sourceTree = ""; }; + EF52C4C1360C951B0774F008 /* Pods-watch Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watch Extension.debug.xcconfig"; path = "Target Support Files/Pods-watch Extension/Pods-watch Extension.debug.xcconfig"; sourceTree = ""; }; + F27C4D74A989CBB3ADF7C643 /* Pods-AbsPROJECT_NAMEWatch-watch Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AbsPROJECT_NAMEWatch-watch Extension.debug.xcconfig"; path = "Target Support Files/Pods-AbsPROJECT_NAMEWatch-watch Extension/Pods-AbsPROJECT_NAMEWatch-watch Extension.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -108,10 +121,19 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3E9BA895D09CB79E387C1344 /* Pods_watch_Extension.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F070ECA5890D54F6F05C28D1 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D81AEDE8E6DF27AC0FCB71A2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -152,6 +174,22 @@ path = "Preview Content"; sourceTree = ""; }; + 5007DEA4342EE0E73C06EC67 /* Pods */ = { + isa = PBXGroup; + children = ( + F27C4D74A989CBB3ADF7C643 /* Pods-AbsPROJECT_NAMEWatch-watch Extension.debug.xcconfig */, + D715AE6242E1A4DAD04A29F4 /* Pods-AbsPROJECT_NAMEWatch-watch Extension.release.xcconfig */, + 203CB464AF16CE89225F7813 /* Pods-AbsPROJECT_NAMEWatch-watch Extension.profile.xcconfig */, + 2030A05F5F3BE734A8070E46 /* Pods-Runner.debug.xcconfig */, + 900233269AEC1A38F27EEDB8 /* Pods-Runner.release.xcconfig */, + 95DB968C9BF258092FCFD9BD /* Pods-Runner.profile.xcconfig */, + EF52C4C1360C951B0774F008 /* Pods-watch Extension.debug.xcconfig */, + 71E8E97FA3A197DCEB51D55C /* Pods-watch Extension.release.xcconfig */, + 8AA421E0363D82BA724B0CDC /* Pods-watch Extension.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -171,6 +209,8 @@ 49C15B4B243E340B0025F804 /* watch */, 49C15B5A243E340E0025F804 /* watch Extension */, 97C146EF1CF9000F007C117D /* Products */, + 5007DEA4342EE0E73C06EC67 /* Pods */, + E9CB96A835309D0ACFA18806 /* Frameworks */, ); sourceTree = ""; }; @@ -207,6 +247,15 @@ name = "Supporting Files"; sourceTree = ""; }; + E9CB96A835309D0ACFA18806 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 696CA539DDC2E5BAE7BE6E30 /* Pods_Runner.framework */, + 1055F86985F96260A366C181 /* Pods_watch_Extension.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -216,6 +265,7 @@ buildPhases = ( 49C15B48243E340B0025F804 /* Resources */, 49C15B6E243E340F0025F804 /* Embed App Extensions */, + D81AEDE8E6DF27AC0FCB71A2 /* Frameworks */, ); buildRules = ( ); @@ -231,9 +281,11 @@ isa = PBXNativeTarget; buildConfigurationList = 49C15B6A243E340F0025F804 /* Build configuration list for PBXNativeTarget "watch Extension" */; buildPhases = ( + DC0384878DB7754C7CDC3539 /* [CP] Check Pods Manifest.lock */, 49C15B52243E340E0025F804 /* Sources */, 49C15B53243E340E0025F804 /* Frameworks */, 49C15B54243E340E0025F804 /* Resources */, + 62A7C66F38F8BDDF8F85E990 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -248,6 +300,7 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + B065CE4C5BB3753A009EB098 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, @@ -255,6 +308,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 49C15B73243E340F0025F804 /* Embed Watch Content */, + DF3DAF4426EF33A40B49B448 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -353,7 +407,24 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; + 62A7C66F38F8BDDF8F85E990 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-watch Extension/Pods-watch Extension-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-watch Extension/Pods-watch Extension-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-watch Extension/Pods-watch Extension-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; @@ -369,6 +440,67 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + B065CE4C5BB3753A009EB098 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DC0384878DB7754C7CDC3539 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-watch Extension-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DF3DAF4426EF33A40B49B448 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -515,6 +647,7 @@ }; 49C15B6B243E340F0025F804 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = EF52C4C1360C951B0774F008 /* Pods-watch Extension.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -549,6 +682,7 @@ }; 49C15B6C243E340F0025F804 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 71E8E97FA3A197DCEB51D55C /* Pods-watch Extension.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -581,6 +715,7 @@ }; 49C15B6D243E340F0025F804 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 8AA421E0363D82BA724B0CDC /* Pods-watch Extension.profile.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/contents.xcworkspacedata b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a16ed0..21a3cc14c74 100644 --- a/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/dev/integration_tests/ios_app_with_extensions/pubspec.yaml b/dev/integration_tests/ios_app_with_extensions/pubspec.yaml index ded699fc03a..5dc83dbc19d 100644 --- a/dev/integration_tests/ios_app_with_extensions/pubspec.yaml +++ b/dev/integration_tests/ios_app_with_extensions/pubspec.yaml @@ -18,10 +18,15 @@ environment: dependencies: flutter: sdk: flutter + # This integration test includes a watchOS pod. Add a Flutter plugin + # to prompt the tool to run pod install. + device_info: 0.4.2+7 characters: 1.1.0-nullsafety.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.15.0-nullsafety.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + device_info_platform_interface: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.3.0-nullsafety.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + plugin_platform_interface: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.0-nullsafety.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.0-nullsafety.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -86,4 +91,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 9599 +# PUBSPEC CHECKSUM: b825 diff --git a/packages/flutter_tools/bin/xcode_backend.sh b/packages/flutter_tools/bin/xcode_backend.sh index 4d70f55029e..f33fe03ac14 100755 --- a/packages/flutter_tools/bin/xcode_backend.sh +++ b/packages/flutter_tools/bin/xcode_backend.sh @@ -271,11 +271,10 @@ ThinFramework() { } ThinAppFrameworks() { - local app_path="${TARGET_BUILD_DIR}/${WRAPPER_NAME}" - local frameworks_dir="${app_path}/Frameworks" + local xcode_frameworks_dir="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - [[ -d "$frameworks_dir" ]] || return 0 - find "${app_path}" -type d -name "*.framework" | while read framework_dir; do + [[ -d "${xcode_frameworks_dir}" ]] || return 0 + find "${xcode_frameworks_dir}" -type d -name "*.framework" | while read framework_dir; do ThinFramework "$framework_dir" "$ARCHS" done }