mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Extract kernel compile from buildAotSnapshot (#17062)
Moves the kernel compile step to the beginning of the AOT build in a separate method. This is pre-factoring for iOS universal builds where the kernel build happens once, but we then snapshot twice: once for armv7 and once for arm64. This also writes dependencies to build/kernel_compile.d rather than build/aot/snapshot.d, since that is immediately overwritten by gen_snapshot.
This commit is contained in:
parent
8860627b63
commit
cdbb2385f1
@ -207,6 +207,52 @@ class Snapshotter {
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/// Compiles a Dart file to kernel.
|
||||
///
|
||||
/// Returns the output kernel file path, or null on failure.
|
||||
Future<String> compileKernel({
|
||||
@required TargetPlatform platform,
|
||||
@required BuildMode buildMode,
|
||||
@required String mainPath,
|
||||
@required String outputPath,
|
||||
List<String> extraFrontEndOptions: const <String>[],
|
||||
}) async {
|
||||
final Directory outputDir = fs.directory(outputPath);
|
||||
outputDir.createSync(recursive: true);
|
||||
|
||||
printTrace('Compiling Dart to kernel: $mainPath');
|
||||
final bool aot = !_isInterpreted(platform, buildMode);
|
||||
final List<String> entryPointsJsonFiles = <String>[];
|
||||
if (aot) {
|
||||
entryPointsJsonFiles.addAll(<String>[
|
||||
artifacts.getArtifactPath(Artifact.entryPointsJson, platform, buildMode),
|
||||
artifacts.getArtifactPath(Artifact.entryPointsExtraJson, platform, buildMode),
|
||||
]);
|
||||
}
|
||||
|
||||
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
|
||||
printTrace('Extra front-end options: $extraFrontEndOptions');
|
||||
|
||||
final String depfilePath = fs.path.join(outputPath, 'kernel_compile.d');
|
||||
final CompilerOutput compilerOutput = await kernelCompiler.compile(
|
||||
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
|
||||
mainPath: mainPath,
|
||||
outputFilePath: fs.path.join(outputPath, 'app.dill'),
|
||||
depFilePath: depfilePath,
|
||||
extraFrontEndOptions: extraFrontEndOptions,
|
||||
linkPlatformKernelIn: true,
|
||||
aot: aot,
|
||||
entryPointsJsonFiles: entryPointsJsonFiles,
|
||||
trackWidgetCreation: false,
|
||||
);
|
||||
|
||||
// Write path to frontend_server, since things need to be re-generated when that changes.
|
||||
final String frontendPath = artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
|
||||
await fs.directory(outputPath).childFile('frontend_server.d').writeAsString('frontend_server.d: $frontendPath\n');
|
||||
|
||||
return compilerOutput?.outputFilename;
|
||||
}
|
||||
|
||||
/// Builds an architecture-specific ahead-of-time compiled snapshot of the specified script.
|
||||
Future<int> buildAotSnapshot({
|
||||
@required TargetPlatform platform,
|
||||
@ -216,7 +262,6 @@ class Snapshotter {
|
||||
@required String outputPath,
|
||||
@required bool previewDart2,
|
||||
@required bool preferSharedLibrary,
|
||||
List<String> extraFrontEndOptions: const <String>[],
|
||||
List<String> extraGenSnapshotOptions: const <String>[],
|
||||
}) async {
|
||||
if (!(platform == TargetPlatform.android_arm ||
|
||||
@ -228,6 +273,7 @@ class Snapshotter {
|
||||
|
||||
final Directory outputDir = fs.directory(outputPath);
|
||||
outputDir.createSync(recursive: true);
|
||||
|
||||
final String vmSnapshotData = fs.path.join(outputDir.path, 'vm_snapshot_data');
|
||||
final String vmSnapshotInstructions = fs.path.join(outputDir.path, 'vm_snapshot_instr');
|
||||
final String isolateSnapshotData = fs.path.join(outputDir.path, 'isolate_snapshot_data');
|
||||
@ -250,15 +296,6 @@ class Snapshotter {
|
||||
final String ioEntryPoints = artifacts.getArtifactPath(Artifact.dartIoEntriesTxt, platform, buildMode);
|
||||
assert(ioEntryPoints != null);
|
||||
|
||||
final bool interpreter = platform == TargetPlatform.ios && buildMode == BuildMode.debug;
|
||||
final List<String> entryPointsJsonFiles = <String>[];
|
||||
if (previewDart2 && !interpreter) {
|
||||
entryPointsJsonFiles.addAll(<String>[
|
||||
artifacts.getArtifactPath(Artifact.entryPointsJson, platform, buildMode),
|
||||
artifacts.getArtifactPath(Artifact.entryPointsExtraJson, platform, buildMode),
|
||||
]);
|
||||
}
|
||||
|
||||
final PackageMap packageMap = new PackageMap(packagesPath);
|
||||
final String packageMapError = packageMap.checkValid();
|
||||
if (packageMapError != null) {
|
||||
@ -278,8 +315,6 @@ class Snapshotter {
|
||||
mainPath,
|
||||
];
|
||||
|
||||
inputPaths.addAll(entryPointsJsonFiles);
|
||||
|
||||
final Set<String> outputPaths = new Set<String>();
|
||||
|
||||
// These paths are used only on iOS.
|
||||
@ -325,14 +360,12 @@ class Snapshotter {
|
||||
'--dependencies=$depfilePath',
|
||||
];
|
||||
|
||||
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
|
||||
printTrace('Extra front-end options: $extraFrontEndOptions');
|
||||
|
||||
if ((extraGenSnapshotOptions != null) && extraGenSnapshotOptions.isNotEmpty) {
|
||||
printTrace('Extra gen-snapshot options: $extraGenSnapshotOptions');
|
||||
genSnapshotArgs.addAll(extraGenSnapshotOptions);
|
||||
}
|
||||
|
||||
final bool interpreter = _isInterpreted(platform, buildMode);
|
||||
if (!interpreter) {
|
||||
genSnapshotArgs.add('--embedder_entry_points_manifest=$vmEntryPoints');
|
||||
genSnapshotArgs.add('--embedder_entry_points_manifest=$ioEntryPoints');
|
||||
@ -347,7 +380,6 @@ class Snapshotter {
|
||||
final String kIsolateSnapshotDataC = fs.path.join(outputDir.path, '$kIsolateSnapshotData.c');
|
||||
final String kVmSnapshotDataO = fs.path.join(outputDir.path, '$kVmSnapshotData.o');
|
||||
final String kIsolateSnapshotDataO = fs.path.join(outputDir.path, '$kIsolateSnapshotData.o');
|
||||
final String kApplicationKernelPath = fs.path.join(getBuildDirectory(), 'app.dill');
|
||||
|
||||
switch (platform) {
|
||||
case TargetPlatform.android_arm:
|
||||
@ -408,36 +440,13 @@ class Snapshotter {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String entrypointPath = mainPath;
|
||||
if (previewDart2) {
|
||||
final CompilerOutput compilerOutput = await kernelCompiler.compile(
|
||||
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
|
||||
mainPath: mainPath,
|
||||
outputFilePath: kApplicationKernelPath,
|
||||
depFilePath: depfilePath,
|
||||
extraFrontEndOptions: extraFrontEndOptions,
|
||||
linkPlatformKernelIn: true,
|
||||
aot: !interpreter,
|
||||
entryPointsJsonFiles: entryPointsJsonFiles,
|
||||
trackWidgetCreation: false,
|
||||
);
|
||||
entrypointPath = compilerOutput?.outputFilename;
|
||||
if (entrypointPath == null) {
|
||||
printError('Compiler terminated unexpectedly.');
|
||||
return -5;
|
||||
}
|
||||
// Write path to frontend_server, since things need to be re-generated when
|
||||
// that changes.
|
||||
await outputDir.childFile('frontend_server.d')
|
||||
.writeAsString('frontend_server.d: ${artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk)}\n');
|
||||
|
||||
genSnapshotArgs.addAll(<String>[
|
||||
'--reify-generic-functions',
|
||||
'--strong',
|
||||
]);
|
||||
}
|
||||
|
||||
genSnapshotArgs.add(entrypointPath);
|
||||
genSnapshotArgs.add(mainPath);
|
||||
|
||||
final int genSnapshotExitCode = await genSnapshot.run(
|
||||
snapshotType: new SnapshotType(platform, buildMode),
|
||||
@ -517,6 +526,11 @@ class Snapshotter {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Returns true if the specified platform and build mode require running in interpreted mode.
|
||||
bool _isInterpreted(TargetPlatform platform, BuildMode buildMode) {
|
||||
return platform == TargetPlatform.ios && buildMode == BuildMode.debug;
|
||||
}
|
||||
|
||||
String _getPackagePath(PackageMap packageMap, String package) {
|
||||
return fs.path.dirname(fs.path.fromUri(packageMap.map[package]));
|
||||
}
|
||||
|
||||
@ -54,29 +54,50 @@ class BuildAotCommand extends BuildSubCommand {
|
||||
@override
|
||||
Future<Null> runCommand() async {
|
||||
await super.runCommand();
|
||||
|
||||
final String targetPlatform = argResults['target-platform'];
|
||||
final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
|
||||
if (platform == null)
|
||||
throwToolExit('Unknown platform: $targetPlatform');
|
||||
|
||||
final String typeName = artifacts.getEngineType(platform, getBuildMode());
|
||||
final BuildMode buildMode = getBuildMode();
|
||||
|
||||
Status status;
|
||||
if (!argResults['quiet']) {
|
||||
final String typeName = artifacts.getEngineType(platform, buildMode);
|
||||
status = logger.startProgress('Building AOT snapshot in ${getModeName(getBuildMode())} mode ($typeName)...',
|
||||
expectSlowOperation: true);
|
||||
}
|
||||
final String outputPath = argResults['output-dir'] ?? getAotBuildDirectory();
|
||||
try {
|
||||
final bool previewDart2 = argResults['preview-dart-2'];
|
||||
String mainPath = findMainDartFile(targetFile);
|
||||
final Snapshotter snapshotter = new Snapshotter();
|
||||
|
||||
// Compile to kernel, if Dart 2.
|
||||
if (previewDart2) {
|
||||
mainPath = await snapshotter.compileKernel(
|
||||
platform: platform,
|
||||
buildMode: buildMode,
|
||||
mainPath: mainPath,
|
||||
outputPath: outputPath,
|
||||
extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
|
||||
);
|
||||
if (mainPath == null) {
|
||||
printError('Compiler terminated unexpectedly.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Build AOT snapshot.
|
||||
final int snapshotExitCode = await snapshotter.buildAotSnapshot(
|
||||
platform: platform,
|
||||
buildMode: getBuildMode(),
|
||||
mainPath: findMainDartFile(targetFile),
|
||||
buildMode: buildMode,
|
||||
mainPath: mainPath,
|
||||
packagesPath: PackageMap.globalPackagesPath,
|
||||
outputPath: outputPath,
|
||||
previewDart2: argResults['preview-dart-2'],
|
||||
previewDart2: previewDart2,
|
||||
preferSharedLibrary: argResults['prefer-shared-library'],
|
||||
extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
|
||||
extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
|
||||
);
|
||||
if (snapshotExitCode != 0) {
|
||||
|
||||
@ -9,7 +9,6 @@ import 'dart:convert' show json;
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/compile.dart';
|
||||
import 'package:flutter_tools/src/base/build.dart';
|
||||
import 'package:flutter_tools/src/base/context.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
@ -70,29 +69,6 @@ class _FakeGenSnapshot implements GenSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
class _FakeKernelCompiler implements KernelCompiler {
|
||||
CompilerOutput output;
|
||||
|
||||
@override
|
||||
Future<CompilerOutput> compile({
|
||||
String sdkRoot,
|
||||
String mainPath,
|
||||
String outputFilePath,
|
||||
String depFilePath,
|
||||
bool linkPlatformKernelIn: false,
|
||||
bool aot: false,
|
||||
List<String> entryPointsJsonFiles,
|
||||
bool trackWidgetCreation: false,
|
||||
List<String> extraFrontEndOptions,
|
||||
String incrementalCompilerByteStorePath,
|
||||
String packagesPath,
|
||||
List<String> fileSystemRoots,
|
||||
String fileSystemScheme,
|
||||
}) async {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
group('SnapshotType', () {
|
||||
test('throws, if build mode is null', () {
|
||||
@ -606,7 +582,6 @@ void main() {
|
||||
String skyEnginePath;
|
||||
|
||||
_FakeGenSnapshot genSnapshot;
|
||||
_FakeKernelCompiler kernelCompiler;
|
||||
MemoryFileSystem fs;
|
||||
Snapshotter snapshotter;
|
||||
MockArtifacts mockArtifacts;
|
||||
@ -630,7 +605,6 @@ void main() {
|
||||
fs.file(fs.path.join(skyEnginePath, 'sdk_ext', 'vmservice_io.dart')).createSync();
|
||||
|
||||
genSnapshot = new _FakeGenSnapshot();
|
||||
kernelCompiler = new _FakeKernelCompiler();
|
||||
snapshotter = new Snapshotter();
|
||||
mockArtifacts = new MockArtifacts();
|
||||
mockXcode = new MockXcode();
|
||||
@ -648,18 +622,16 @@ void main() {
|
||||
Artifacts: () => mockArtifacts,
|
||||
FileSystem: () => fs,
|
||||
GenSnapshot: () => genSnapshot,
|
||||
KernelCompiler: () => kernelCompiler,
|
||||
Xcode: () => mockXcode,
|
||||
Xxd: () => mockXxd,
|
||||
};
|
||||
|
||||
testUsingContext('builds iOS debug AOT snapshot', () async {
|
||||
fs.file('main.dart').writeAsStringSync('void main() {}');
|
||||
fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
final String outputPath = fs.path.join('build', 'foo');
|
||||
fs.directory(outputPath).createSync(recursive: true);
|
||||
|
||||
kernelCompiler.output = const CompilerOutput('main.dill', 0);
|
||||
genSnapshot.outputs = <String, String>{
|
||||
fs.path.join(outputPath, 'vm_snapshot_data'): '',
|
||||
fs.path.join(outputPath, 'vm_snapshot_instr'): '',
|
||||
@ -672,7 +644,7 @@ void main() {
|
||||
final int genSnapshotExitCode = await snapshotter.buildAotSnapshot(
|
||||
platform: TargetPlatform.ios,
|
||||
buildMode: BuildMode.debug,
|
||||
mainPath: 'main.dart',
|
||||
mainPath: 'main.dill',
|
||||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
preferSharedLibrary: false,
|
||||
@ -701,12 +673,11 @@ void main() {
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
testUsingContext('builds iOS profile AOT snapshot', () async {
|
||||
fs.file('main.dart').writeAsStringSync('void main() {}');
|
||||
fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
final String outputPath = fs.path.join('build', 'foo');
|
||||
fs.directory(outputPath).createSync(recursive: true);
|
||||
|
||||
kernelCompiler.output = const CompilerOutput('main.dill', 0);
|
||||
genSnapshot.outputs = <String, String>{
|
||||
fs.path.join(outputPath, 'snapshot_assembly.S'): '',
|
||||
fs.path.join(outputPath, 'snapshot.d'): '',
|
||||
@ -715,7 +686,7 @@ void main() {
|
||||
final int genSnapshotExitCode = await snapshotter.buildAotSnapshot(
|
||||
platform: TargetPlatform.ios,
|
||||
buildMode: BuildMode.profile,
|
||||
mainPath: 'main.dart',
|
||||
mainPath: 'main.dill',
|
||||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
preferSharedLibrary: false,
|
||||
@ -746,12 +717,11 @@ void main() {
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
testUsingContext('builds iOS release AOT snapshot', () async {
|
||||
fs.file('main.dart').writeAsStringSync('void main() {}');
|
||||
fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
final String outputPath = fs.path.join('build', 'foo');
|
||||
fs.directory(outputPath).createSync(recursive: true);
|
||||
|
||||
kernelCompiler.output = const CompilerOutput('main.dill', 0);
|
||||
genSnapshot.outputs = <String, String>{
|
||||
fs.path.join(outputPath, 'snapshot_assembly.S'): '',
|
||||
fs.path.join(outputPath, 'snapshot.d'): '',
|
||||
@ -760,7 +730,7 @@ void main() {
|
||||
final int genSnapshotExitCode = await snapshotter.buildAotSnapshot(
|
||||
platform: TargetPlatform.ios,
|
||||
buildMode: BuildMode.release,
|
||||
mainPath: 'main.dart',
|
||||
mainPath: 'main.dill',
|
||||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
preferSharedLibrary: false,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user