d0e1be5c99
This replaces third_party/wasmer and the related build rules, so I'll delete that stuff once the package is published. Bug: https://github.com/dart-lang/sdk/issues/37882 Change-Id: I33728e42c734bc8c25a2d32522112f2a3dbf4384 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180446 Commit-Queue: Liam Appelbe <liama@google.com> Reviewed-by: Siva Annamalai <asiva@google.com>
166 lines
4.5 KiB
Dart
166 lines
4.5 KiB
Dart
// Copyright (c) 2021, 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.
|
|
|
|
// Builds the wasmer runtime library, to by used by package:wasm. Requires
|
|
// rustc, cargo, clang, and clang++. If a target triple is not specified, it
|
|
// will default to the host target.
|
|
// Usage: dart setup.dart [target-triple]
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
Uri getSdkDir() {
|
|
// The common case, and how cli_util.dart computes the Dart SDK directory,
|
|
// path.dirname called twice on Platform.resolvedExecutable.
|
|
final exe = Uri.file(Platform.resolvedExecutable);
|
|
final commonSdkDir = exe.resolve('../..');
|
|
if (Directory(commonSdkDir.path).existsSync()) {
|
|
return commonSdkDir;
|
|
}
|
|
|
|
// This is the less common case where the user is in the checked out Dart
|
|
// SDK, and is executing dart via:
|
|
// ./out/ReleaseX64/dart ...
|
|
final checkedOutSdkDir = exe.resolve('../dart-sdk');
|
|
if (Directory(checkedOutSdkDir.path).existsSync()) {
|
|
return checkedOutSdkDir;
|
|
}
|
|
|
|
// If neither returned above, we return the common case:
|
|
return commonSdkDir;
|
|
}
|
|
|
|
String getOutLib(String target) {
|
|
final os = RegExp(r'^.*-.*-(.*)').firstMatch(target)?.group(1) ?? '';
|
|
if (os == 'darwin' || os == 'ios') {
|
|
return 'libwasmer.dylib';
|
|
} else if (os == 'windows') {
|
|
return 'wasmer.dll';
|
|
}
|
|
return 'libwasmer.so';
|
|
}
|
|
|
|
getTargetTriple() async {
|
|
final process = await Process.start('rustc', ['--print', 'cfg']);
|
|
process.stderr
|
|
.transform(utf8.decoder)
|
|
.transform(const LineSplitter())
|
|
.listen((line) => stderr.writeln(line));
|
|
final cfg = {};
|
|
await process.stdout
|
|
.transform(utf8.decoder)
|
|
.transform(const LineSplitter())
|
|
.listen((line) {
|
|
final match = RegExp(r'^([^=]+)="(.*)"$').firstMatch(line);
|
|
if (match != null) cfg[match.group(1)] = match.group(2);
|
|
}).asFuture();
|
|
String arch = cfg['target_arch'] ?? 'unknown';
|
|
String vendor = cfg['target_vendor'] ?? 'unknown';
|
|
String os = cfg['target_os'] ?? 'unknown';
|
|
String env = cfg['target_env'] ?? 'unknown';
|
|
return '$arch-$vendor-$os-$env';
|
|
}
|
|
|
|
run(String exe, List<String> args) async {
|
|
print('\n$exe ${args.join(' ')}\n');
|
|
final process = await Process.start(exe, args);
|
|
process.stdout
|
|
.transform(utf8.decoder)
|
|
.transform(const LineSplitter())
|
|
.listen((line) => print(line));
|
|
process.stderr
|
|
.transform(utf8.decoder)
|
|
.transform(const LineSplitter())
|
|
.listen((line) => stderr.writeln(line));
|
|
final exitCode = await process.exitCode;
|
|
if (exitCode != 0) {
|
|
print('Command failed with exit code ${exitCode}');
|
|
exit(exitCode);
|
|
}
|
|
}
|
|
|
|
main(List<String> args) async {
|
|
if (args.length > 1) {
|
|
print('Usage: dart setup.dart [target-triple]');
|
|
exit(1);
|
|
}
|
|
|
|
final target = args.length >= 1 ? args[0] : await getTargetTriple();
|
|
final sdkDir = getSdkDir();
|
|
final binDir = Platform.script;
|
|
final outLib = binDir.resolve('out/' + getOutLib(target)).path;
|
|
|
|
print('Dart SDK directory: ${sdkDir.path}');
|
|
print('Script directory: ${binDir.path}');
|
|
print('Target: $target');
|
|
print('Output library: $outLib');
|
|
|
|
// Build wasmer crate.
|
|
await run('cargo', [
|
|
'build',
|
|
'--target',
|
|
target,
|
|
'--target-dir',
|
|
binDir.resolve('out').path,
|
|
'--manifest-path',
|
|
binDir.resolve('Cargo.toml').path,
|
|
'--release'
|
|
]);
|
|
|
|
// Build dart_api_dl.o.
|
|
await run('clang', [
|
|
'-DDART_SHARED_LIB',
|
|
'-DNDEBUG',
|
|
'-fno-exceptions',
|
|
'-fPIC',
|
|
'-O3',
|
|
'-target',
|
|
target,
|
|
'-c',
|
|
sdkDir.resolve('runtime/include/dart_api_dl.c').path,
|
|
'-o',
|
|
binDir.resolve('out/dart_api_dl.o').path
|
|
]);
|
|
|
|
// Build finalizers.o.
|
|
await run('clang++', [
|
|
'-DDART_SHARED_LIB',
|
|
'-DNDEBUG',
|
|
'-fno-exceptions',
|
|
'-fno-rtti',
|
|
'-fPIC',
|
|
'-O3',
|
|
'-std=c++11',
|
|
'-target',
|
|
target,
|
|
'-I',
|
|
sdkDir.resolve('runtime').path,
|
|
'-c',
|
|
binDir.resolve('finalizers.cc').path,
|
|
'-o',
|
|
binDir.resolve('out/finalizers.o').path
|
|
]);
|
|
|
|
// Link wasmer, dart_api_dl, and finalizers to create the output library.
|
|
await run('clang++', [
|
|
'-shared',
|
|
'-Wl,--no-as-needed',
|
|
'-Wl,--fatal-warnings',
|
|
'-Wl,-z,now',
|
|
'-Wl,-z,noexecstack',
|
|
'-Wl,-z,relro',
|
|
'-Wl,--build-id=none',
|
|
'-fPIC',
|
|
'-Wl,-O1',
|
|
'-Wl,--gc-sections',
|
|
'-target',
|
|
target,
|
|
binDir.resolve('out/dart_api_dl.o').path,
|
|
binDir.resolve('out/finalizers.o').path,
|
|
binDir.resolve('out/' + target + '/release/libwasmer.a').path,
|
|
'-o',
|
|
outLib
|
|
]);
|
|
}
|