mirror of
https://github.com/flutter/flutter
synced 2024-10-12 19:23:02 +00:00
Add iOS build -destination flag (#90915)
This commit is contained in:
parent
905ac63e34
commit
61e2e86611
|
@ -184,7 +184,8 @@ Future<XcodeBuildResult> buildXcodeProject({
|
|||
|
||||
final Map<String, String> buildSettings = await app.project.buildSettingsForBuildInfo(
|
||||
buildInfo,
|
||||
environmentType: environmentType
|
||||
environmentType: environmentType,
|
||||
deviceId: deviceID,
|
||||
) ?? <String, String>{};
|
||||
|
||||
if (codesign && environmentType == EnvironmentType.physical) {
|
||||
|
@ -249,11 +250,12 @@ Future<XcodeBuildResult> buildXcodeProject({
|
|||
final bool hasWatchCompanion = await app.project.containsWatchCompanion(
|
||||
projectInfo.targets,
|
||||
buildInfo,
|
||||
deviceID,
|
||||
);
|
||||
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.
|
||||
globals.printStatus('Watch companion app found. Adjusting build settings.');
|
||||
globals.printStatus('Watch companion app found.');
|
||||
if (environmentType == EnvironmentType.simulator && (deviceID == null || deviceID == '')) {
|
||||
globals.printError('No simulator device ID has been set.');
|
||||
globals.printError('A device ID is required to build an app with a watchOS companion app.');
|
||||
|
@ -261,9 +263,6 @@ Future<XcodeBuildResult> buildXcodeProject({
|
|||
globals.printError('and specify one using the -d, --device-id flag.');
|
||||
return XcodeBuildResult(success: false);
|
||||
}
|
||||
if (environmentType == EnvironmentType.simulator) {
|
||||
buildCommands.addAll(<String>['-destination', 'id=$deviceID']);
|
||||
}
|
||||
} else {
|
||||
if (environmentType == EnvironmentType.physical) {
|
||||
buildCommands.addAll(<String>['-sdk', 'iphoneos']);
|
||||
|
@ -272,6 +271,15 @@ Future<XcodeBuildResult> buildXcodeProject({
|
|||
}
|
||||
}
|
||||
|
||||
buildCommands.add('-destination');
|
||||
if (deviceID != null) {
|
||||
buildCommands.add('id=$deviceID');
|
||||
} else if (environmentType == EnvironmentType.physical) {
|
||||
buildCommands.add('generic/platform=iOS');
|
||||
} else {
|
||||
buildCommands.add('generic/platform=iOS Simulator');
|
||||
}
|
||||
|
||||
if (activeArch != null) {
|
||||
final String activeArchName = getNameForDarwinArch(activeArch);
|
||||
if (activeArchName != null) {
|
||||
|
|
|
@ -173,6 +173,7 @@ class XcodeProjectInterpreter {
|
|||
final Status status = _logger.startSpinner();
|
||||
final String? scheme = buildContext.scheme;
|
||||
final String? configuration = buildContext.configuration;
|
||||
final String? deviceId = buildContext.deviceId;
|
||||
final List<String> showBuildSettingsCommand = <String>[
|
||||
...xcrunCommand(),
|
||||
'xcodebuild',
|
||||
|
@ -184,6 +185,13 @@ class XcodeProjectInterpreter {
|
|||
...<String>['-configuration', configuration],
|
||||
if (buildContext.environmentType == EnvironmentType.simulator)
|
||||
...<String>['-sdk', 'iphonesimulator'],
|
||||
'-destination',
|
||||
if (deviceId != null)
|
||||
'id=$deviceId'
|
||||
else if (buildContext.environmentType == EnvironmentType.physical)
|
||||
'generic/platform=iOS'
|
||||
else
|
||||
'generic/platform=iOS Simulator',
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${_fileSystem.path.absolute(getIosBuildDirectory())}',
|
||||
...environmentVariablesAsXcodeBuildSettings(_platform)
|
||||
|
@ -351,14 +359,20 @@ String substituteXcodeVariables(String str, Map<String, String> xcodeBuildSettin
|
|||
|
||||
@immutable
|
||||
class XcodeProjectBuildContext {
|
||||
const XcodeProjectBuildContext({this.scheme, this.configuration, this.environmentType = EnvironmentType.physical});
|
||||
const XcodeProjectBuildContext({
|
||||
this.scheme,
|
||||
this.configuration,
|
||||
this.environmentType = EnvironmentType.physical,
|
||||
this.deviceId,
|
||||
});
|
||||
|
||||
final String? scheme;
|
||||
final String? configuration;
|
||||
final EnvironmentType environmentType;
|
||||
final String? deviceId;
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(scheme, configuration, environmentType);
|
||||
int get hashCode => Object.hash(scheme, configuration, environmentType, deviceId);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
|
@ -368,6 +382,7 @@ class XcodeProjectBuildContext {
|
|||
return other is XcodeProjectBuildContext &&
|
||||
other.scheme == scheme &&
|
||||
other.configuration == configuration &&
|
||||
other.deviceId == deviceId &&
|
||||
other.environmentType == environmentType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,7 +244,11 @@ class IosProject extends XcodeBasedProject {
|
|||
/// 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>?> buildSettingsForBuildInfo(BuildInfo? buildInfo, { EnvironmentType environmentType = EnvironmentType.physical }) async {
|
||||
Future<Map<String, String>?> buildSettingsForBuildInfo(
|
||||
BuildInfo? buildInfo, {
|
||||
EnvironmentType environmentType = EnvironmentType.physical,
|
||||
String? deviceId,
|
||||
}) async {
|
||||
if (!existsSync()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -262,7 +266,12 @@ class IosProject extends XcodeBasedProject {
|
|||
buildInfo,
|
||||
scheme,
|
||||
);
|
||||
final XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(environmentType: environmentType, scheme: scheme, configuration: configuration);
|
||||
final XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(
|
||||
environmentType: environmentType,
|
||||
scheme: scheme,
|
||||
configuration: configuration,
|
||||
deviceId: deviceId,
|
||||
);
|
||||
final Map<String, String>? currentBuildSettings = _buildSettingsByBuildContext[buildContext];
|
||||
if (currentBuildSettings == null) {
|
||||
final Map<String, String>? calculatedBuildSettings = await _xcodeProjectBuildSettings(buildContext);
|
||||
|
@ -310,7 +319,7 @@ class IosProject extends XcodeBasedProject {
|
|||
}
|
||||
|
||||
/// Check if one the [targets] of the project is a watchOS companion app target.
|
||||
Future<bool> containsWatchCompanion(List<String> targets, BuildInfo buildInfo) async {
|
||||
Future<bool> containsWatchCompanion(List<String> targets, BuildInfo buildInfo, String? deviceId) async {
|
||||
final String? bundleIdentifier = await productBundleIdentifier(buildInfo);
|
||||
// A bundle identifier is required for a companion app.
|
||||
if (bundleIdentifier == null) {
|
||||
|
@ -330,7 +339,7 @@ class IosProject extends XcodeBasedProject {
|
|||
// The key WKCompanionAppBundleIdentifier might contain an xcode variable
|
||||
// that needs to be substituted before comparing it with bundle id
|
||||
if (fromPlist != null && fromPlist.contains(r'$')) {
|
||||
final Map<String, String>? allBuildSettings = await buildSettingsForBuildInfo(buildInfo);
|
||||
final Map<String, String>? allBuildSettings = await buildSettingsForBuildInfo(buildInfo, deviceId: deviceId);
|
||||
if (allBuildSettings != null) {
|
||||
final String substitutedVariable = substituteXcodeVariables(fromPlist, allBuildSettings);
|
||||
if (substitutedVariable == bundleIdentifier) {
|
||||
|
|
|
@ -112,10 +112,15 @@ void main() {
|
|||
'-scheme', 'Runner',
|
||||
'BUILD_DIR=/build/ios',
|
||||
'-sdk',
|
||||
if (simulator)
|
||||
'iphonesimulator'
|
||||
else
|
||||
if (simulator) ...<String>[
|
||||
'iphonesimulator',
|
||||
'-destination',
|
||||
'generic/platform=iOS Simulator',
|
||||
] else ...<String>[
|
||||
'iphoneos',
|
||||
'-destination',
|
||||
'generic/platform=iOS',
|
||||
],
|
||||
'FLUTTER_SUPPRESS_ANALYTICS=true',
|
||||
'COMPILER_INDEX_STORE_ENABLE=NO',
|
||||
],
|
||||
|
|
|
@ -96,6 +96,8 @@ void main() {
|
|||
'-workspace', 'Runner.xcworkspace',
|
||||
'-scheme', 'Runner',
|
||||
'-sdk', 'iphoneos',
|
||||
'-destination',
|
||||
'generic/platform=iOS',
|
||||
'FLUTTER_SUPPRESS_ANALYTICS=true',
|
||||
'COMPILER_INDEX_STORE_ENABLE=NO',
|
||||
'-archivePath', '/build/ios/archive/Runner',
|
||||
|
|
|
@ -54,6 +54,8 @@ const List<String> kRunReleaseArgs = <String>[
|
|||
'BUILD_DIR=/build/ios',
|
||||
'-sdk',
|
||||
'iphoneos',
|
||||
'-destination',
|
||||
'id=123',
|
||||
'ONLY_ACTIVE_ARCH=YES',
|
||||
'ARCHS=arm64',
|
||||
'FLUTTER_SUPPRESS_ANALYTICS=true',
|
||||
|
|
|
@ -278,6 +278,8 @@ void main() {
|
|||
'/',
|
||||
'-scheme',
|
||||
'Free',
|
||||
'-destination',
|
||||
'id=123',
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
|
||||
],
|
||||
|
@ -286,7 +288,7 @@ void main() {
|
|||
]);
|
||||
|
||||
expect(
|
||||
await xcodeProjectInterpreter.getBuildSettings('', buildContext: const XcodeProjectBuildContext(scheme: 'Free')),
|
||||
await xcodeProjectInterpreter.getBuildSettings('', buildContext: const XcodeProjectBuildContext(deviceId: '123', scheme: 'Free')),
|
||||
const <String, String>{});
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
}, overrides: <Type, Generator>{
|
||||
|
@ -308,6 +310,8 @@ void main() {
|
|||
'/',
|
||||
'-sdk',
|
||||
'iphonesimulator',
|
||||
'-destination',
|
||||
'generic/platform=iOS Simulator',
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
|
||||
],
|
||||
|
@ -340,6 +344,8 @@ void main() {
|
|||
'xcodebuild',
|
||||
'-project',
|
||||
'/',
|
||||
'-destination',
|
||||
'generic/platform=iOS',
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
|
||||
],
|
||||
|
@ -371,6 +377,8 @@ void main() {
|
|||
fileSystem.path.separator,
|
||||
'-scheme',
|
||||
'Free',
|
||||
'-destination',
|
||||
'generic/platform=iOS',
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
|
||||
'CODE_SIGN_STYLE=Manual',
|
||||
|
|
|
@ -628,7 +628,7 @@ apply plugin: 'kotlin-android'
|
|||
|
||||
testUsingContext('cannot find bundle identifier', () async {
|
||||
final FlutterProject project = await someProject();
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null), isFalse);
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null, '123'), isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
@ -647,7 +647,7 @@ apply plugin: 'kotlin-android'
|
|||
|
||||
testUsingContext('no Info.plist in target', () async {
|
||||
final FlutterProject project = await someProject();
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null), isFalse);
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null, '123'), isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
@ -660,7 +660,7 @@ apply plugin: 'kotlin-android'
|
|||
final FlutterProject project = await someProject();
|
||||
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
|
||||
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null), isFalse);
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null, '123'), isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
@ -674,7 +674,7 @@ apply plugin: 'kotlin-android'
|
|||
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
|
||||
|
||||
testPlistParser.setProperty('WKCompanionAppBundleIdentifier', 'io.flutter.someOTHERproject');
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null), isFalse);
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null, '123'), isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
@ -689,7 +689,7 @@ apply plugin: 'kotlin-android'
|
|||
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
|
||||
testPlistParser.setProperty('WKCompanionAppBundleIdentifier', 'io.flutter.someProject');
|
||||
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null), isTrue);
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null, '123'), isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
@ -707,7 +707,7 @@ apply plugin: 'kotlin-android'
|
|||
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
|
||||
testPlistParser.setProperty('WKCompanionAppBundleIdentifier', r'$(PRODUCT_BUNDLE_IDENTIFIER)');
|
||||
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null), isTrue);
|
||||
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], null, '123'), isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
|
Loading…
Reference in a new issue