From 8876bccf3ab8cbdd8cb65a53f911ca658830209d Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 6 Mar 2025 20:14:08 +0000 Subject: [PATCH] Use separate artifacts for arm64 and x64 versions of gen_snapshot on Apple platforms (#164419) Fixes https://github.com/flutter/flutter/issues/156175 --- packages/flutter_tools/lib/src/artifacts.dart | 27 ++++++++++++++++--- .../flutter_tools/lib/src/base/build.dart | 14 ++++++---- .../test/general.shard/base/build_test.dart | 16 +++++------ .../build_system/targets/common_test.dart | 2 +- .../build_system/targets/macos_test.dart | 4 +-- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart index 6ae0d666ce..a9fead5599 100644 --- a/packages/flutter_tools/lib/src/artifacts.dart +++ b/packages/flutter_tools/lib/src/artifacts.dart @@ -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 clangDirs = [ '.', '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: diff --git a/packages/flutter_tools/lib/src/base/build.dart b/packages/flutter_tools/lib/src/base/build.dart index 790cec98bc..b61d936ec8 100644 --- a/packages/flutter_tools/lib/src/base/build.dart +++ b/packages/flutter_tools/lib/src/base/build.dart @@ -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 args = [...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([ snapshotterPath, ...args, diff --git a/packages/flutter_tools/test/general.shard/base/build_test.dart b/packages/flutter_tools/test/general.shard/base/build_test.dart index 6d5b052906..c36835b6df 100644 --- a/packages/flutter_tools/test/general.shard/base/build_test.dart +++ b/packages/flutter_tools/test/general.shard/base/build_test.dart @@ -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: ['${genSnapshotPath}_arm64', '--additional_arg']), + FakeCommand(command: [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( command: [ - '${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( command: [ - '${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( command: [ - '${genSnapshotPath}_arm64', + genSnapshotPath, '--deterministic', '--snapshot_kind=app-aot-assembly', '--assembly=${fileSystem.path.join(outputPath, 'snapshot_assembly.S')}', diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart index 2d7ebfcdf8..8ceab06877 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/common_test.dart @@ -794,7 +794,7 @@ void main() { FakeCommand( command: [ // 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', diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart index f23664832d..98eafe5058 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/macos_test.dart @@ -813,7 +813,7 @@ void main() { processManager.addCommands([ FakeCommand( command: [ - '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: [ - '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}',