Use separate artifacts for arm64 and x64 versions of gen_snapshot on Apple platforms (#164419)

Fixes https://github.com/flutter/flutter/issues/156175
This commit is contained in:
Jason Simmons 2025-03-06 20:14:08 +00:00 committed by GitHub
parent 50f6b48e85
commit 8876bccf3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 44 additions and 19 deletions

View File

@ -29,6 +29,8 @@ import 'globals.dart' as globals;
enum Artifact {
/// The tool which compiles a dart kernel file into native code.
genSnapshot,
genSnapshotArm64,
genSnapshotX64,
/// The flutter tester binary.
flutterTester,
@ -173,6 +175,10 @@ String? _artifactToFileName(Artifact artifact, Platform hostPlatform, [BuildMode
switch (artifact) {
case Artifact.genSnapshot:
return 'gen_snapshot';
case Artifact.genSnapshotArm64:
return 'gen_snapshot_arm64';
case Artifact.genSnapshotX64:
return 'gen_snapshot_x64';
case Artifact.flutterTester:
return 'flutter_tester$exe';
case Artifact.flutterFramework:
@ -543,6 +549,8 @@ class CachedArtifacts implements Artifacts {
final String engineDir = _getEngineArtifactsPath(platform, mode)!;
switch (artifact) {
case Artifact.genSnapshot:
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
return _fileSystem.path.join(engineDir, _artifactToFileName(artifact, _platform));
case Artifact.engineDartSdkPath:
case Artifact.engineDartBinary:
@ -581,6 +589,8 @@ class CachedArtifacts implements Artifacts {
final String engineDir = _getEngineArtifactsPath(platform, mode)!;
switch (artifact) {
case Artifact.genSnapshot:
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
// TODO(cbracken): Build Android gen_snapshot as Arm64 binary to run
@ -636,6 +646,8 @@ class CachedArtifacts implements Artifacts {
) {
switch (artifact) {
case Artifact.genSnapshot:
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
case Artifact.flutterXcframework:
final String artifactFileName = _artifactToFileName(artifact, _platform)!;
final String engineDir = _getEngineArtifactsPath(platform, mode)!;
@ -686,6 +698,9 @@ class CachedArtifacts implements Artifacts {
case Artifact.genSnapshot:
final String genSnapshot = mode.isRelease ? 'gen_snapshot_product' : 'gen_snapshot';
return _fileSystem.path.join(root, runtime, 'dart_binaries', genSnapshot);
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
throw ArgumentError('$artifact is not available on this platform');
case Artifact.flutterPatchedSdkPath:
const String artifactFileName = 'flutter_runner_patched_sdk';
return _fileSystem.path.join(root, runtime, artifactFileName);
@ -741,6 +756,8 @@ class CachedArtifacts implements Artifacts {
String _getHostArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode? mode) {
switch (artifact) {
case Artifact.genSnapshot:
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
// For script snapshots any gen_snapshot binary will do. Returning gen_snapshot for
// android_arm in profile mode because it is available on all supported host platforms.
return _getAndroidArtifactPath(artifact, TargetPlatform.android_arm, BuildMode.profile);
@ -1178,7 +1195,9 @@ class CachedLocalEngineArtifacts implements Artifacts {
isDirectoryArtifact ? null : _artifactToFileName(artifact, _platform, mode);
switch (artifact) {
case Artifact.genSnapshot:
return _genSnapshotPath();
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
return _genSnapshotPath(artifact);
case Artifact.flutterTester:
return _flutterTesterPath(platform!);
case Artifact.isolateSnapshotData:
@ -1344,7 +1363,7 @@ class CachedLocalEngineArtifacts implements Artifacts {
return _fileSystem.path.join(localEngineInfo.targetOutPath, 'flutter_web_sdk');
}
String _genSnapshotPath() {
String _genSnapshotPath(Artifact artifact) {
const List<String> clangDirs = <String>[
'.',
'clang_x64',
@ -1352,7 +1371,7 @@ class CachedLocalEngineArtifacts implements Artifacts {
'clang_i386',
'clang_arm64',
];
final String genSnapshotName = _artifactToFileName(Artifact.genSnapshot, _platform)!;
final String genSnapshotName = _artifactToFileName(artifact, _platform)!;
for (final String clangDir in clangDirs) {
final String genSnapshotPath = _fileSystem.path.join(
localEngineInfo.targetOutPath,
@ -1422,6 +1441,8 @@ class CachedLocalWebSdkArtifacts implements Artifacts {
_artifactToFileName(artifact, _platform, mode),
);
case Artifact.genSnapshot:
case Artifact.genSnapshotArm64:
case Artifact.genSnapshotX64:
case Artifact.flutterTester:
case Artifact.flutterFramework:
case Artifact.flutterFrameworkDsym:

View File

@ -35,9 +35,9 @@ class GenSnapshot {
final Artifacts _artifacts;
final ProcessUtils _processUtils;
String getSnapshotterPath(SnapshotType snapshotType) {
String getSnapshotterPath(SnapshotType snapshotType, Artifact artifact) {
return _artifacts.getArtifactPath(
Artifact.genSnapshot,
artifact,
platform: snapshotType.platform,
mode: snapshotType.mode,
);
@ -63,16 +63,20 @@ class GenSnapshot {
assert(snapshotType.platform != TargetPlatform.ios || darwinArch != null);
final List<String> args = <String>[...additionalArgs];
String snapshotterPath = getSnapshotterPath(snapshotType);
// iOS and macOS have separate gen_snapshot binaries for each target
// architecture (iOS: armv7, arm64; macOS: x86_64, arm64). Select the right
// one for the target architecture in question.
Artifact genSnapshotArtifact;
if (snapshotType.platform == TargetPlatform.ios ||
snapshotType.platform == TargetPlatform.darwin) {
snapshotterPath += '_${darwinArch!.dartName}';
genSnapshotArtifact =
darwinArch == DarwinArch.arm64 ? Artifact.genSnapshotArm64 : Artifact.genSnapshotX64;
} else {
genSnapshotArtifact = Artifact.genSnapshot;
}
final String snapshotterPath = getSnapshotterPath(snapshotType, genSnapshotArtifact);
return _processUtils.stream(<String>[
snapshotterPath,
...args,

View File

@ -81,12 +81,12 @@ void main() {
testWithoutContext('iOS arm64', () async {
final String genSnapshotPath = artifacts.getArtifactPath(
Artifact.genSnapshot,
Artifact.genSnapshotArm64,
platform: TargetPlatform.ios,
mode: BuildMode.release,
);
processManager.addCommand(
FakeCommand(command: <String>['${genSnapshotPath}_arm64', '--additional_arg']),
FakeCommand(command: <String>[genSnapshotPath, '--additional_arg']),
);
final int result = await genSnapshot.run(
@ -197,14 +197,14 @@ void main() {
final String assembly = fileSystem.path.join(outputPath, 'snapshot_assembly.S');
final String debugPath = fileSystem.path.join('foo', 'app.ios-arm64.symbols');
final String genSnapshotPath = artifacts.getArtifactPath(
Artifact.genSnapshot,
Artifact.genSnapshotArm64,
platform: TargetPlatform.ios,
mode: BuildMode.profile,
);
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
'${genSnapshotPath}_arm64',
genSnapshotPath,
'--deterministic',
'--snapshot_kind=app-aot-assembly',
'--assembly=$assembly',
@ -272,14 +272,14 @@ void main() {
final String outputPath = fileSystem.path.join('build', 'foo');
final String assembly = fileSystem.path.join(outputPath, 'snapshot_assembly.S');
final String genSnapshotPath = artifacts.getArtifactPath(
Artifact.genSnapshot,
Artifact.genSnapshotArm64,
platform: TargetPlatform.ios,
mode: BuildMode.profile,
);
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
'${genSnapshotPath}_arm64',
genSnapshotPath,
'--deterministic',
'--snapshot_kind=app-aot-assembly',
'--assembly=$assembly',
@ -343,14 +343,14 @@ void main() {
testWithoutContext('builds iOS snapshot', () async {
final String outputPath = fileSystem.path.join('build', 'foo');
final String genSnapshotPath = artifacts.getArtifactPath(
Artifact.genSnapshot,
Artifact.genSnapshotArm64,
platform: TargetPlatform.ios,
mode: BuildMode.release,
);
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
'${genSnapshotPath}_arm64',
genSnapshotPath,
'--deterministic',
'--snapshot_kind=app-aot-assembly',
'--assembly=${fileSystem.path.join(outputPath, 'snapshot_assembly.S')}',

View File

@ -794,7 +794,7 @@ void main() {
FakeCommand(
command: <String>[
// This path is not known by the cache due to the iOS gen_snapshot split.
'Artifact.genSnapshot.TargetPlatform.ios.profile_arm64',
'Artifact.genSnapshotArm64.TargetPlatform.ios.profile',
'--deterministic',
'--write-v8-snapshot-profile-to=code_size_1/snapshot.arm64.json',
'--trace-precompiler-to=code_size_1/trace.arm64.json',

View File

@ -813,7 +813,7 @@ void main() {
processManager.addCommands(<FakeCommand>[
FakeCommand(
command: <String>[
'Artifact.genSnapshot.TargetPlatform.darwin.release_arm64',
'Artifact.genSnapshotArm64.TargetPlatform.darwin.release',
'--deterministic',
'--snapshot_kind=app-aot-assembly',
'--assembly=${environment.buildDir.childFile('arm64/snapshot_assembly.S').path}',
@ -822,7 +822,7 @@ void main() {
),
FakeCommand(
command: <String>[
'Artifact.genSnapshot.TargetPlatform.darwin.release_x64',
'Artifact.genSnapshotX64.TargetPlatform.darwin.release',
'--deterministic',
'--snapshot_kind=app-aot-assembly',
'--assembly=${environment.buildDir.childFile('x86_64/snapshot_assembly.S').path}',