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

View File

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

View File

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

View File

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

View File

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