Exclude arm64 from iOS app archs if unsupported by plugins (#87244)
This commit is contained in:
parent
5b0fd2f31c
commit
a69b3ca5d3
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import '../artifacts.dart';
|
import '../artifacts.dart';
|
||||||
import '../base/file_system.dart';
|
import '../base/file_system.dart';
|
||||||
|
import '../base/os.dart';
|
||||||
import '../build_info.dart';
|
import '../build_info.dart';
|
||||||
import '../cache.dart';
|
import '../cache.dart';
|
||||||
import '../flutter_manifest.dart';
|
import '../flutter_manifest.dart';
|
||||||
@ -35,7 +36,7 @@ Future<void> updateGeneratedXcodeProperties({
|
|||||||
bool useMacOSConfig = false,
|
bool useMacOSConfig = false,
|
||||||
String? buildDirOverride,
|
String? buildDirOverride,
|
||||||
}) async {
|
}) async {
|
||||||
final List<String> xcodeBuildSettings = _xcodeBuildSettingsLines(
|
final List<String> xcodeBuildSettings = await _xcodeBuildSettingsLines(
|
||||||
project: project,
|
project: project,
|
||||||
buildInfo: buildInfo,
|
buildInfo: buildInfo,
|
||||||
targetOverride: targetOverride,
|
targetOverride: targetOverride,
|
||||||
@ -136,13 +137,13 @@ String? parsedBuildNumber({
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// List of lines of build settings. Example: 'FLUTTER_BUILD_DIR=build'
|
/// List of lines of build settings. Example: 'FLUTTER_BUILD_DIR=build'
|
||||||
List<String> _xcodeBuildSettingsLines({
|
Future<List<String>> _xcodeBuildSettingsLines({
|
||||||
required FlutterProject project,
|
required FlutterProject project,
|
||||||
required BuildInfo buildInfo,
|
required BuildInfo buildInfo,
|
||||||
String? targetOverride,
|
String? targetOverride,
|
||||||
bool useMacOSConfig = false,
|
bool useMacOSConfig = false,
|
||||||
String? buildDirOverride,
|
String? buildDirOverride,
|
||||||
}) {
|
}) async {
|
||||||
final List<String> xcodeBuildSettings = <String>[];
|
final List<String> xcodeBuildSettings = <String>[];
|
||||||
|
|
||||||
final String flutterRoot = globals.fs.path.normalize(Cache.flutterRoot!);
|
final String flutterRoot = globals.fs.path.normalize(Cache.flutterRoot!);
|
||||||
@ -204,7 +205,15 @@ List<String> _xcodeBuildSettingsLines({
|
|||||||
// ARM not yet supported https://github.com/flutter/flutter/issues/69221
|
// ARM not yet supported https://github.com/flutter/flutter/issues/69221
|
||||||
xcodeBuildSettings.add('EXCLUDED_ARCHS=arm64');
|
xcodeBuildSettings.add('EXCLUDED_ARCHS=arm64');
|
||||||
} else {
|
} else {
|
||||||
xcodeBuildSettings.add('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386');
|
String excludedSimulatorArchs = 'i386';
|
||||||
|
|
||||||
|
// If any plugins or their dependencies do not support arm64 simulators
|
||||||
|
// (to run natively without Rosetta translation on an ARM Mac),
|
||||||
|
// the app will fail to build unless it also excludes arm64 simulators.
|
||||||
|
if (globals.os.hostPlatform == HostPlatform.darwin_arm && !(await project.ios.pluginsSupportArmSimulator())) {
|
||||||
|
excludedSimulatorArchs += ' arm64';
|
||||||
|
}
|
||||||
|
xcodeBuildSettings.add('EXCLUDED_ARCHS[sdk=iphonesimulator*]=$excludedSimulatorArchs');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final MapEntry<String, String> config in buildInfo.toEnvironmentConfig().entries) {
|
for (final MapEntry<String, String> config in buildInfo.toEnvironmentConfig().entries) {
|
||||||
|
@ -215,6 +215,58 @@ class XcodeProjectInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Asynchronously retrieve xcode build settings for the generated Pods.xcodeproj plugins project.
|
||||||
|
///
|
||||||
|
/// Returns the stdout of the Xcode command.
|
||||||
|
Future<String?> pluginsBuildSettingsOutput(
|
||||||
|
Directory podXcodeProject, {
|
||||||
|
Duration timeout = const Duration(minutes: 1),
|
||||||
|
}) async {
|
||||||
|
if (!podXcodeProject.existsSync()) {
|
||||||
|
// No plugins.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final Status status = _logger.startSpinner();
|
||||||
|
final List<String> showBuildSettingsCommand = <String>[
|
||||||
|
...xcrunCommand(),
|
||||||
|
'xcodebuild',
|
||||||
|
'-alltargets',
|
||||||
|
'-sdk',
|
||||||
|
'iphonesimulator',
|
||||||
|
'-project',
|
||||||
|
podXcodeProject.path,
|
||||||
|
'-showBuildSettings',
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
// showBuildSettings is reported to occasionally timeout. Here, we give it
|
||||||
|
// a lot of wiggle room (locally on Flutter Gallery, this takes ~1s).
|
||||||
|
// When there is a timeout, we retry once.
|
||||||
|
final RunResult result = await _processUtils.run(
|
||||||
|
showBuildSettingsCommand,
|
||||||
|
throwOnError: true,
|
||||||
|
workingDirectory: podXcodeProject.path,
|
||||||
|
timeout: timeout,
|
||||||
|
timeoutRetries: 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return the stdout only. Do not parse with parseXcodeBuildSettings, `-alltargets` prints the build settings
|
||||||
|
// for all targets (one per plugin), so it would require a Map of Maps.
|
||||||
|
return result.stdout.trim();
|
||||||
|
} on Exception catch (error) {
|
||||||
|
if (error is ProcessException && error.toString().contains('timed out')) {
|
||||||
|
BuildEvent('xcode-show-build-settings-timeout',
|
||||||
|
type: 'ios',
|
||||||
|
command: showBuildSettingsCommand.join(' '),
|
||||||
|
flutterUsage: _usage,
|
||||||
|
).send();
|
||||||
|
}
|
||||||
|
_logger.printTrace('Unexpected failure to get Pod Xcode project build settings: $error.');
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
status.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> cleanWorkspace(String workspacePath, String scheme, { bool verbose = false }) async {
|
Future<void> cleanWorkspace(String workspacePath, String scheme, { bool verbose = false }) async {
|
||||||
await _processUtils.run(<String>[
|
await _processUtils.run(<String>[
|
||||||
...xcrunCommand(),
|
...xcrunCommand(),
|
||||||
|
@ -146,6 +146,30 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
|
|||||||
/// Xcode workspace shared workspace settings file for the host app.
|
/// Xcode workspace shared workspace settings file for the host app.
|
||||||
File get xcodeWorkspaceSharedSettings => xcodeWorkspaceSharedData.childFile('WorkspaceSettings.xcsettings');
|
File get xcodeWorkspaceSharedSettings => xcodeWorkspaceSharedData.childFile('WorkspaceSettings.xcsettings');
|
||||||
|
|
||||||
|
/// Do all plugins support arm64 simulators to run natively on an ARM Mac?
|
||||||
|
Future<bool> pluginsSupportArmSimulator() async {
|
||||||
|
final Directory podXcodeProject = hostAppRoot
|
||||||
|
.childDirectory('Pods')
|
||||||
|
.childDirectory('Pods.xcodeproj');
|
||||||
|
if (!podXcodeProject.existsSync()) {
|
||||||
|
// No plugins.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final XcodeProjectInterpreter? xcodeProjectInterpreter = globals.xcodeProjectInterpreter;
|
||||||
|
if (xcodeProjectInterpreter == null) {
|
||||||
|
// Xcode isn't installed, don't try to check.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final String? buildSettings = await xcodeProjectInterpreter.pluginsBuildSettingsOutput(podXcodeProject);
|
||||||
|
|
||||||
|
// See if any plugins or their dependencies exclude arm64 simulators
|
||||||
|
// as a valid architecture, usually because a binary is missing that slice.
|
||||||
|
// Example: EXCLUDED_ARCHS = arm64 i386
|
||||||
|
// NOT: EXCLUDED_ARCHS = i386
|
||||||
|
return buildSettings != null && !buildSettings.contains(RegExp('EXCLUDED_ARCHS.*arm64'));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool existsSync() {
|
bool existsSync() {
|
||||||
return parent.isModule || _editableDirectory.existsSync();
|
return parent.isModule || _editableDirectory.existsSync();
|
||||||
|
@ -9,6 +9,7 @@ import 'package:flutter_tools/src/artifacts.dart';
|
|||||||
import 'package:flutter_tools/src/base/file_system.dart';
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
import 'package:flutter_tools/src/base/io.dart';
|
import 'package:flutter_tools/src/base/io.dart';
|
||||||
import 'package:flutter_tools/src/base/logger.dart';
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
|
import 'package:flutter_tools/src/base/os.dart';
|
||||||
import 'package:flutter_tools/src/base/platform.dart';
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/base/version.dart';
|
import 'package:flutter_tools/src/base/version.dart';
|
||||||
import 'package:flutter_tools/src/build_info.dart';
|
import 'package:flutter_tools/src/build_info.dart';
|
||||||
@ -20,6 +21,7 @@ import 'package:flutter_tools/src/reporting/reporting.dart';
|
|||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
import '../../src/fake_process_manager.dart';
|
import '../../src/fake_process_manager.dart';
|
||||||
|
import '../../src/fakes.dart';
|
||||||
|
|
||||||
const String xcodebuild = '/usr/bin/xcodebuild';
|
const String xcodebuild = '/usr/bin/xcodebuild';
|
||||||
|
|
||||||
@ -38,7 +40,8 @@ void main() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const FakeCommand kARMCheckCommand = FakeCommand(
|
// x64 host.
|
||||||
|
const FakeCommand kx64CheckCommand = FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'sysctl',
|
'sysctl',
|
||||||
'hw.optional.arm64',
|
'hw.optional.arm64',
|
||||||
@ -46,6 +49,15 @@ void main() {
|
|||||||
exitCode: 1,
|
exitCode: 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ARM host.
|
||||||
|
const FakeCommand kARMCheckCommand = FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'sysctl',
|
||||||
|
'hw.optional.arm64',
|
||||||
|
],
|
||||||
|
stdout: 'hw.optional.arm64: 1',
|
||||||
|
);
|
||||||
|
|
||||||
FakeProcessManager fakeProcessManager;
|
FakeProcessManager fakeProcessManager;
|
||||||
XcodeProjectInterpreter xcodeProjectInterpreter;
|
XcodeProjectInterpreter xcodeProjectInterpreter;
|
||||||
FakePlatform platform;
|
FakePlatform platform;
|
||||||
@ -70,7 +82,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild versionText returns null when xcodebuild is not fully installed', () {
|
testWithoutContext('xcodebuild versionText returns null when xcodebuild is not fully installed', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: "xcode-select: error: tool 'xcodebuild' requires Xcode, "
|
stdout: "xcode-select: error: tool 'xcodebuild' requires Xcode, "
|
||||||
@ -87,7 +99,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild versionText returns null when xcodebuild is not installed', () {
|
testWithoutContext('xcodebuild versionText returns null when xcodebuild is not installed', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
exception: ProcessException(xcodebuild, <String>['-version']),
|
exception: ProcessException(xcodebuild, <String>['-version']),
|
||||||
@ -100,7 +112,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild versionText returns formatted version text', () {
|
testWithoutContext('xcodebuild versionText returns formatted version text', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode 8.3.3\nBuild version 8E3004b',
|
stdout: 'Xcode 8.3.3\nBuild version 8E3004b',
|
||||||
@ -114,7 +126,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild versionText handles Xcode version string with unexpected format', () {
|
testWithoutContext('xcodebuild versionText handles Xcode version string with unexpected format', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
|
stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
|
||||||
@ -128,7 +140,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild version parts can be parsed', () {
|
testWithoutContext('xcodebuild version parts can be parsed', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode 11.4.1\nBuild version 11N111s',
|
stdout: 'Xcode 11.4.1\nBuild version 11N111s',
|
||||||
@ -142,7 +154,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild minor and patch version default to 0', () {
|
testWithoutContext('xcodebuild minor and patch version default to 0', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode 11\nBuild version 11N111s',
|
stdout: 'Xcode 11\nBuild version 11N111s',
|
||||||
@ -156,7 +168,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild version parts is null when version has unexpected format', () {
|
testWithoutContext('xcodebuild version parts is null when version has unexpected format', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
|
stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
|
||||||
@ -192,7 +204,7 @@ void main() {
|
|||||||
'xcodebuild isInstalled is false when Xcode is not fully installed', () {
|
'xcodebuild isInstalled is false when Xcode is not fully installed', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: "xcode-select: error: tool 'xcodebuild' requires Xcode, "
|
stdout: "xcode-select: error: tool 'xcodebuild' requires Xcode, "
|
||||||
@ -209,7 +221,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild isInstalled is false when version has unexpected format', () {
|
testWithoutContext('xcodebuild isInstalled is false when version has unexpected format', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
|
stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
|
||||||
@ -223,7 +235,7 @@ void main() {
|
|||||||
testWithoutContext('xcodebuild isInstalled is true when version has expected format', () {
|
testWithoutContext('xcodebuild isInstalled is true when version has expected format', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||||
stdout: 'Xcode 8.3.3\nBuild version 8E3004b',
|
stdout: 'Xcode 8.3.3\nBuild version 8E3004b',
|
||||||
@ -237,13 +249,7 @@ void main() {
|
|||||||
testWithoutContext('xcrun runs natively on arm64', () {
|
testWithoutContext('xcrun runs natively on arm64', () {
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
FakeCommand(
|
kARMCheckCommand,
|
||||||
command: <String>[
|
|
||||||
'sysctl',
|
|
||||||
'hw.optional.arm64',
|
|
||||||
],
|
|
||||||
stdout: 'hw.optional.arm64: 1',
|
|
||||||
),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(xcodeProjectInterpreter.xcrunCommand(), <String>[
|
expect(xcodeProjectInterpreter.xcrunCommand(), <String>[
|
||||||
@ -295,7 +301,7 @@ void main() {
|
|||||||
|
|
||||||
fakeProcessManager.addCommands(<FakeCommand>[
|
fakeProcessManager.addCommands(<FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'xcrun',
|
'xcrun',
|
||||||
@ -329,7 +335,7 @@ void main() {
|
|||||||
|
|
||||||
fakeProcessManager.addCommands(<FakeCommand>[
|
fakeProcessManager.addCommands(<FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'xcrun',
|
'xcrun',
|
||||||
@ -358,7 +364,7 @@ void main() {
|
|||||||
};
|
};
|
||||||
fakeProcessManager.addCommands(<FakeCommand>[
|
fakeProcessManager.addCommands(<FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'xcrun',
|
'xcrun',
|
||||||
@ -391,7 +397,7 @@ void main() {
|
|||||||
|
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>[
|
command: <String>[
|
||||||
'xcrun',
|
'xcrun',
|
||||||
@ -416,7 +422,7 @@ void main() {
|
|||||||
const String workingDirectory = '/';
|
const String workingDirectory = '/';
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-list'],
|
command: <String>['xcrun', 'xcodebuild', '-list'],
|
||||||
),
|
),
|
||||||
@ -440,7 +446,7 @@ void main() {
|
|||||||
|
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-list'],
|
command: <String>['xcrun', 'xcodebuild', '-list'],
|
||||||
exitCode: 66,
|
exitCode: 66,
|
||||||
@ -466,7 +472,7 @@ void main() {
|
|||||||
|
|
||||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||||
kWhichSysctlCommand,
|
kWhichSysctlCommand,
|
||||||
kARMCheckCommand,
|
kx64CheckCommand,
|
||||||
FakeCommand(
|
FakeCommand(
|
||||||
command: <String>['xcrun', 'xcodebuild', '-list'],
|
command: <String>['xcrun', 'xcodebuild', '-list'],
|
||||||
exitCode: 74,
|
exitCode: 74,
|
||||||
@ -676,10 +682,171 @@ Information about project "Runner":
|
|||||||
fs.file(xcodebuild).createSync(recursive: true);
|
fs.file(xcodebuild).createSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('arm simulator', () {
|
||||||
|
FakeProcessManager fakeProcessManager;
|
||||||
|
XcodeProjectInterpreter xcodeProjectInterpreter;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
fakeProcessManager = FakeProcessManager.empty();
|
||||||
|
xcodeProjectInterpreter = XcodeProjectInterpreter.test(processManager: fakeProcessManager);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('does not exclude arm64 simulator when supported by all plugins', () async {
|
||||||
|
const BuildInfo buildInfo = BuildInfo.debug;
|
||||||
|
final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
|
||||||
|
final Directory podXcodeProject = project.ios.hostAppRoot.childDirectory('Pods').childDirectory('Pods.xcodeproj')
|
||||||
|
..createSync(recursive: true);
|
||||||
|
|
||||||
|
fakeProcessManager.addCommands(<FakeCommand>[
|
||||||
|
kWhichSysctlCommand,
|
||||||
|
kARMCheckCommand,
|
||||||
|
FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'/usr/bin/arch',
|
||||||
|
'-arm64e',
|
||||||
|
'xcrun',
|
||||||
|
'xcodebuild',
|
||||||
|
'-alltargets',
|
||||||
|
'-sdk',
|
||||||
|
'iphonesimulator',
|
||||||
|
'-project',
|
||||||
|
podXcodeProject.path,
|
||||||
|
'-showBuildSettings',
|
||||||
|
],
|
||||||
|
stdout: '''
|
||||||
|
Build settings for action build and target plugin1:
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
EXCLUDED_ARCHS = i386;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
UNRELATED_BUILD_SETTING = arm64;
|
||||||
|
|
||||||
|
Build settings for action build and target plugin2:
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
EXCLUDED_ARCHS = i386;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
UNRELATED_BUILD_SETTING = arm64;
|
||||||
|
'''
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
await updateGeneratedXcodeProperties(
|
||||||
|
project: project,
|
||||||
|
buildInfo: buildInfo,
|
||||||
|
);
|
||||||
|
|
||||||
|
final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
|
||||||
|
expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386\n'));
|
||||||
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
Artifacts: () => localArtifacts,
|
||||||
|
Platform: () => macOS,
|
||||||
|
OperatingSystemUtils: () => FakeOperatingSystemUtils(hostPlatform: HostPlatform.darwin_arm),
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => fakeProcessManager,
|
||||||
|
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('excludes arm64 simulator when build setting fetch fails', () async {
|
||||||
|
const BuildInfo buildInfo = BuildInfo.debug;
|
||||||
|
final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
|
||||||
|
final Directory podXcodeProject = project.ios.hostAppRoot.childDirectory('Pods').childDirectory('Pods.xcodeproj')
|
||||||
|
..createSync(recursive: true);
|
||||||
|
|
||||||
|
fakeProcessManager.addCommands(<FakeCommand>[
|
||||||
|
kWhichSysctlCommand,
|
||||||
|
kARMCheckCommand,
|
||||||
|
FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'/usr/bin/arch',
|
||||||
|
'-arm64e',
|
||||||
|
'xcrun',
|
||||||
|
'xcodebuild',
|
||||||
|
'-alltargets',
|
||||||
|
'-sdk',
|
||||||
|
'iphonesimulator',
|
||||||
|
'-project',
|
||||||
|
podXcodeProject.path,
|
||||||
|
'-showBuildSettings',
|
||||||
|
],
|
||||||
|
exitCode: 1,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
await updateGeneratedXcodeProperties(
|
||||||
|
project: project,
|
||||||
|
buildInfo: buildInfo,
|
||||||
|
);
|
||||||
|
|
||||||
|
final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
|
||||||
|
expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 arm64\n'));
|
||||||
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
Artifacts: () => localArtifacts,
|
||||||
|
Platform: () => macOS,
|
||||||
|
OperatingSystemUtils: () => FakeOperatingSystemUtils(hostPlatform: HostPlatform.darwin_arm),
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => fakeProcessManager,
|
||||||
|
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('excludes arm64 simulator when unsupported by plugins', () async {
|
||||||
|
const BuildInfo buildInfo = BuildInfo.debug;
|
||||||
|
final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
|
||||||
|
final Directory podXcodeProject = project.ios.hostAppRoot.childDirectory('Pods').childDirectory('Pods.xcodeproj')
|
||||||
|
..createSync(recursive: true);
|
||||||
|
|
||||||
|
fakeProcessManager.addCommands(<FakeCommand>[
|
||||||
|
kWhichSysctlCommand,
|
||||||
|
kARMCheckCommand,
|
||||||
|
FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'/usr/bin/arch',
|
||||||
|
'-arm64e',
|
||||||
|
'xcrun',
|
||||||
|
'xcodebuild',
|
||||||
|
'-alltargets',
|
||||||
|
'-sdk',
|
||||||
|
'iphonesimulator',
|
||||||
|
'-project',
|
||||||
|
podXcodeProject.path,
|
||||||
|
'-showBuildSettings',
|
||||||
|
],
|
||||||
|
stdout: '''
|
||||||
|
Build settings for action build and target plugin1:
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
EXCLUDED_ARCHS = i386;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
UNRELATED_BUILD_SETTING = arm64;
|
||||||
|
|
||||||
|
Build settings for action build and target plugin2:
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
EXCLUDED_ARCHS = i386 arm64;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
UNRELATED_BUILD_SETTING = arm64;
|
||||||
|
'''
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
await updateGeneratedXcodeProperties(
|
||||||
|
project: project,
|
||||||
|
buildInfo: buildInfo,
|
||||||
|
);
|
||||||
|
|
||||||
|
final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
|
||||||
|
expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 arm64\n'));
|
||||||
|
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
Artifacts: () => localArtifacts,
|
||||||
|
Platform: () => macOS,
|
||||||
|
OperatingSystemUtils: () => FakeOperatingSystemUtils(hostPlatform: HostPlatform.darwin_arm),
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => fakeProcessManager,
|
||||||
|
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
void testUsingOsxContext(String description, dynamic Function() testMethod) {
|
void testUsingOsxContext(String description, dynamic Function() testMethod) {
|
||||||
testUsingContext(description, testMethod, overrides: <Type, Generator>{
|
testUsingContext(description, testMethod, overrides: <Type, Generator>{
|
||||||
Artifacts: () => localArtifacts,
|
Artifacts: () => localArtifacts,
|
||||||
Platform: () => macOS,
|
Platform: () => macOS,
|
||||||
|
OperatingSystemUtils: () => FakeOperatingSystemUtils(hostPlatform: HostPlatform.darwin_x64),
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
});
|
});
|
||||||
@ -708,6 +875,21 @@ Information about project "Runner":
|
|||||||
expect(buildPhaseScriptContents.contains('EXCLUDED_ARCHS'), isFalse);
|
expect(buildPhaseScriptContents.contains('EXCLUDED_ARCHS'), isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingOsxContext('excludes i386 simulator', () async {
|
||||||
|
const BuildInfo buildInfo = BuildInfo.debug;
|
||||||
|
final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
|
||||||
|
await updateGeneratedXcodeProperties(
|
||||||
|
project: project,
|
||||||
|
buildInfo: buildInfo,
|
||||||
|
);
|
||||||
|
|
||||||
|
final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
|
||||||
|
expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386\n'));
|
||||||
|
|
||||||
|
final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
|
||||||
|
expect(buildPhaseScript.readAsStringSync(), isNot(contains('EXCLUDED_ARCHS')));
|
||||||
|
});
|
||||||
|
|
||||||
testUsingOsxContext('sets TRACK_WIDGET_CREATION=true when trackWidgetCreation is true', () async {
|
testUsingOsxContext('sets TRACK_WIDGET_CREATION=true when trackWidgetCreation is true', () async {
|
||||||
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true, treeShakeIcons: false);
|
const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true, treeShakeIcons: false);
|
||||||
final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
|
final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
|
||||||
|
@ -306,6 +306,14 @@ class FakeXcodeProjectInterpreter implements XcodeProjectInterpreter {
|
|||||||
return <String, String>{};
|
return <String, String>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> pluginsBuildSettingsOutput(
|
||||||
|
Directory podXcodeProject, {
|
||||||
|
Duration timeout = const Duration(minutes: 1),
|
||||||
|
}) async {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> cleanWorkspace(String workspacePath, String scheme, { bool verbose = false }) {
|
Future<void> cleanWorkspace(String workspacePath, String scheme, { bool verbose = false }) {
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user