Re-reland Xcode backend refactor (#23762) * Use Xcode build configurations to drive Flutter build mode * Proper check wrt local_engine, print error if profile mode misisng * Remove unused code, update tests, fix template problem, update warning * fix up warning * add explanatory dev comment * fix whitespace * missing words, change lambda arrow to function body * error indentation * Test early exits for xcode_backend.sh * only on macOS, use right test * Update error messages * case insensitive compare for build config * Update gallery podfile * update projects to add profile configuration * make compatible with flavors * add missing plist files * add FLUTTER_FRAMEWORK_DIR back, set swift version for profile, tell Podfile about profile
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 346392a..77286f0 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -317,6 +317,23 @@ printError('Flutter expects a build configuration named ${XcodeProjectInfo.expectedBuildConfigurationFor(buildInfo, scheme)} or similar.'); printError('Open Xcode to fix the problem:'); printError(' open ios/Runner.xcworkspace'); + printError('1. Click on "Runner" in the project navigator.'); + printError('2. Ensure the Runner PROJECT is selected, not the Runner TARGET.'); + if (buildInfo.isDebug) { + printError('3. Click the Editor->Add Configuration->Duplicate "Debug" Configuration.'); + } else { + printError('3. Click the Editor->Add Configuration->Duplicate "Release" Configuration.'); + } + printError(''); + printError(' If this option is disabled, it is likely you have the target selected instead'); + printError(' of the project; see:'); + printError(' https://stackoverflow.com/questions/19842746/adding-a-build-configuration-in-xcode'); + printError(''); + printError(' If you have created a completely custom set of build configurations,'); + printError(' you can set the FLUTTER_BUILD_MODE=${buildInfo.modeName.toLowerCase()}'); + printError(' in the .xcconfig file for that configuration and run from Xcode.'); + printError(''); + printError('4. If you are not using completely custom build configurations, name the newly created configuration ${buildInfo.modeName}.'); return XcodeBuildResult(success: false); }
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index 2bb2a20..e8e07fc 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -49,9 +49,6 @@ if (targetOverride != null) localsBuffer.writeln('FLUTTER_TARGET=$targetOverride'); - // The runtime mode for the current build. - localsBuffer.writeln('FLUTTER_BUILD_MODE=${buildInfo.modeName}'); - // The build outputs directory, relative to FLUTTER_APPLICATION_PATH. localsBuffer.writeln('FLUTTER_BUILD_DIR=${getBuildDirectory()}'); @@ -61,6 +58,7 @@ // For module projects we do not want to write the FLUTTER_FRAMEWORK_DIR // explicitly. Rather we rely on the xcode backend script and the Podfile // logic to derive it from FLUTTER_ROOT and FLUTTER_BUILD_MODE. + // However, this is necessary for regular projects using Cocoapods. localsBuffer.writeln('FLUTTER_FRAMEWORK_DIR=${flutterFrameworkDir(buildInfo.mode)}'); } @@ -247,6 +245,17 @@ return baseConfiguration + '-$scheme'; } + /// Checks whether the [buildConfigurations] contains the specified string, without + /// regard to case. + bool hasBuildConfiguratinForBuildMode(String buildMode) { + buildMode = buildMode.toLowerCase(); + for (String name in buildConfigurations) { + if (name.toLowerCase() == buildMode) { + return true; + } + } + return false; + } /// Returns unique scheme matching [buildInfo], or null, if there is no unique /// best match. String schemeFor(BuildInfo buildInfo) { @@ -262,7 +271,7 @@ /// null, if there is no unique best match. String buildConfigurationFor(BuildInfo buildInfo, String scheme) { final String expectedConfiguration = expectedBuildConfigurationFor(buildInfo, scheme); - if (buildConfigurations.contains(expectedConfiguration)) + if (hasBuildConfiguratinForBuildMode(expectedConfiguration)) return expectedConfiguration; final String baseConfiguration = _baseConfigurationFor(buildInfo); return _uniqueMatch(buildConfigurations, (String candidate) { @@ -274,7 +283,13 @@ }); } - static String _baseConfigurationFor(BuildInfo buildInfo) => buildInfo.isDebug ? 'Debug' : 'Release'; + static String _baseConfigurationFor(BuildInfo buildInfo) { + if (buildInfo.isDebug) + return 'Debug'; + if (buildInfo.isProfile) + return 'Profile'; + return 'Release'; + } static String _uniqueMatch(Iterable<String> strings, bool matches(String s)) { final List<String> options = strings.where(matches).toList();