55daf05f4f
Fixes https://github.com/dart-lang/sdk/issues/44553 Change-Id: Id461550e7761d874719220a5cb7a6b2c9ac421a0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181020 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Clement Skau <cskau@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com>
121 lines
4.2 KiB
Dart
121 lines
4.2 KiB
Dart
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:io';
|
|
import 'package:path/path.dart' as path;
|
|
import 'dart2native.dart';
|
|
|
|
final Directory binDir = File(Platform.resolvedExecutable).parent;
|
|
final String executableSuffix = Platform.isWindows ? '.exe' : '';
|
|
final String dartaotruntime =
|
|
path.join(binDir.path, 'dartaotruntime${executableSuffix}');
|
|
final String genKernel =
|
|
path.join(binDir.path, 'snapshots', 'gen_kernel.dart.snapshot');
|
|
final String genSnapshot =
|
|
path.join(binDir.path, 'utils', 'gen_snapshot${executableSuffix}');
|
|
final String productPlatformDill = path.join(
|
|
binDir.parent.path, 'lib', '_internal', 'vm_platform_strong_product.dill');
|
|
|
|
Future<void> generateNative({
|
|
String kind = 'exe',
|
|
String sourceFile,
|
|
String outputFile,
|
|
String debugFile,
|
|
String packages,
|
|
List<String> defines,
|
|
String enableExperiment = '',
|
|
bool enableAsserts = false,
|
|
bool soundNullSafety,
|
|
bool verbose = false,
|
|
String verbosity = 'all',
|
|
List<String> extraOptions = const [],
|
|
}) async {
|
|
final Directory tempDir = Directory.systemTemp.createTempSync();
|
|
try {
|
|
final sourcePath = path.canonicalize(path.normalize(sourceFile));
|
|
if (packages != null) {
|
|
packages = path.canonicalize(path.normalize(packages));
|
|
}
|
|
final Kind outputKind = {
|
|
'aot': Kind.aot,
|
|
'exe': Kind.exe,
|
|
}[kind];
|
|
final sourceWithoutDart = sourcePath.replaceFirst(RegExp(r'\.dart$'), '');
|
|
final outputPath = path.canonicalize(path.normalize(outputFile != null
|
|
? outputFile
|
|
: {
|
|
Kind.aot: '${sourceWithoutDart}.aot',
|
|
Kind.exe: '${sourceWithoutDart}.exe',
|
|
}[outputKind]));
|
|
final debugPath =
|
|
debugFile != null ? path.canonicalize(path.normalize(debugFile)) : null;
|
|
|
|
if (verbose) {
|
|
print('Compiling $sourcePath to $outputPath using format $kind:');
|
|
print('Generating AOT kernel dill.');
|
|
}
|
|
|
|
final String kernelFile = path.join(tempDir.path, 'kernel.dill');
|
|
final kernelResult = await generateAotKernel(Platform.executable, genKernel,
|
|
productPlatformDill, sourcePath, kernelFile, packages, defines,
|
|
enableExperiment: enableExperiment,
|
|
extraGenKernelOptions: [
|
|
'--invocation-modes=compile',
|
|
'--verbosity=$verbosity',
|
|
if (soundNullSafety != null)
|
|
'--${soundNullSafety ? '' : 'no-'}sound-null-safety',
|
|
]);
|
|
if (kernelResult.exitCode != 0) {
|
|
// We pipe both stdout and stderr to stderr because the CFE doesn't print
|
|
// errors to stderr. This unfortunately does emit info-only output in
|
|
// stderr, though.
|
|
stderr.write(kernelResult.stdout);
|
|
stderr.write(kernelResult.stderr);
|
|
await stderr.flush();
|
|
throw 'Generating AOT kernel dill failed!';
|
|
}
|
|
// Pipe info and warnings from the CFE to stdout since the compilation
|
|
// succeeded. Stderr should be empty but we pipe it to stderr for
|
|
// completeness.
|
|
stdout.write(kernelResult.stdout);
|
|
await stdout.flush();
|
|
stderr.write(kernelResult.stderr);
|
|
await stderr.flush();
|
|
|
|
if (verbose) {
|
|
print('Generating AOT snapshot.');
|
|
}
|
|
|
|
final String snapshotFile = (outputKind == Kind.aot
|
|
? outputPath
|
|
: path.join(tempDir.path, 'snapshot.aot'));
|
|
final snapshotResult = await generateAotSnapshot(genSnapshot, kernelFile,
|
|
snapshotFile, debugPath, enableAsserts, extraOptions);
|
|
if (snapshotResult.exitCode != 0) {
|
|
stderr.writeln(snapshotResult.stdout);
|
|
stderr.writeln(snapshotResult.stderr);
|
|
await stderr.flush();
|
|
throw 'Generating AOT snapshot failed!';
|
|
}
|
|
|
|
if (outputKind == Kind.exe) {
|
|
if (verbose) {
|
|
print('Generating executable.');
|
|
}
|
|
await writeAppendedExecutable(dartaotruntime, snapshotFile, outputPath);
|
|
|
|
if (Platform.isLinux || Platform.isMacOS) {
|
|
if (verbose) {
|
|
print('Marking binary executable.');
|
|
}
|
|
await markExecutable(outputPath);
|
|
}
|
|
}
|
|
|
|
print('Generated: ${outputPath}');
|
|
} finally {
|
|
tempDir.deleteSync(recursive: true);
|
|
}
|
|
}
|