[frontend_server] native-assets-only compilation
This CL adds a `--native-assets-only` CLI option to the frontend_server startup for single shot compilation. This CL adds a `native-assets-only` instruction to the frontend_server protocol. TEST=pkg/frontend_server/test/native_assets_test.dart Unit test producing kernel file. Closes: https://github.com/dart-lang/sdk/issues/55503 Change-Id: Ice6281162460032e669d2dda2a128b357e81bc50 Cq-Include-Trybots: dart/try:pkg-linux-debug-try,pkg-linux-release-arm64-try,pkg-mac-release-try,pkg-mac-release-arm64-try,pkg-win-release-try,pkg-win-release-arm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363567 Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
committed by
Alexander Thomas
parent
2946586ef2
commit
81af7ebbf4
@@ -100,6 +100,9 @@ ArgParser argParser = new ArgParser(allowTrailingOptions: true)
|
||||
defaultsTo: const <String>[])
|
||||
..addOption('native-assets',
|
||||
help: 'Provide the native-assets mapping for @Native external functions.')
|
||||
..addFlag('native-assets-only',
|
||||
help: "Only compile the native-assets mapping. "
|
||||
"Don't compile the dart program.")
|
||||
..addOption('target',
|
||||
help: 'Target model that determines what core libraries are available',
|
||||
allowed: <String>[
|
||||
@@ -291,6 +294,14 @@ abstract class CompilerInterface {
|
||||
IncrementalCompiler? generator,
|
||||
});
|
||||
|
||||
/// Compiles the native_assets.yaml into a dill file.
|
||||
///
|
||||
/// Returns [true] if compilation was successful and produced no errors.
|
||||
Future<bool> compileNativeAssetsOnly(
|
||||
ArgResults options, {
|
||||
IncrementalCompiler? generator,
|
||||
});
|
||||
|
||||
/// Sets the native assets mapping to be embedded in the kernel.
|
||||
Future<bool> setNativeAssets(String nativeAssets);
|
||||
|
||||
@@ -480,7 +491,9 @@ class FrontendCompiler implements CompilerInterface {
|
||||
_additionalSources =
|
||||
(options['source'] as List<String>).map(resolveInputUri).toList();
|
||||
final String? nativeAssets = options['native-assets'] as String?;
|
||||
_nativeAssets = nativeAssets != null ? resolveInputUri(nativeAssets) : null;
|
||||
if (_nativeAssets == null && nativeAssets != null) {
|
||||
_nativeAssets = resolveInputUri(nativeAssets);
|
||||
}
|
||||
_kernelBinaryFilenameFull = _options['output-dill'] ?? '$entryPoint.dill';
|
||||
_kernelBinaryFilenameIncremental = _options['output-incremental-dill'] ??
|
||||
(_options['output-dill'] != null
|
||||
@@ -694,6 +707,55 @@ class FrontendCompiler implements CompilerInterface {
|
||||
return errors.isEmpty;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> compileNativeAssetsOnly(
|
||||
ArgResults options, {
|
||||
IncrementalCompiler? generator,
|
||||
}) async {
|
||||
_fileSystem = createFrontEndFileSystem(
|
||||
options['filesystem-scheme'],
|
||||
options['filesystem-root'],
|
||||
allowHttp: options['enable-http-uris'],
|
||||
);
|
||||
_options = options;
|
||||
final String? nativeAssets = options['native-assets'] as String?;
|
||||
if (_nativeAssets == null && nativeAssets != null) {
|
||||
_nativeAssets = resolveInputUri(nativeAssets);
|
||||
}
|
||||
if (_nativeAssets == null) {
|
||||
print(
|
||||
'Error: When --native-assets-only is specified it is required to'
|
||||
' specify --native-assets option that points to physical file system'
|
||||
' location of a source native_assets.yaml file.',
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (_options['output-dill'] == null) {
|
||||
print(
|
||||
'Error: When --native-assets-only is specified it is required to'
|
||||
' specify --output-dill option that points to physical file system'
|
||||
' location of a target dill file.',
|
||||
);
|
||||
return false;
|
||||
}
|
||||
_kernelBinaryFilename = _options['output-dill'];
|
||||
final CompilerOptions compilerOptions = new CompilerOptions();
|
||||
_compilerOptions = compilerOptions;
|
||||
|
||||
final String boundaryKey = generateV4UUID();
|
||||
_outputStream.writeln('result $boundaryKey');
|
||||
await _compileNativeAssets();
|
||||
await writeDillFileNativeAssets(
|
||||
_nativeAssetsLibrary!,
|
||||
_kernelBinaryFilename,
|
||||
);
|
||||
_outputStream.writeln(boundaryKey);
|
||||
_outputStream.writeln('+${await asFileUri(_fileSystem, _nativeAssets!)}');
|
||||
_outputStream
|
||||
.writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> setNativeAssets(String nativeAssets) async {
|
||||
_nativeAssetsLibrary = null; // Purge compiled cache.
|
||||
@@ -875,6 +937,19 @@ class FrontendCompiler implements CompilerInterface {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> writeDillFileNativeAssets(
|
||||
Library nativeAssetsLibrary,
|
||||
String filename,
|
||||
) async {
|
||||
final IOSink sink = new File(filename).openWrite();
|
||||
final BinaryPrinter printer = new BinaryPrinter(sink);
|
||||
printer.writeComponentFile(new Component(
|
||||
libraries: [nativeAssetsLibrary],
|
||||
mode: nativeAssetsLibrary.nonNullableByDefaultCompiledMode,
|
||||
));
|
||||
await sink.close();
|
||||
}
|
||||
|
||||
Future<void> invalidateIfInitializingFromDill() async {
|
||||
if (_assumeInitializeFromDillUpToDate) return;
|
||||
if (_kernelBinaryFilename != _kernelBinaryFilenameFull) return;
|
||||
@@ -1297,6 +1372,7 @@ StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
|
||||
const String COMPILE_INSTRUCTION_SPACE = 'compile ';
|
||||
const String RECOMPILE_INSTRUCTION_SPACE = 'recompile ';
|
||||
const String NATIVE_ASSETS_INSTRUCTION_SPACE = 'native-assets ';
|
||||
const String NATIVE_ASSETS_ONLY_INSTRUCTION = 'native-assets-only';
|
||||
const String COMPILE_EXPRESSION_INSTRUCTION_SPACE =
|
||||
'compile-expression ';
|
||||
const String COMPILE_EXPRESSION_TO_JS_INSTRUCTION_SPACE =
|
||||
@@ -1305,6 +1381,8 @@ StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
|
||||
final String entryPoint =
|
||||
string.substring(COMPILE_INSTRUCTION_SPACE.length);
|
||||
await compiler.compile(entryPoint, options, generator: generator);
|
||||
} else if (string == NATIVE_ASSETS_ONLY_INSTRUCTION) {
|
||||
await compiler.compileNativeAssetsOnly(options, generator: generator);
|
||||
} else if (string.startsWith(RECOMPILE_INSTRUCTION_SPACE)) {
|
||||
// 'recompile [<entryPoint>] <boundarykey>'
|
||||
// where <boundarykey> can't have spaces
|
||||
|
||||
@@ -97,6 +97,14 @@ Future<int> starter(
|
||||
canaryFeatures: options['dartdevc-canary'],
|
||||
);
|
||||
|
||||
if (options['native-assets-only']) {
|
||||
final bool compileResult = await compiler.compileNativeAssetsOnly(
|
||||
options,
|
||||
generator: generator,
|
||||
);
|
||||
return compileResult ? 0 : 254;
|
||||
}
|
||||
|
||||
if (options.rest.isNotEmpty) {
|
||||
return await compiler.compile(options.rest[0], options,
|
||||
generator: generator)
|
||||
|
||||
@@ -3328,6 +3328,12 @@ class FrontendServer {
|
||||
.codeUnits);
|
||||
}
|
||||
|
||||
/// Compiles the native assets in isolation.
|
||||
void compileNativeAssetsOnly() {
|
||||
outputParser.expectSources = true;
|
||||
inputStreamController.add('native-assets-only\n'.codeUnits);
|
||||
}
|
||||
|
||||
/// Sets the native assets yaml [uri].
|
||||
void setNativeAssets({required Uri uri}) {
|
||||
outputParser.expectSources = true;
|
||||
|
||||
@@ -187,8 +187,8 @@ void main() {
|
||||
expect(await dillFile.exists(), equals(true));
|
||||
expect(result.filename, dillFile.path);
|
||||
expect(result.errorsCount, 0);
|
||||
count += 1;
|
||||
frontendServer.accept();
|
||||
frontendServer.quit();
|
||||
|
||||
final Component component =
|
||||
loadComponentFromBinary(dillFile.path);
|
||||
@@ -196,7 +196,21 @@ void main() {
|
||||
_findNativeAssetsLibrary(component);
|
||||
expect(nativeAssetsLibrary, isNotNull);
|
||||
|
||||
frontendServer.compileNativeAssetsOnly();
|
||||
break;
|
||||
case 2:
|
||||
expect(await dillFile.exists(), equals(true));
|
||||
expect(result.filename, dillFile.path);
|
||||
expect(result.errorsCount, 0);
|
||||
count += 1;
|
||||
|
||||
final Component component =
|
||||
loadComponentFromBinary(dillFile.path);
|
||||
final Library? nativeAssetsLibrary =
|
||||
_findNativeAssetsLibrary(component);
|
||||
expect(nativeAssetsLibrary, isNotNull);
|
||||
|
||||
frontendServer.quit();
|
||||
}
|
||||
});
|
||||
expect(await result, 0);
|
||||
@@ -320,6 +334,28 @@ void main() {
|
||||
_findNativeAssetsLibrary(component);
|
||||
expect(nativeAssetsLibrary, isNotNull);
|
||||
});
|
||||
|
||||
test('pass in native assets only at startup', () async {
|
||||
final FrontendServer frontendServer = new FrontendServer();
|
||||
Future<int> frontendServerResult = frontendServer.open(<String>[
|
||||
'--sdk-root=${sdkRoot.toFilePath()}',
|
||||
'--platform=${platformKernel.path}',
|
||||
'--aot',
|
||||
'--tfa',
|
||||
'--output-dill=${dillFile.path}',
|
||||
'--native-assets=${nativeAssetsYamlFile.path}',
|
||||
'--native-assets-only',
|
||||
]);
|
||||
|
||||
expect(await frontendServerResult, 0);
|
||||
frontendServer.close();
|
||||
|
||||
expect(await dillFile.exists(), equals(true));
|
||||
final Component component = loadComponentFromBinary(dillFile.path);
|
||||
final Library? nativeAssetsLibrary =
|
||||
_findNativeAssetsLibrary(component);
|
||||
expect(nativeAssetsLibrary, isNotNull);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user