Skip to content

Commit 05226d2

Browse files
authored
Reland: [flutter_tool] Fuchsia AOT builds (flutter#45350)
* Reland: [flutter_tool] Fuchsia AOT builds * Fixes
1 parent 785e557 commit 05226d2

16 files changed

+267
-133
lines changed

packages/flutter_tools/lib/src/artifacts.dart

+22-19
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ enum Artifact {
6161

6262
// Fuchsia artifacts from the engine prebuilts.
6363
fuchsiaKernelCompiler,
64-
fuchsiaFlutterJitRunner,
64+
fuchsiaFlutterRunner,
6565
}
6666

6767
String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMode mode ]) {
@@ -136,11 +136,10 @@ String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMo
136136
return 'flutter_ddc_sdk.dill';
137137
case Artifact.fuchsiaKernelCompiler:
138138
return 'kernel_compiler.snapshot';
139-
case Artifact.fuchsiaFlutterJitRunner:
140-
if (mode == BuildMode.debug || mode == BuildMode.profile) {
141-
return 'flutter_jit_runner-0.far';
142-
}
143-
return 'flutter_jit_product_runner-0.far';
139+
case Artifact.fuchsiaFlutterRunner:
140+
final String jitOrAot = mode.isJit ? '_jit' : '_aot';
141+
final String productOrNo = mode.isRelease ? '_product' : '';
142+
return 'flutter$jitOrAot${productOrNo}_runner-0.far';
144143
}
145144
assert(false, 'Invalid artifact $artifact.');
146145
return null;
@@ -278,21 +277,25 @@ class CachedArtifacts extends Artifacts {
278277
cache.getArtifactDirectory('flutter_runner').path,
279278
'flutter',
280279
fuchsiaArchForTargetPlatform(platform),
281-
getNameForBuildMode(mode),
280+
mode.isRelease ? 'release' : mode.toString(),
282281
);
282+
final String runtime = mode.isJit ? 'jit' : 'aot';
283283
switch (artifact) {
284+
case Artifact.genSnapshot:
285+
final String genSnapshot = mode.isRelease ? 'gen_snapshot_product' : 'gen_snapshot';
286+
return fs.path.join(root, runtime, 'dart_binaries', genSnapshot);
284287
case Artifact.flutterPatchedSdkPath:
285288
const String artifactFileName = 'flutter_runner_patched_sdk';
286-
return fs.path.join(root, 'jit', artifactFileName);
289+
return fs.path.join(root, runtime, artifactFileName);
287290
case Artifact.platformKernelDill:
288291
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
289-
return fs.path.join(root, 'jit', 'flutter_runner_patched_sdk', artifactFileName);
292+
return fs.path.join(root, runtime, 'flutter_runner_patched_sdk', artifactFileName);
290293
case Artifact.fuchsiaKernelCompiler:
291294
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
292-
return fs.path.join(root, 'jit', 'dart_binaries', artifactFileName);
293-
case Artifact.fuchsiaFlutterJitRunner:
295+
return fs.path.join(root, runtime, 'dart_binaries', artifactFileName);
296+
case Artifact.fuchsiaFlutterRunner:
294297
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
295-
return fs.path.join(root, 'jit', artifactFileName);
298+
return fs.path.join(root, runtime, artifactFileName);
296299
default:
297300
return _getHostArtifactPath(artifact, platform, mode);
298301
}
@@ -413,7 +416,7 @@ class LocalEngineArtifacts extends Artifacts {
413416
@override
414417
String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
415418
platform ??= _currentHostPlatform;
416-
final String artifactFileName = _artifactToFileName(artifact, platform);
419+
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
417420
switch (artifact) {
418421
case Artifact.snapshotDart:
419422
return fs.path.join(_engineSrcPath, 'flutter', 'lib', 'snapshot', artifactFileName);
@@ -482,13 +485,13 @@ class LocalEngineArtifacts extends Artifacts {
482485
return fs.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
483486
case Artifact.fuchsiaKernelCompiler:
484487
final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
485-
final String dartBinaries = 'dart_binaries-$mode-$hostPlatform';
488+
final String modeName = mode.isRelease ? 'release' : mode.toString();
489+
final String dartBinaries = 'dart_binaries-$modeName-$hostPlatform';
486490
return fs.path.join(engineOutPath, 'host_bundle', dartBinaries, 'kernel_compiler.dart.snapshot');
487-
case Artifact.fuchsiaFlutterJitRunner:
488-
if (mode == BuildMode.debug || mode == BuildMode.profile) {
489-
return fs.path.join(engineOutPath, 'flutter_jit_runner-0.far');
490-
}
491-
return fs.path.join(engineOutPath, 'flutter_jit_product_runner-0.far');
491+
case Artifact.fuchsiaFlutterRunner:
492+
final String jitOrAot = mode.isJit ? '_jit' : '_aot';
493+
final String productOrNo = mode.isRelease ? '_product' : '';
494+
return fs.path.join(engineOutPath, 'flutter$jitOrAot${productOrNo}_runner-0.far');
492495
}
493496
assert(false, 'Invalid artifact $artifact.');
494497
return null;

packages/flutter_tools/lib/src/build_info.dart

+11-2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class BuildInfo {
5959

6060
static const BuildInfo debug = BuildInfo(BuildMode.debug, null);
6161
static const BuildInfo profile = BuildInfo(BuildMode.profile, null);
62+
static const BuildInfo jitRelease = BuildInfo(BuildMode.jitRelease, null);
6263
static const BuildInfo release = BuildInfo(BuildMode.release, null);
6364

6465
/// Returns whether a debug build is requested.
@@ -68,14 +69,22 @@ class BuildInfo {
6869

6970
/// Returns whether a profile build is requested.
7071
///
71-
/// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
72+
/// Exactly one of [isDebug], [isProfile], [isJitRelease],
73+
/// or [isRelease] is true.
7274
bool get isProfile => mode == BuildMode.profile;
7375

7476
/// Returns whether a release build is requested.
7577
///
76-
/// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
78+
/// Exactly one of [isDebug], [isProfile], [isJitRelease],
79+
/// or [isRelease] is true.
7780
bool get isRelease => mode == BuildMode.release;
7881

82+
/// Returns whether a JIT release build is requested.
83+
///
84+
/// Exactly one of [isDebug], [isProfile], [isJitRelease],
85+
/// or [isRelease] is true.
86+
bool get isJitRelease => mode == BuildMode.jitRelease;
87+
7988
bool get usesAot => isAotBuildMode(mode);
8089
bool get supportsEmulator => isEmulatorBuildMode(mode);
8190
bool get supportsSimulator => isEmulatorBuildMode(mode);

packages/flutter_tools/lib/src/commands/attach.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class AttachCommand extends FlutterCommand {
214214
if (module == null) {
215215
throwToolExit('\'--module\' is required for attaching to a Fuchsia device');
216216
}
217-
usesIpv6 = device.ipv6;
217+
usesIpv6 = await device.ipv6;
218218
FuchsiaIsolateDiscoveryProtocol isolateDiscoveryProtocol;
219219
try {
220220
isolateDiscoveryProtocol = device.getIsolateDiscoveryProtocol(module);

packages/flutter_tools/lib/src/commands/build.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class BuildCommand extends FlutterCommand {
2929
addSubcommand(BuildIOSFrameworkCommand());
3030
addSubcommand(BuildBundleCommand(verboseHelp: verboseHelp));
3131
addSubcommand(BuildWebCommand());
32-
addSubcommand(BuildMacosCommand(verboseHelp: verboseHelp));
32+
addSubcommand(BuildMacosCommand());
3333
addSubcommand(BuildLinuxCommand());
3434
addSubcommand(BuildWindowsCommand());
3535
addSubcommand(BuildFuchsiaCommand(verboseHelp: verboseHelp));

packages/flutter_tools/lib/src/commands/build_fuchsia.dart

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class BuildFuchsiaCommand extends BuildSubCommand {
3131
],
3232
defaultsTo: FuchsiaPackageServer.toolHost,
3333
);
34+
argParser.addOption('target-platform',
35+
defaultsTo: 'fuchsia-x64',
36+
allowed: <String>['fuchsia-arm64', 'fuchsia-x64'],
37+
help: 'The target platform for which the app is compiled.',
38+
);
3439
}
3540

3641
@override
@@ -69,6 +74,7 @@ class BuildFuchsiaCommand extends BuildSubCommand {
6974
await buildFuchsia(
7075
fuchsiaProject: flutterProject.fuchsia,
7176
target: targetFile,
77+
targetPlatform: getTargetPlatformForName(argResults['target-platform']),
7278
buildInfo: buildInfo,
7379
runnerPackageSource: stringArg('runner-source'),
7480
);

packages/flutter_tools/lib/src/commands/build_ios.dart

+1-12
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,13 @@ import 'build.dart';
1919
/// .ipas, see https://flutter.dev/docs/deployment/ios.
2020
class BuildIOSCommand extends BuildSubCommand {
2121
BuildIOSCommand() {
22+
addBuildModeFlags(defaultToRelease: false);
2223
usesTargetOption();
2324
usesFlavorOption();
2425
usesPubOption();
2526
usesBuildNumberOption();
2627
usesBuildNameOption();
2728
argParser
28-
..addFlag('debug',
29-
negatable: false,
30-
help: 'Build a debug version of your app (default mode for iOS simulator builds).',
31-
)
32-
..addFlag('profile',
33-
negatable: false,
34-
help: 'Build a version of your app specialized for performance profiling.',
35-
)
36-
..addFlag('release',
37-
negatable: false,
38-
help: 'Build a release version of your app (default mode for device builds).',
39-
)
4029
..addFlag('simulator',
4130
help: 'Build for the iOS simulator instead of the device.',
4231
)

packages/flutter_tools/lib/src/commands/build_linux.dart

+1-12
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,8 @@ import 'build.dart';
1717
/// A command to build a linux desktop target through a build shell script.
1818
class BuildLinuxCommand extends BuildSubCommand {
1919
BuildLinuxCommand() {
20+
addBuildModeFlags();
2021
usesTargetOption();
21-
argParser.addFlag('debug',
22-
negatable: false,
23-
help: 'Build a debug version of your app.',
24-
);
25-
argParser.addFlag('profile',
26-
negatable: false,
27-
help: 'Build a version of your app specialized for performance profiling.',
28-
);
29-
argParser.addFlag('release',
30-
negatable: false,
31-
help: 'Build a version of your app specialized for performance profiling.',
32-
);
3322
}
3423

3524
@override

packages/flutter_tools/lib/src/commands/build_macos.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import 'build.dart';
1616

1717
/// A command to build a macOS desktop target through a build shell script.
1818
class BuildMacosCommand extends BuildSubCommand {
19-
BuildMacosCommand({bool verboseHelp}) {
19+
BuildMacosCommand() {
2020
usesTargetOption();
21-
addBuildModeFlags(verboseHelp: verboseHelp);
21+
addBuildModeFlags();
2222
}
2323

2424
@override

packages/flutter_tools/lib/src/commands/build_windows.dart

+1-12
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,8 @@ import 'build.dart';
1717
/// A command to build a windows desktop target through a build shell script.
1818
class BuildWindowsCommand extends BuildSubCommand {
1919
BuildWindowsCommand() {
20+
addBuildModeFlags();
2021
usesTargetOption();
21-
argParser.addFlag('debug',
22-
negatable: false,
23-
help: 'Build a debug version of your app.',
24-
);
25-
argParser.addFlag('profile',
26-
negatable: false,
27-
help: 'Build a version of your app specialized for performance profiling.',
28-
);
29-
argParser.addFlag('release',
30-
negatable: false,
31-
help: 'Build a version of your app specialized for performance profiling.',
32-
);
3322
}
3423

3524
@override

packages/flutter_tools/lib/src/commands/run.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ class RunCommand extends RunCommandBase {
295295

296296
DebuggingOptions _createDebuggingOptions() {
297297
final BuildInfo buildInfo = getBuildInfo();
298-
if (buildInfo.isRelease) {
298+
if (buildInfo.mode.isRelease) {
299299
return DebuggingOptions.disabled(
300300
buildInfo,
301301
initializePlatform: boolArg('web-initialize-platform'),

packages/flutter_tools/lib/src/fuchsia/fuchsia_build.dart

+87-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ import 'dart:async';
66

77
import 'package:meta/meta.dart';
88

9+
import '../artifacts.dart';
910
import '../asset.dart';
1011
import '../base/common.dart';
1112
import '../base/file_system.dart';
1213
import '../base/io.dart';
14+
import '../base/logger.dart';
15+
import '../base/process.dart';
1316
import '../base/utils.dart';
1417
import '../build_info.dart';
1518
import '../bundle.dart';
@@ -37,6 +40,7 @@ Future<void> _timedBuildStep(String name, Future<void> Function() action) async
3740
// Fuchsia package.
3841
Future<void> buildFuchsia({
3942
@required FuchsiaProject fuchsiaProject,
43+
@required TargetPlatform targetPlatform,
4044
@required String target, // E.g., lib/main.dart
4145
BuildInfo buildInfo = BuildInfo.debug,
4246
String runnerPackageSource = FuchsiaPackageServer.toolHost,
@@ -49,12 +53,66 @@ Future<void> buildFuchsia({
4953
await _timedBuildStep('fuchsia-kernel-compile',
5054
() => fuchsiaSdk.fuchsiaKernelCompiler.build(
5155
fuchsiaProject: fuchsiaProject, target: target, buildInfo: buildInfo));
56+
57+
if (buildInfo.usesAot) {
58+
await _timedBuildStep('fuchsia-gen-snapshot',
59+
() => _genSnapshot(fuchsiaProject, target, buildInfo, targetPlatform));
60+
}
61+
5262
await _timedBuildStep('fuchsia-build-assets',
5363
() => _buildAssets(fuchsiaProject, target, buildInfo));
5464
await _timedBuildStep('fuchsia-build-package',
5565
() => _buildPackage(fuchsiaProject, target, buildInfo, runnerPackageSource));
5666
}
5767

68+
Future<void> _genSnapshot(
69+
FuchsiaProject fuchsiaProject,
70+
String target, // lib/main.dart
71+
BuildInfo buildInfo,
72+
TargetPlatform targetPlatform,
73+
) async {
74+
final String outDir = getFuchsiaBuildDirectory();
75+
final String appName = fuchsiaProject.project.manifest.appName;
76+
final String dilPath = fs.path.join(outDir, '$appName.dil');
77+
78+
final String vmSnapshotData = fs.path.join(outDir, 'vm_data.aotsnapshot');
79+
final String vmSnapshotInstructions = fs.path.join(outDir, 'vm_instructions.aotsnapshot');
80+
final String snapshotData = fs.path.join(outDir, 'data.aotsnapshot');
81+
final String snapshotInstructions = fs.path.join(outDir, 'instructions.aotsnapshot');
82+
83+
final String genSnapshot = artifacts.getArtifactPath(
84+
Artifact.genSnapshot,
85+
platform: targetPlatform,
86+
mode: buildInfo.mode,
87+
);
88+
89+
final List<String> command = <String>[
90+
genSnapshot,
91+
'--no_causal_async_stacks',
92+
'--deterministic',
93+
'--snapshot_kind=app-aot-blobs',
94+
'--vm_snapshot_data=$vmSnapshotData',
95+
'--vm_snapshot_instructions=$vmSnapshotInstructions',
96+
'--isolate_snapshot_data=$snapshotData',
97+
'--isolate_snapshot_instructions=$snapshotInstructions',
98+
if (buildInfo.isDebug) '--enable-asserts',
99+
dilPath,
100+
];
101+
int result;
102+
final Status status = logger.startProgress(
103+
'Compiling Fuchsia application to native code...',
104+
timeout: null,
105+
);
106+
try {
107+
result = await processUtils.stream(command, trace: true);
108+
} finally {
109+
status.cancel();
110+
}
111+
if (result != 0) {
112+
throwToolExit('Build process failed');
113+
}
114+
}
115+
58116
Future<void> _buildAssets(
59117
FuchsiaProject fuchsiaProject,
60118
String target, // lib/main.dart
@@ -98,12 +156,17 @@ void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst)
98156
String runner;
99157
switch (mode) {
100158
case BuildMode.debug:
101-
case BuildMode.profile:
102159
runner = 'flutter_jit_runner';
103160
break;
104-
case BuildMode.release:
161+
case BuildMode.profile:
162+
runner = 'flutter_aot_runner';
163+
break;
164+
case BuildMode.jitRelease:
105165
runner = 'flutter_jit_product_runner';
106166
break;
167+
case BuildMode.release:
168+
runner = 'flutter_aot_product_runner';
169+
break;
107170
default:
108171
throwToolExit('Fuchsia does not support build mode "$mode"');
109172
break;
@@ -122,7 +185,6 @@ Future<void> _buildPackage(
122185
final String outDir = getFuchsiaBuildDirectory();
123186
final String pkgDir = fs.path.join(outDir, 'pkg');
124187
final String appName = fuchsiaProject.project.manifest.appName;
125-
final String dilpmanifest = fs.path.join(outDir, '$appName.dilpmanifest');
126188
final String pkgassets = fs.path.join(outDir, '${appName}_pkgassets');
127189
final String packageManifest = fs.path.join(pkgDir, 'package_manifest');
128190
final String devKeyPath = fs.path.join(pkgDir, 'development.key');
@@ -137,9 +199,29 @@ Future<void> _buildPackage(
137199
final File dstCmx = fs.file(fs.path.join(outDir, '$appName.cmx'));
138200
_rewriteCmx(buildInfo.mode, runnerPackageSource, srcCmx, dstCmx);
139201

140-
// Concatenate dilpmanifest and pkgassets into package_manifest.
141202
final File manifestFile = fs.file(packageManifest);
142-
manifestFile.writeAsStringSync(fs.file(dilpmanifest).readAsStringSync());
203+
204+
if (buildInfo.usesAot) {
205+
final String vmSnapshotData = fs.path.join(outDir, 'vm_data.aotsnapshot');
206+
final String vmSnapshotInstructions = fs.path.join(outDir, 'vm_instructions.aotsnapshot');
207+
final String snapshotData = fs.path.join(outDir, 'data.aotsnapshot');
208+
final String snapshotInstructions = fs.path.join(outDir, 'instructions.aotsnapshot');
209+
manifestFile.writeAsStringSync(
210+
'data/$appName/vm_snapshot_data.bin=$vmSnapshotData\n');
211+
manifestFile.writeAsStringSync(
212+
'data/$appName/vm_snapshot_instructions.bin=$vmSnapshotInstructions\n',
213+
mode: FileMode.append);
214+
manifestFile.writeAsStringSync(
215+
'data/$appName/isolate_snapshot_data.bin=$snapshotData\n',
216+
mode: FileMode.append);
217+
manifestFile.writeAsStringSync(
218+
'data/$appName/isolate_snapshot_instructions.bin=$snapshotInstructions\n',
219+
mode: FileMode.append);
220+
} else {
221+
final String dilpmanifest = fs.path.join(outDir, '$appName.dilpmanifest');
222+
manifestFile.writeAsStringSync(fs.file(dilpmanifest).readAsStringSync());
223+
}
224+
143225
manifestFile.writeAsStringSync(fs.file(pkgassets).readAsStringSync(),
144226
mode: FileMode.append);
145227
manifestFile.writeAsStringSync('meta/$appName.cmx=${dstCmx.path}\n',

0 commit comments

Comments
 (0)