blob: 6820fbb0e20e960eff38d3d149b07f96e2c6deb9 [file] [log] [blame]
#!/usr/bin/env dart
// ignore_for_file: only_throw_errors
import 'dart:io' show Directory, Platform, Process, ProcessResult, exit;
import 'package:args/args.dart' show ArgParser;
import 'package:path/path.dart' as path;
import 'package:pool/pool.dart' show Pool;
Future<void> main(List<String> args) async {
final argParser = ArgParser()
..addOption('target',
mandatory: false, defaultsTo: 'aot,exe,jit,js,js-production')
..addOption('jobs', abbr: 'j', mandatory: false);
final parsedArgs = argParser.parse(args);
var jobs = Platform.numberOfProcessors;
if (parsedArgs['jobs'] != null) {
jobs = int.parse(parsedArgs['jobs'] as String);
}
final targets = <Target>{};
for (final targetStr in (parsedArgs['target'] as String).split(',')) {
switch (targetStr) {
case 'aot':
targets.add(aotTarget);
break;
case 'exe':
targets.add(exeTarget);
break;
case 'jit':
targets.add(jitTarget);
break;
case 'js':
targets.add(jsTarget);
break;
case 'js-production':
targets.add(jsProductionTarget);
break;
case 'wasm':
targets.add(wasmTarget);
break;
default:
print('Unsupported target: $targetStr. Supported targets: aot, exe, '
'jit, js, js-production, wasm, wasm-omit-checks');
exit(1);
}
}
var sourceFiles = parsedArgs.rest;
if (sourceFiles.isEmpty) {
// Compile all files in bin/
sourceFiles = Directory('bin')
.listSync(recursive: false)
.where((dirFile) => path.extension(dirFile.path) == '.dart')
.map((dirFile) => dirFile.path)
.toList();
}
final commands = <List<String>>[];
if (sourceFiles.isNotEmpty && targets.isNotEmpty) {
try {
Directory('out').createSync(recursive: true);
} catch (e) {
print("Error while creating 'out' directory: $e");
exit(1);
}
}
for (final sourceFile in sourceFiles) {
for (final target in targets) {
commands.add(target.compileArgs(sourceFile));
}
}
final pool = Pool(jobs);
final stream = pool.forEach<List<String>, CompileProcess>(commands,
(List<String> command) async {
final commandStr = command.join(' ');
print(commandStr);
final result = await Process.run(command[0], command.sublist(1));
return CompileProcess(commandStr, result);
});
await for (final compileProcess in stream) {
final exitCode = compileProcess.result.exitCode;
if (exitCode != 0) {
print('Process exited with $exitCode');
print('Command: ${compileProcess.command}');
print(
'Process stdout ---------------------------------------------------');
print(compileProcess.result.stdout);
print(
'Process stderr ---------------------------------------------------');
print(compileProcess.result.stderr);
print(
'------------------------------------------------------------------');
exit(1);
}
}
await pool.done;
}
class CompileProcess {
final String command;
final ProcessResult result;
CompileProcess(this.command, this.result);
}
class Target {
final String _name;
final List<String> Function(String) _processArgs;
const Target(this._name, this._processArgs);
@override
String toString() {
return 'Target($_name)';
}
List<String> compileArgs(String sourceFile) {
return _processArgs(sourceFile);
}
}
const aotTarget = Target('aot', aotProcessArgs);
const exeTarget = Target('exe', exeProcessArgs);
const jitTarget = Target('jit', jitProcessArgs);
const jsTarget = Target('js', jsProcessArgs);
const jsProductionTarget = Target('js-production', jsProductionProcessArgs);
const wasmTarget = Target('wasm', wasmProcessArgs);
List<String> aotProcessArgs(String sourceFile) {
final baseName = path.basename(sourceFile);
final baseNameNoExt = path.withoutExtension(baseName);
return [
'dart',
'compile',
'aot-snapshot',
sourceFile,
'-o',
'out/$baseNameNoExt.aot'
];
}
List<String> exeProcessArgs(String sourceFile) {
final baseName = path.basename(sourceFile);
final baseNameNoExt = path.withoutExtension(baseName);
return ['dart', 'compile', 'exe', sourceFile, '-o', 'out/$baseNameNoExt.exe'];
}
List<String> jitProcessArgs(String sourceFile) {
final baseName = path.basename(sourceFile);
final baseNameNoExt = path.withoutExtension(baseName);
return [
'dart',
'--snapshot-kind=kernel',
'--snapshot=out/$baseNameNoExt.dill',
sourceFile
];
}
List<String> jsProcessArgs(String sourceFile) {
final baseName = path.basename(sourceFile);
final baseNameNoExt = path.withoutExtension(baseName);
return ['dart', 'compile', 'js', sourceFile, '-o', 'out/$baseNameNoExt.js'];
}
List<String> jsProductionProcessArgs(String sourceFile) {
final baseName = path.basename(sourceFile);
final baseNameNoExt = path.withoutExtension(baseName);
return [
'dart',
'compile',
'js',
sourceFile,
'-O4',
'-o',
'out/$baseNameNoExt.production.js'
];
}
List<String> wasmProcessArgs(String sourceFile) {
final baseName = path.basename(sourceFile);
final baseNameNoExt = path.withoutExtension(baseName);
return [
'dart',
'compile',
'wasm',
sourceFile,
'-O4',
'-o',
'out/$baseNameNoExt.wasm'
];
}