49f630c53b
These new modules are only used when compiling with the `--canary`, `--modules=ddc` and no other module formats. This new flavor of the module system treats the output .js files as a bundle of one or more Dart libraries. In this change the Dart SDK module is still compiled with it's libraries mixed together but exports them individually. Ideally this is temporary and eventually they can be compiled in isolation as well. All other modules are compiled in isolation so class hierarchies many may be broken until proper cross library linking is implemented in a followup change. Change-Id: I27e58a445476198bd8613bb63c57cb96c0d5bc55 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379261 Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Nicholas Shahan <nshahan@google.com> Reviewed-by: Mark Zhou <markzipan@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
531 lines
20 KiB
Dart
Executable File
531 lines
20 KiB
Dart
Executable File
#!/usr/bin/env dart
|
|
// Copyright (c) 2018, 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.
|
|
|
|
/// Compiles code with DDC and runs the resulting code with either node or
|
|
/// chrome.
|
|
///
|
|
/// The first script supplied should be the one with `main()`.
|
|
///
|
|
/// Saves the output in the same directory as the sources for convenient
|
|
/// inspection, modification or rerunning the code.
|
|
|
|
import 'dart:io';
|
|
import 'dart:ffi';
|
|
|
|
import 'package:args/args.dart' show ArgParser;
|
|
import 'package:dev_compiler/src/compiler/js_names.dart' as js_names;
|
|
import 'package:path/path.dart' as p;
|
|
|
|
enum NullSafety { strict, weak, disabled }
|
|
|
|
void main(List<String> args) async {
|
|
void printUsage() {
|
|
print('Usage: ddb [options] <dart-script-file>\n');
|
|
print('Compiles <dart-script-file> with the dev_compiler and runs it on a '
|
|
'JS platform.\n'
|
|
'Optionally, mulitple Dart source files can be passed as arguments and '
|
|
'they will be compiled into seperate modules in the order provided. '
|
|
'The order will be treated as an import DAG with the last file as the '
|
|
'application entrypoint. The .dill file outputs from each compile will '
|
|
'be collected and passed as dependency summaries for the next compile '
|
|
'step.');
|
|
}
|
|
|
|
// Parse flags.
|
|
var parser = ArgParser(usageLineLength: 80)
|
|
..addOption('arch',
|
|
abbr: 'a',
|
|
help: "Target platform's machine architecture.",
|
|
allowed: ['x64', 'arm64'])
|
|
..addOption('binary', abbr: 'b', help: 'Runtime binary path.')
|
|
..addOption('compile-vm-options',
|
|
help: 'DART_VM_OPTIONS for the compilation VM.')
|
|
..addFlag('debug',
|
|
abbr: 'd',
|
|
help: 'Use current source instead of built SDK.',
|
|
defaultsTo: false)
|
|
..addMultiOption('enable-experiment',
|
|
help: 'Run with specified experiments enabled.')
|
|
..addFlag('help', abbr: 'h', help: 'Display this message.')
|
|
..addOption('mode',
|
|
help: 'Option to (compile|run|all). Default is all (compile and run).',
|
|
allowed: ['compile', 'run', 'all'],
|
|
defaultsTo: 'all')
|
|
..addFlag('sound-null-safety',
|
|
help: 'Compile for sound null safety at runtime. Passed through to the '
|
|
'DDC binary. Defaults to false.',
|
|
negatable: true,
|
|
defaultsTo: true)
|
|
..addFlag('emit-debug-symbols',
|
|
help: 'Pass through flag for DDC, emits debug symbols file along with '
|
|
'the compiled module.',
|
|
defaultsTo: false)
|
|
..addFlag('null-assertions',
|
|
help: 'Run with assertions that values passed to non-nullable method '
|
|
'parameters are not null.',
|
|
defaultsTo: false)
|
|
..addFlag('native-null-assertions',
|
|
help: 'Run with assertions on non-nullable values returned from native '
|
|
'APIs.',
|
|
negatable: true)
|
|
..addFlag('interop-null-assertions',
|
|
help: 'Run with assertions on non-nullable values returned from '
|
|
'non-static JavaScript interop APIs.',
|
|
defaultsTo: false)
|
|
..addFlag('weak-null-safety-errors',
|
|
help: 'Treat weak null safety warnings as errors.', defaultsTo: false)
|
|
..addFlag('ddc-modules',
|
|
help: 'Emit modules in the ddc format. Currently supported in Chrome '
|
|
'(amd modules by default) and D8 (already uses ddc modules by '
|
|
'default).',
|
|
defaultsTo: false)
|
|
..addFlag('canary',
|
|
help: 'Enable all compiler features under active development.',
|
|
defaultsTo: false)
|
|
..addFlag('observe',
|
|
help:
|
|
'Run the compiler in the Dart VM with --observe. Implies --debug.',
|
|
defaultsTo: false)
|
|
..addOption('out', help: 'Output file.')
|
|
..addOption('packages', help: 'Where to find a package spec file.')
|
|
..addOption('port',
|
|
abbr: 'p',
|
|
help: 'Run with the corresponding chrome/V8 debugging port open.',
|
|
defaultsTo: '9222')
|
|
..addOption('runtime',
|
|
abbr: 'r',
|
|
help: 'Platform to run on (node|d8|chrome). Default is node.',
|
|
allowed: ['node', 'd8', 'chrome'],
|
|
defaultsTo: 'node')
|
|
..addFlag('summarize-text',
|
|
help: 'Emit API summary in a .js.txt file.', defaultsTo: false)
|
|
..addMultiOption('summary',
|
|
abbr: 's',
|
|
help: 'summary file(s) of imported libraries, optionally with module '
|
|
'import path: -s path.sum=js/import/path')
|
|
..addFlag('verbose',
|
|
abbr: 'v',
|
|
help: 'Echos the commands, arguments, and environment this script is '
|
|
'running.',
|
|
defaultsTo: false)
|
|
..addOption('vm-service-port',
|
|
help: 'Specify the observatory port. Implied --observe.');
|
|
|
|
var options = parser.parse(args);
|
|
if (options['help'] as bool) {
|
|
printUsage();
|
|
print('Available options:');
|
|
print(parser.usage);
|
|
exit(0);
|
|
}
|
|
if (options.rest.isEmpty) {
|
|
print('Dart script file required.\n');
|
|
printUsage();
|
|
exit(1);
|
|
}
|
|
var arch = options['arch'] as String?;
|
|
var debug = options['debug'] as bool ||
|
|
options['observe'] as bool ||
|
|
options.wasParsed('vm-service-port');
|
|
var summarizeText = options['summarize-text'] as bool;
|
|
var binary = options['binary'] as String?;
|
|
var experiments = options['enable-experiment'] as List<String>;
|
|
var summaries = options['summary'] as List<String>;
|
|
var port = int.parse(options['port'] as String);
|
|
var mode = options['mode'] as String;
|
|
var compile = mode == 'compile' || mode == 'all';
|
|
var run = mode == 'run' || mode == 'all';
|
|
var verbose = options['verbose'] as bool;
|
|
var soundNullSafety = options['sound-null-safety'] as bool;
|
|
var emitDebugSymbols = options['emit-debug-symbols'] as bool;
|
|
var nonNullAsserts = options['null-assertions'] as bool;
|
|
var nativeNonNullAsserts = options.wasParsed('native-null-assertions')
|
|
? options['native-null-assertions'] as bool
|
|
: soundNullSafety;
|
|
var jsInteropNonNullAsserts = options['interop-null-assertions'] as bool;
|
|
var weakNullSafetyErrors = options['weak-null-safety-errors'] as bool;
|
|
var ddcModules = options['ddc-modules'] as bool;
|
|
var canaryFeatures = options['canary'] as bool;
|
|
var sourceFiles = options.rest.map(p.canonicalize);
|
|
var entryPoint = sourceFiles.last;
|
|
var libRoot = p.dirname(entryPoint);
|
|
var basename = p.basenameWithoutExtension(entryPoint);
|
|
var libname = pathToLibName(entryPoint);
|
|
|
|
// This is used in the DDC module system and usually corresponds to the
|
|
// entrypoint's path.
|
|
var appname = p.relative(p.withoutExtension(entryPoint));
|
|
|
|
// This is used in the DDC module system for multiapp workflows and is
|
|
// stubbed in ddb.
|
|
var uuid = '00000000-0000-0000-0000-000000000000';
|
|
|
|
// By default (no `-d`), we use the `dartdevc` binary on the user's path to
|
|
// compute the SDK we use for execution. I.e., we assume that `dart` is
|
|
// under `$DART_SDK/bin/dart` and use that to find `dartdevc` and related
|
|
// artifacts. In this mode, this script can run against any installed SDK.
|
|
// If you want to run against a freshly built SDK, that must be first on
|
|
// your path.
|
|
var dartBinary = Platform.resolvedExecutable;
|
|
var dartSdk = p.dirname(p.dirname(dartBinary));
|
|
|
|
// In debug mode (`-d`), we run from the `pkg/dev_compiler` sources. We
|
|
// determine the location via this actual script (i.e., `-d` assumes
|
|
// this script remains under to `tool` sub-directory).
|
|
var toolPath =
|
|
Platform.script.normalizePath().toFilePath(windows: Platform.isWindows);
|
|
var ddcPath = p.dirname(p.dirname(toolPath));
|
|
var dartCheckoutPath = p.dirname(p.dirname(ddcPath));
|
|
|
|
/// Runs the [command] with [args] in [environment].
|
|
///
|
|
/// Will echo the commands to the console before running them when running in
|
|
/// `verbose` mode.
|
|
Future<Process> startProcess(String name, String command, List<String> args,
|
|
[Map<String, String> environment = const {}]) {
|
|
if (verbose) {
|
|
print('Running $name:\n$command ${args.join(' ')}\n');
|
|
if (environment.isNotEmpty) {
|
|
var environmentVariables =
|
|
environment.entries.map((e) => '${e.key}: ${e.value}').join('\n');
|
|
print('With Environment:\n$environmentVariables\n');
|
|
}
|
|
}
|
|
return Process.start(command, args,
|
|
mode: ProcessStartMode.inheritStdio, environment: environment);
|
|
}
|
|
|
|
Future<void> runDdc(List<String> ddcArgs) async {
|
|
var observe =
|
|
options.wasParsed('vm-service-port') || options['observe'] as bool;
|
|
var vmServicePort = options.wasParsed('vm-service-port')
|
|
? '=${options['vm-service-port']}'
|
|
: '';
|
|
var vmOptions = options['compile-vm-options'] as String?;
|
|
var args = <String>[
|
|
...?vmOptions?.split(' '),
|
|
if (debug) ...[
|
|
if (observe) ...[
|
|
'--enable-vm-service$vmServicePort',
|
|
'--pause-isolates-on-start',
|
|
],
|
|
'--enable-asserts',
|
|
// Use unbuilt script. This only works from a source checkout.
|
|
p.join(ddcPath, 'bin', 'dartdevc.dart'),
|
|
] else
|
|
// Use built snapshot.
|
|
p.join(dartSdk, 'bin', 'snapshots', 'dartdevc.dart.snapshot'),
|
|
...ddcArgs,
|
|
];
|
|
var process = await startProcess('DDC', dartBinary, args);
|
|
if (await process.exitCode != 0) exit(await process.exitCode);
|
|
}
|
|
|
|
String mod;
|
|
var chrome = false;
|
|
var node = false;
|
|
var d8 = false;
|
|
var runtime = options['runtime'] as String?;
|
|
switch (runtime) {
|
|
case 'node':
|
|
// TODO(nshahan): Cleanup after the ddc module format is used everywhere.
|
|
if (ddcModules) {
|
|
throw ('The combination of `--runtime=$runtime` and `--ddc-modules` '
|
|
'is not supported at this time.');
|
|
}
|
|
node = true;
|
|
mod = 'common';
|
|
break;
|
|
case 'd8':
|
|
d8 = true;
|
|
mod = 'ddc';
|
|
break;
|
|
case 'chrome':
|
|
chrome = true;
|
|
// TODO(nshahan): Cleanup after the ddc module format is used everywhere.
|
|
mod = ddcModules ? 'ddc' : 'amd';
|
|
break;
|
|
default:
|
|
throw Exception('Unexpected runtime: $runtime');
|
|
}
|
|
|
|
var sdkRoot = p.dirname(p.dirname(ddcPath));
|
|
var buildDir = resolveBuildDir(sdkRoot, arch);
|
|
var requirePath = p.join(sdkRoot, 'third_party', 'requirejs');
|
|
var sdkOutlineDill = p.join(buildDir,
|
|
soundNullSafety ? 'ddc_outline.dill' : 'ddc_outline_unsound.dill');
|
|
var compileModeDir = [
|
|
canaryFeatures ? 'canary' : 'stable',
|
|
soundNullSafety ? '' : '_unsound',
|
|
].join();
|
|
var sdkJsPath =
|
|
p.join(buildDir, 'gen', 'utils', 'ddc', compileModeDir, 'sdk', mod);
|
|
var preamblesDir = p.join(
|
|
sdkRoot, 'sdk', 'lib', '_internal', 'js_runtime', 'lib', 'preambles');
|
|
|
|
// Print an initial empty line to separate the invocation from the output.
|
|
if (verbose) {
|
|
print('');
|
|
}
|
|
var outputs = <String>[];
|
|
if (compile) {
|
|
var ddcArgs = [
|
|
if (summarizeText) '--summarize-text',
|
|
'--modules=$mod',
|
|
'--dart-sdk-summary=$sdkOutlineDill',
|
|
for (var summary in summaries) '--summary=$summary',
|
|
for (var experiment in experiments) '--enable-experiment=$experiment',
|
|
if (soundNullSafety) '--sound-null-safety' else '--no-sound-null-safety',
|
|
if (options['packages'] != null) '--packages=${options['packages']}',
|
|
if (emitDebugSymbols) '--emit-debug-symbols',
|
|
if (canaryFeatures) '--canary',
|
|
];
|
|
var summaryFiles = [];
|
|
for (var sourceFile in sourceFiles) {
|
|
var out = p.setExtension(sourceFile, '.js');
|
|
var requestArgs = [
|
|
for (var summary in summaryFiles) '--summary=$summary',
|
|
'-o',
|
|
out,
|
|
sourceFile,
|
|
];
|
|
await runDdc([...ddcArgs, ...requestArgs]);
|
|
outputs.add(out);
|
|
var summaryFile = p.setExtension(out, '.dill');
|
|
var libname =
|
|
js_names.pathToJSIdentifier(p.basenameWithoutExtension(sourceFile));
|
|
summaryFiles.add('$summaryFile=$libname');
|
|
}
|
|
}
|
|
|
|
if (run) {
|
|
var ddcModuleSdkOptions = canaryFeatures ?
|
|
'''let sdkOptions = {
|
|
weakNullSafetyWarnings: !($weakNullSafetyErrors || $soundNullSafety),
|
|
weakNullSafetyErrors: $weakNullSafetyErrors,
|
|
nonNullAsserts: $nonNullAsserts,
|
|
nativeNonNullAsserts: $nativeNonNullAsserts,
|
|
jsInteropNonNullAsserts: $jsInteropNonNullAsserts,
|
|
};''' :
|
|
'''
|
|
let sdk = dart_library.import("dart_sdk", "$appname");
|
|
sdk.dart.weakNullSafetyWarnings(!($weakNullSafetyErrors || $soundNullSafety));
|
|
sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
|
|
sdk.dart.nonNullAsserts($nonNullAsserts);
|
|
sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
|
|
sdk.dart.jsInteropNonNullAsserts($jsInteropNonNullAsserts);
|
|
''';
|
|
var ddcModuleRunMain = canaryFeatures
|
|
? 'dartDevEmbedder.runMain("$libname", sdkOptions);'
|
|
: 'dart_library.start('
|
|
'"$appname", "$uuid", "$basename", "$libname", false);';
|
|
if (chrome) {
|
|
String chromeBinary;
|
|
if (binary != null) {
|
|
chromeBinary = binary;
|
|
} else if (Platform.isWindows) {
|
|
chromeBinary =
|
|
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe';
|
|
} else if (Platform.isMacOS) {
|
|
chromeBinary =
|
|
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
|
|
} else {
|
|
// Assume Linux
|
|
chromeBinary = 'google-chrome';
|
|
}
|
|
var amdModulePaths = [
|
|
for (var output in outputs)
|
|
'"${pathToLibName(output)}": "${p.withoutExtension(output)}"'
|
|
].join(',\n ');
|
|
|
|
// Seal the native JavaScript Object prototype to avoid pollution before
|
|
// loading the Dart SDK module.
|
|
var amdModulesHtml = '''
|
|
<script src="$preamblesDir/seal_native_object.js"></script>
|
|
<script src='$requirePath/require.js'></script>
|
|
<script>
|
|
require.config({
|
|
paths: {
|
|
'dart_sdk': '$sdkJsPath/dart_sdk',
|
|
$amdModulePaths
|
|
},
|
|
waitSeconds: 15
|
|
});
|
|
require(['dart_sdk', '$libname'],
|
|
function(sdk, app) {
|
|
'use strict';
|
|
|
|
sdk.dart.weakNullSafetyWarnings(
|
|
!($weakNullSafetyErrors || $soundNullSafety));
|
|
sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
|
|
sdk.dart.nonNullAsserts($nonNullAsserts);
|
|
sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
|
|
sdk.dart.jsInteropNonNullAsserts($jsInteropNonNullAsserts);
|
|
sdk._debugger.registerDevtoolsFormatter();
|
|
app.$libname.main([]);
|
|
});
|
|
</script>
|
|
''';
|
|
var ddcModuleScriptTags = [
|
|
for (var output in outputs) '<script src="$output"></script>'
|
|
].join('\n');
|
|
var ddcModulesHtml = '''
|
|
<script src="$preamblesDir/seal_native_object.js"></script>
|
|
<script src="$ddcPath/lib/js/ddc/ddc_module_loader.js"></script>
|
|
<script src="$sdkJsPath/dart_sdk.js"></script>
|
|
$ddcModuleScriptTags
|
|
<script>
|
|
$ddcModuleSdkOptions
|
|
$ddcModuleRunMain
|
|
</script>
|
|
''';
|
|
var htmlFile = p.setExtension(entryPoint, '.html');
|
|
File(htmlFile)
|
|
.writeAsStringSync(ddcModules ? ddcModulesHtml : amdModulesHtml);
|
|
var tmp = p.join(Directory.systemTemp.path, 'ddc');
|
|
|
|
var process = await startProcess('Chrome', chromeBinary, [
|
|
'--auto-open-devtools-for-tabs',
|
|
'--allow-file-access-from-files',
|
|
'--remote-debugging-port=$port',
|
|
'--user-data-dir=$tmp',
|
|
htmlFile
|
|
]);
|
|
if (await process.exitCode != 0) exit(await process.exitCode);
|
|
} else if (node) {
|
|
var nodePath = '$sdkJsPath:$libRoot';
|
|
var runjs = '''
|
|
// Seal the native JavaScript Object prototype to avoid pollution before
|
|
// loading the Dart SDK module.
|
|
delete Object.prototype.__proto__;
|
|
Object.seal(Object.prototype);
|
|
|
|
let source_maps;
|
|
try {
|
|
source_maps = require('source-map-support');
|
|
source_maps.install();
|
|
} catch(e) {
|
|
}
|
|
let sdk = require(\"dart_sdk\");
|
|
// Create a self reference for JS interop tests that set fields on self.
|
|
sdk.dart.global.self = sdk.dart.global;
|
|
let main = require(\"./$basename\").$libname.main;
|
|
try {
|
|
sdk.dart.weakNullSafetyWarnings(
|
|
!($weakNullSafetyErrors || $soundNullSafety));
|
|
sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
|
|
sdk.dart.nonNullAsserts($nonNullAsserts);
|
|
sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
|
|
sdk.dart.jsInteropNonNullAsserts($jsInteropNonNullAsserts);
|
|
sdk._isolate_helper.startRootIsolate(main, []);
|
|
} catch(e) {
|
|
if (!source_maps) {
|
|
console.log('For Dart source maps: npm install source-map-support');
|
|
}
|
|
sdk.core.print(sdk.dart.stackTrace(e));
|
|
process.exit(1);
|
|
}
|
|
''';
|
|
var nodeFile = p.setExtension(entryPoint, '.run.js');
|
|
File(nodeFile).writeAsStringSync(runjs);
|
|
var nodeBinary = binary ?? 'node';
|
|
var process = await startProcess('Node', nodeBinary,
|
|
['--inspect=localhost:$port', nodeFile], {'NODE_PATH': nodePath});
|
|
if (await process.exitCode != 0) exit(await process.exitCode);
|
|
} else if (d8) {
|
|
var ddcModuleScriptTags =
|
|
[for (var output in outputs) 'load("$output");'].join('\n');
|
|
var ddcModuleAssignGlobalSelf = canaryFeatures ?
|
|
'''
|
|
let dart = dartDevEmbedder.importLibrary("dart");
|
|
dart.global.self = dart.global;''':
|
|
'sdk.dart.global.self = sdk.dart.global;';
|
|
var runjs = '''
|
|
load("$ddcPath/lib/js/ddc/ddc_module_loader.js");
|
|
load("$sdkJsPath/dart_sdk.js");
|
|
$ddcModuleScriptTags
|
|
|
|
$ddcModuleSdkOptions
|
|
// Create a self reference for JS interop tests that set fields on self.
|
|
$ddcModuleAssignGlobalSelf
|
|
|
|
// Invoke main through the d8 preamble to ensure the code is running
|
|
// within the fake event loop.
|
|
self.dartMainRunner(function () {
|
|
$ddcModuleRunMain
|
|
});
|
|
''';
|
|
var d8File = p.setExtension(entryPoint, '.d8.js');
|
|
File(d8File).writeAsStringSync(runjs);
|
|
var d8Binary = binary ?? p.join(dartCheckoutPath, _d8executable);
|
|
var process = await startProcess('D8', d8Binary, [
|
|
p.join(preamblesDir, 'seal_native_object.js'),
|
|
p.join(preamblesDir, 'd8.js'),
|
|
d8File
|
|
]);
|
|
if (await process.exitCode != 0) exit(await process.exitCode);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Converts a path to the expected default library name DDC will use.
|
|
String pathToLibName(String path) =>
|
|
js_names.pathToJSIdentifier(p.withoutExtension(
|
|
p.isWithin(p.current, path) ? p.relative(path) : p.absolute(path)));
|
|
|
|
String get _d8executable {
|
|
final arch = Abi.current().toString().split('_')[1];
|
|
if (Platform.isWindows) {
|
|
return p.join('third_party', 'd8', 'windows', arch, 'd8.exe');
|
|
} else if (Platform.isLinux) {
|
|
return p.join('third_party', 'd8', 'linux', arch, 'd8');
|
|
} else if (Platform.isMacOS) {
|
|
return p.join('third_party', 'd8', 'macos', arch, 'd8');
|
|
}
|
|
throw UnsupportedError('Unsupported platform.');
|
|
}
|
|
|
|
/// Maps supported unames to supported architectures.
|
|
final _resolvedUnames = {
|
|
'arm64': 'arm64',
|
|
'x86_64': 'x64',
|
|
'x64': 'x64',
|
|
};
|
|
|
|
/// Returns the location of the Dart SDK's build directory.
|
|
String resolveBuildDir(String sdkRoot, String? architecture) {
|
|
String platformString;
|
|
String archString;
|
|
if (Platform.isMacOS) {
|
|
platformString = 'xcodebuild';
|
|
var resolvedArchitecture = architecture;
|
|
if (architecture == null) {
|
|
var result = Process.runSync('uname', ['-m']).stdout as String;
|
|
final uname = result.trim();
|
|
resolvedArchitecture = _resolvedUnames[uname] ?? uname;
|
|
}
|
|
if (resolvedArchitecture == 'x64') {
|
|
archString = 'ReleaseX64';
|
|
} else if (resolvedArchitecture == 'arm64') {
|
|
archString = 'ReleaseARM64';
|
|
} else {
|
|
throw UnsupportedError(
|
|
'DDB does not currently support the architecture $architecture '
|
|
'on MacOS.');
|
|
}
|
|
} else if (Platform.isLinux || Platform.isWindows) {
|
|
platformString = 'out';
|
|
if (architecture != null && architecture != 'x64') {
|
|
throw UnsupportedError(
|
|
'DDB does not currently support the architecture $architecture '
|
|
'on Windows or Linux.');
|
|
}
|
|
archString = 'ReleaseX64';
|
|
} else {
|
|
throw UnsupportedError('Unsupported platform.');
|
|
}
|
|
return p.join(sdkRoot, platformString, archString);
|
|
}
|