Remove Runner target check, prefer schemes (#56620)
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart
index 0b00d6b..3315e46 100644
--- a/packages/flutter_tools/lib/src/application_package.dart
+++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -31,6 +31,7 @@
Future<ApplicationPackage> getPackageForPlatform(
TargetPlatform platform, {
+ BuildInfo buildInfo,
File applicationBinary,
}) async {
switch (platform) {
@@ -47,7 +48,7 @@
: AndroidApk.fromApk(applicationBinary);
case TargetPlatform.ios:
return applicationBinary == null
- ? await IOSApp.fromIosProject(FlutterProject.current().ios)
+ ? await IOSApp.fromIosProject(FlutterProject.current().ios, buildInfo)
: IOSApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.tester:
return FlutterTesterApp.fromCurrentDirectory();
@@ -327,7 +328,7 @@
);
}
- static Future<IOSApp> fromIosProject(IosProject project) {
+ static Future<IOSApp> fromIosProject(IosProject project, BuildInfo buildInfo) {
if (getCurrentHostPlatform() != HostPlatform.darwin_x64) {
return null;
}
@@ -344,7 +345,7 @@
globals.printError('Expected ios/Runner.xcodeproj/project.pbxproj but this file is missing.');
return null;
}
- return BuildableIOSApp.fromProject(project);
+ return BuildableIOSApp.fromProject(project, buildInfo);
}
@override
@@ -360,9 +361,9 @@
: _hostAppBundleName = hostAppBundleName,
super(projectBundleId: projectBundleId);
- static Future<BuildableIOSApp> fromProject(IosProject project) async {
- final String projectBundleId = await project.productBundleIdentifier;
- final String hostAppBundleName = await project.hostAppBundleName;
+ static Future<BuildableIOSApp> fromProject(IosProject project, BuildInfo buildInfo) async {
+ final String projectBundleId = await project.productBundleIdentifier(buildInfo);
+ final String hostAppBundleName = await project.hostAppBundleName(buildInfo);
return BuildableIOSApp(project, projectBundleId, hostAppBundleName);
}
@@ -416,7 +417,10 @@
MacOSApp macOS;
WindowsApp windows;
- Future<ApplicationPackage> getPackageForPlatform(TargetPlatform platform) async {
+ Future<ApplicationPackage> getPackageForPlatform(
+ TargetPlatform platform,
+ BuildInfo buildInfo,
+ ) async {
switch (platform) {
case TargetPlatform.android:
case TargetPlatform.android_arm:
@@ -426,7 +430,7 @@
android ??= await AndroidApk.fromAndroidProject(FlutterProject.current().android);
return android;
case TargetPlatform.ios:
- iOS ??= await IOSApp.fromIosProject(FlutterProject.current().ios);
+ iOS ??= await IOSApp.fromIosProject(FlutterProject.current().ios, buildInfo);
return iOS;
case TargetPlatform.fuchsia_arm64:
case TargetPlatform.fuchsia_x64:
diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
index b3cb71d..b445ea1 100644
--- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
@@ -370,6 +370,7 @@
firstBuildTime = DateTime.now();
final ApplicationPackage package = await ApplicationPackageFactory.instance.getPackageForPlatform(
TargetPlatform.web_javascript,
+ buildInfo: debuggingOptions.buildInfo,
applicationBinary: null,
);
if (package == null) {
diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart
index fb7a10b..5f5dee1 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios.dart
@@ -64,7 +64,11 @@
throwToolExit('Building for iOS is only supported on the Mac.');
}
- final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(TargetPlatform.ios) as BuildableIOSApp;
+ final BuildInfo buildInfo = getBuildInfo();
+ final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(
+ TargetPlatform.ios,
+ buildInfo,
+ ) as BuildableIOSApp;
if (app == null) {
throwToolExit('Application not configured for iOS');
@@ -76,7 +80,6 @@
globals.printStatus('Warning: Building for device with codesigning disabled. You will '
'have to manually codesign before deploying to device.');
}
- final BuildInfo buildInfo = getBuildInfo();
if (forSimulator && !buildInfo.supportsSimulator) {
throwToolExit('${toTitleCase(buildInfo.friendlyModeName)} mode is not supported for simulators.');
}
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 479119b..5fa5942 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
@@ -181,8 +181,8 @@
final Directory outputDirectory = globals.fs.directory(globals.fs.path.absolute(globals.fs.path.normalize(outputArgument)));
- final String productBundleIdentifier = await _project.ios.productBundleIdentifier;
for (final BuildInfo buildInfo in buildInfos) {
+ final String productBundleIdentifier = await _project.ios.productBundleIdentifier(buildInfo);
globals.printStatus('Building frameworks for $productBundleIdentifier in ${getNameForBuildMode(buildInfo.mode)} mode...');
final String xcodeBuildConfiguration = toTitleCase(getNameForBuildMode(buildInfo.mode));
final Directory modeDirectory = outputDirectory.childDirectory(xcodeBuildConfiguration);
diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart
index b6bfdf2..9055483 100644
--- a/packages/flutter_tools/lib/src/commands/drive.dart
+++ b/packages/flutter_tools/lib/src/commands/drive.dart
@@ -404,7 +404,7 @@
await appStopper(command);
final ApplicationPackage package = await command.applicationPackages
- .getPackageForPlatform(await command.device.targetPlatform);
+ .getPackageForPlatform(await command.device.targetPlatform, command.getBuildInfo());
if (command.shouldBuild) {
globals.printTrace('Installing application package.');
@@ -497,7 +497,10 @@
Future<bool> _stopApp(DriveCommand command) async {
globals.printTrace('Stopping application.');
- final ApplicationPackage package = await command.applicationPackages.getPackageForPlatform(await command.device.targetPlatform);
+ final ApplicationPackage package = await command.applicationPackages.getPackageForPlatform(
+ await command.device.targetPlatform,
+ command.getBuildInfo(),
+ );
final bool stopped = await command.device.stopApp(package);
await command._deviceLogSubscription?.cancel();
return stopped;
diff --git a/packages/flutter_tools/lib/src/commands/install.dart b/packages/flutter_tools/lib/src/commands/install.dart
index 2d2b69a..320552a 100644
--- a/packages/flutter_tools/lib/src/commands/install.dart
+++ b/packages/flutter_tools/lib/src/commands/install.dart
@@ -43,7 +43,10 @@
@override
Future<FlutterCommandResult> runCommand() async {
- final ApplicationPackage package = await applicationPackages.getPackageForPlatform(await device.targetPlatform);
+ final ApplicationPackage package = await applicationPackages.getPackageForPlatform(
+ await device.targetPlatform,
+ null, // Build info isn't relevant for install, will use whatever bundle was built last.
+ );
Cache.releaseLockEarly();
diff --git a/packages/flutter_tools/lib/src/ios/code_signing.dart b/packages/flutter_tools/lib/src/ios/code_signing.dart
index cce0ae4..ec99325 100644
--- a/packages/flutter_tools/lib/src/ios/code_signing.dart
+++ b/packages/flutter_tools/lib/src/ios/code_signing.dart
@@ -13,6 +13,7 @@
import '../base/io.dart';
import '../base/logger.dart';
import '../base/process.dart';
+import '../build_info.dart';
import '../convert.dart' show utf8;
import '../globals.dart' as globals;
@@ -101,8 +102,9 @@
@required BuildableIOSApp iosApp,
@required ProcessManager processManager,
@required Logger logger,
+ @required BuildInfo buildInfo,
}) async {
- final Map<String, String> buildSettings = await iosApp.project.buildSettings;
+ final Map<String, String> buildSettings = await iosApp.project.buildSettingsForBuildInfo(buildInfo);
if (buildSettings == null) {
return null;
}
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index d3d6e92..f2f088d 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -111,12 +111,6 @@
await removeFinderExtendedAttributes(app.project.hostAppRoot, processUtils, globals.logger);
final XcodeProjectInfo projectInfo = await globals.xcodeProjectInterpreter.getInfo(app.project.hostAppRoot.path);
- if (!projectInfo.targets.contains('Runner')) {
- globals.printError('The Xcode project does not define target "Runner" which is needed by Flutter tooling.');
- globals.printError('Open Xcode to fix the problem:');
- globals.printError(' open ios/Runner.xcworkspace');
- return XcodeBuildResult(success: false);
- }
final String scheme = projectInfo.schemeFor(buildInfo);
if (scheme == null) {
globals.printError('');
@@ -180,7 +174,8 @@
autoSigningConfigs = await getCodeSigningIdentityDevelopmentTeam(
iosApp: app,
processManager: globals.processManager,
- logger: globals.logger
+ logger: globals.logger,
+ buildInfo: buildInfo,
);
}
@@ -229,7 +224,10 @@
}
// Check if the project contains a watchOS companion app.
- final bool hasWatchCompanion = await app.project.containsWatchCompanion(projectInfo.targets);
+ final bool hasWatchCompanion = await app.project.containsWatchCompanion(
+ projectInfo.targets,
+ buildInfo,
+ );
if (hasWatchCompanion) {
// The -sdk argument has to be omitted if a watchOS companion app exists.
// Otherwise the build will fail as WatchKit dependencies cannot be build using the iOS SDK.
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
index 1786508..b2fab77 100644
--- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -309,9 +309,12 @@
/// Asynchronously retrieve xcode build settings. This one is preferred for
/// new call-sites.
+ ///
+ /// If [scheme] is null, xcodebuild will return build settings for the first discovered
+ /// target (by default this is Runner).
Future<Map<String, String>> getBuildSettings(
- String projectPath,
- String target, {
+ String projectPath, {
+ String scheme,
Duration timeout = const Duration(minutes: 1),
}) async {
final Status status = Status.withSpinner(
@@ -324,8 +327,8 @@
_executable,
'-project',
_fileSystem.path.absolute(projectPath),
- '-target',
- target,
+ if (scheme != null)
+ ...<String>['-scheme', scheme],
'-showBuildSettings',
...environmentVariablesAsXcodeBuildSettings(_platform)
];
@@ -465,7 +468,6 @@
final List<String> buildConfigurations;
final List<String> schemes;
- bool get definesCustomTargets => !(targets.contains('Runner') && targets.length == 1);
bool get definesCustomSchemes => !(schemes.contains('Runner') && schemes.length == 1);
bool get definesCustomBuildConfigurations {
return !(buildConfigurations.contains('Debug') &&
@@ -475,7 +477,7 @@
/// The expected scheme for [buildInfo].
static String expectedSchemeFor(BuildInfo buildInfo) {
- return toTitleCase(buildInfo.flavor ?? 'runner');
+ return toTitleCase(buildInfo?.flavor ?? 'runner');
}
/// The expected build configuration for [buildInfo] and [scheme].
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart
index c46a096..2960019 100644
--- a/packages/flutter_tools/lib/src/macos/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -267,7 +267,6 @@
} else {
final bool isSwift = (await _xcodeProjectInterpreter.getBuildSettings(
runnerProject.path,
- 'Runner',
)).containsKey('SWIFT_VERSION');
podfileTemplateName = isSwift ? 'Podfile-ios-swift' : 'Podfile-ios-objc';
}
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 77cd014..8ef4656 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -102,11 +102,14 @@
/// Gradle group ID.
Future<Set<String>> get organizationNames async {
final List<String> candidates = <String>[
- await ios.productBundleIdentifier,
+ // Don't require iOS build info, this method is only
+ // used during create as best-effort, use the
+ // default target bundle identifier.
+ await ios.productBundleIdentifier(null),
android.applicationId,
android.group,
example.android.applicationId,
- await example.ios.productBundleIdentifier,
+ await example.ios.productBundleIdentifier(null),
];
return Set<String>.of(candidates
.map<String>(_organizationNameFromPackageName)
@@ -411,11 +414,11 @@
/// The product bundle identifier of the host app, or null if not set or if
/// iOS tooling needed to read it is not installed.
- Future<String> get productBundleIdentifier async =>
- _productBundleIdentifier ??= await _parseProductBundleIdentifier();
+ Future<String> productBundleIdentifier(BuildInfo buildInfo) async =>
+ _productBundleIdentifier ??= await _parseProductBundleIdentifier(buildInfo);
String _productBundleIdentifier;
- Future<String> _parseProductBundleIdentifier() async {
+ Future<String> _parseProductBundleIdentifier(BuildInfo buildInfo) async {
String fromPlist;
final File defaultInfoPlist = defaultHostInfoPlist;
// Users can change the location of the Info.plist.
@@ -434,7 +437,7 @@
return fromPlist;
}
}
- final Map<String, String> allBuildSettings = await buildSettings;
+ final Map<String, String> allBuildSettings = await buildSettingsForBuildInfo(buildInfo);
if (allBuildSettings != null) {
if (fromPlist != null) {
// Perform variable substitution using build settings.
@@ -458,18 +461,18 @@
}
/// The bundle name of the host app, `My App.app`.
- Future<String> get hostAppBundleName async =>
- _hostAppBundleName ??= await _parseHostAppBundleName();
+ Future<String> hostAppBundleName(BuildInfo buildInfo) async =>
+ _hostAppBundleName ??= await _parseHostAppBundleName(buildInfo);
String _hostAppBundleName;
- Future<String> _parseHostAppBundleName() async {
+ Future<String> _parseHostAppBundleName(BuildInfo buildInfo) async {
// The product name and bundle name are derived from the display name, which the user
// is instructed to change in Xcode as part of deploying to the App Store.
// https://flutter.dev/docs/deployment/ios#review-xcode-project-settings
// The only source of truth for the name is Xcode's interpretation of the build settings.
String productName;
if (globals.xcodeProjectInterpreter.isInstalled) {
- final Map<String, String> xcodeBuildSettings = await buildSettings;
+ final Map<String, String> xcodeBuildSettings = await buildSettingsForBuildInfo(buildInfo);
if (xcodeBuildSettings != null) {
productName = xcodeBuildSettings['FULL_PRODUCT_NAME'];
}
@@ -483,17 +486,20 @@
/// The build settings for the host app of this project, as a detached map.
///
/// Returns null, if iOS tooling is unavailable.
- Future<Map<String, String>> get buildSettings async =>
- _buildSettings ??= await _xcodeProjectBuildSettings();
- Map<String, String> _buildSettings;
+ Future<Map<String, String>> buildSettingsForBuildInfo(BuildInfo buildInfo) async {
+ _buildSettingsByScheme ??= <String, Map<String, String>>{};
+ final String scheme = xcode.XcodeProjectInfo.expectedSchemeFor(buildInfo);
+ return _buildSettingsByScheme[scheme] ??= await _xcodeProjectBuildSettings(scheme);
+ }
+ Map<String, Map<String, String>> _buildSettingsByScheme;
- Future<Map<String, String>> _xcodeProjectBuildSettings() async {
+ Future<Map<String, String>> _xcodeProjectBuildSettings(String scheme) async {
if (!globals.xcodeProjectInterpreter.isInstalled) {
return null;
}
final Map<String, String> buildSettings = await globals.xcodeProjectInterpreter.getBuildSettings(
xcodeProject.path,
- _hostAppProjectName,
+ scheme: scheme,
);
if (buildSettings != null && buildSettings.isNotEmpty) {
// No timeouts, flakes, or errors.
@@ -511,8 +517,8 @@
}
/// Check if one the [targets] of the project is a watchOS companion app target.
- Future<bool> containsWatchCompanion(List<String> targets) async {
- final String bundleIdentifier = await productBundleIdentifier;
+ Future<bool> containsWatchCompanion(List<String> targets, BuildInfo buildInfo) async {
+ final String bundleIdentifier = await productBundleIdentifier(buildInfo);
// A bundle identifier is required for a companion app.
if (bundleIdentifier == null) {
return false;
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index d9d044d..40d6311 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -469,6 +469,7 @@
final TargetPlatform targetPlatform = await device.targetPlatform;
package = await ApplicationPackageFactory.instance.getPackageForPlatform(
targetPlatform,
+ buildInfo: hotRunner.debuggingOptions.buildInfo,
applicationBinary: hotRunner.applicationBinary,
);
@@ -524,6 +525,7 @@
final TargetPlatform targetPlatform = await device.targetPlatform;
package = await ApplicationPackageFactory.instance.getPackageForPlatform(
targetPlatform,
+ buildInfo: coldRunner.debuggingOptions.buildInfo,
applicationBinary: coldRunner.applicationBinary,
);