3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
5
// Builds the wasmer runtime library, to by used by package:wasm. Requires
6
- // rustc, cargo, clang , and clang++. If a target triple is not specified, it
7
- // will default to the host target.
8
- // Usage: dart run wasm:setup [optional target-triple]
6
+ // Rust ( rustc, rustup, cargo) , and Clang ( clang, clang++, ar).
7
+ // Usage: dart run wasm:setup
8
+ // For more details use the --help option.
9
9
10
10
import 'dart:convert' ;
11
11
import 'dart:io' hide exit;
12
12
13
+ import 'package:args/args.dart' ;
13
14
import 'package:package_config/package_config.dart' show findPackageConfig;
14
15
import 'package:wasm/src/shared.dart' ;
15
16
16
- Future <void > main (List <String > args) async {
17
- if (args.length > 1 ) {
18
- print ('Usage: $invocationString [target-triple]' );
19
- exitCode = 64 ; // bad usage
17
+ Future <void > main (List <String > arguments) async {
18
+ final parser = ArgParser ()
19
+ ..addOption (
20
+ 'target' ,
21
+ abbr: 't' ,
22
+ help: 'Target triple. Defaults to host target.' ,
23
+ )
24
+ ..addOption (
25
+ 'out-dir' ,
26
+ abbr: 'o' ,
27
+ help: 'Output directory. Defaults to the directory that package:wasm '
28
+ 'searches.' ,
29
+ )
30
+ ..addOption (
31
+ 'rustc' ,
32
+ help: "Path of rustc. Defaults to assuming it's in PATH variable." ,
33
+ )
34
+ ..addOption (
35
+ 'rustup' ,
36
+ help: "Path of rustup. Defaults to assuming it's in PATH variable." ,
37
+ )
38
+ ..addOption (
39
+ 'cargo' ,
40
+ help: "Path of cargo. Defaults to assuming it's in PATH variable." ,
41
+ )
42
+ ..addOption (
43
+ 'clang' ,
44
+ help: "Path of clang. Defaults to assuming it's in PATH variable." ,
45
+ )
46
+ ..addOption (
47
+ 'clangpp' ,
48
+ help: "Path of clang++. Defaults to assuming it's in PATH variable." ,
49
+ )
50
+ ..addOption (
51
+ 'ar' ,
52
+ help: "Path of ar. Defaults to assuming it's in PATH variable." ,
53
+ )
54
+ ..addOption (
55
+ 'sysroot' ,
56
+ help: 'Sysroot argument passed to linker.' ,
57
+ )
58
+ ..addFlag (
59
+ 'help' ,
60
+ abbr: 'h' ,
61
+ negatable: false ,
62
+ help: 'Show this help.' ,
63
+ );
64
+ final args = parser.parse (arguments);
65
+
66
+ if (args['help' ] as bool ) {
67
+ print ('Usage: $invocationString [OPTION...]\n ' );
68
+ print (parser.usage);
69
+ exitCode = 0 ; // ok
20
70
return ;
21
71
}
22
72
23
- final target = args.isNotEmpty ? args[0 ] : await _getTargetTriple ();
24
-
25
73
try {
26
- await _main (target );
74
+ await _main (args );
27
75
} on ProcessException catch (e) {
28
76
final invocation = [e.executable, ...e.arguments].join (' ' );
29
77
print ('FAILED with exit code ${e .errorCode } `$invocation `' );
@@ -144,9 +192,9 @@ String _getWasmerLib(String os) {
144
192
return 'libwasmer.a' ;
145
193
}
146
194
147
- Future <String > _getTargetTriple () async {
195
+ Future <String > _getTargetTriple (String rustc ) async {
148
196
final _regexp = RegExp (r'^([^=]+)="(.*)"$' );
149
- final process = await Process .start (' rustc' , ['--print' , 'cfg' ]);
197
+ final process = await Process .start (rustc, ['--print' , 'cfg' ]);
150
198
final sub = process.stderr
151
199
.transform (utf8.decoder)
152
200
.transform (const LineSplitter ())
@@ -170,21 +218,42 @@ Future<String> _getTargetTriple() async {
170
218
.join ('-' );
171
219
}
172
220
173
- Future <void > _run (String exe, List <String > args) async {
221
+ Future <void > _run (
222
+ String exe,
223
+ List <String > args, {
224
+ Map <String , String >? environment,
225
+ }) async {
174
226
print ('\n $exe ${args .join (' ' )}\n ' );
175
- final process =
176
- await Process .start (exe, args, mode: ProcessStartMode .inheritStdio);
227
+ final process = await Process .start (
228
+ exe,
229
+ args,
230
+ mode: ProcessStartMode .inheritStdio,
231
+ environment: environment,
232
+ );
177
233
final result = await process.exitCode;
178
234
if (result != 0 ) {
179
235
throw ProcessException (exe, args, '' , result);
180
236
}
181
237
}
182
238
183
- Future <void > _main (String target) async {
239
+ String _toUpperUnderscore (String string) {
240
+ return string.toUpperCase ().replaceAll ('-' , '_' );
241
+ }
242
+
243
+ Future <void > _main (ArgResults args) async {
244
+ final rustc = args['rustc' ] as String ? ?? 'rustc' ;
245
+ final rustup = args['rustup' ] as String ? ?? 'rustup' ;
246
+ final cargo = args['cargo' ] as String ? ?? 'cargo' ;
247
+ final clang = args['clang' ] as String ? ?? 'clang' ;
248
+ final clangpp = args['clangpp' ] as String ? ?? 'clang++' ;
249
+
250
+ final target = args['target' ] as String ? ?? await _getTargetTriple (rustc);
184
251
final sdkDir = _getSdkDir ();
185
252
final sdkIncDir = _getSdkIncDir (sdkDir);
186
253
final srcDir = await _getSrcDir ();
187
- final outDir = _getOutDir (Directory .current.uri);
254
+ final outDir = args['out-dir' ] != null
255
+ ? Uri .directory (args['out-dir' ] as String )
256
+ : _getOutDir (Directory .current.uri);
188
257
final os = _getOsFromTarget (target);
189
258
final outLib = outDir.resolve (_getOutLib (os)).toFilePath ();
190
259
@@ -196,17 +265,32 @@ Future<void> _main(String target) async {
196
265
print ('OS: $os ' );
197
266
print ('Output library: $outLib ' );
198
267
268
+ // Make sure rust libs are installed for the target.
269
+ await _run (rustup, ['target' , 'add' , target]);
270
+
199
271
// Build wasmer crate.
200
- await _run ('cargo' , [
201
- 'build' ,
202
- '--target' ,
203
- target,
204
- '--target-dir' ,
205
- outDir.toFilePath (),
206
- '--manifest-path' ,
207
- srcDir.resolve ('Cargo.toml' ).toFilePath (),
208
- '--release'
209
- ]);
272
+ await _run (
273
+ cargo,
274
+ [
275
+ 'build' ,
276
+ '--target' ,
277
+ target,
278
+ '--target-dir' ,
279
+ outDir.toFilePath (),
280
+ '--manifest-path' ,
281
+ srcDir.resolve ('Cargo.toml' ).toFilePath (),
282
+ '--release'
283
+ ],
284
+ environment: {
285
+ if (args['clangpp' ] != null ) ...{
286
+ 'CC' : clangpp,
287
+ 'CXX' : clangpp,
288
+ 'LINKER' : clangpp,
289
+ 'CARGO_TARGET_${_toUpperUnderscore (target )}_LINKER' : clangpp,
290
+ },
291
+ if (args['ar' ] != null ) 'AR' : args['ar' ] as String ,
292
+ },
293
+ );
210
294
211
295
// Hack around a bug with dart_api_dl_impl.h include path in dart_api_dl.c.
212
296
const dartApiDlImplPath = 'include/internal/dart_api_dl_impl.h' ;
@@ -218,7 +302,7 @@ Future<void> _main(String target) async {
218
302
}
219
303
220
304
// Build dart_api_dl.o.
221
- await _run (' clang' , [
305
+ await _run (clang, [
222
306
'-DDART_SHARED_LIB' ,
223
307
'-DNDEBUG' ,
224
308
'-fno-exceptions' ,
@@ -237,7 +321,7 @@ Future<void> _main(String target) async {
237
321
]);
238
322
239
323
// Build finalizers.o.
240
- await _run ('clang++' , [
324
+ await _run (clangpp , [
241
325
'-DDART_SHARED_LIB' ,
242
326
'-DNDEBUG' ,
243
327
'-fno-exceptions' ,
@@ -258,8 +342,9 @@ Future<void> _main(String target) async {
258
342
]);
259
343
260
344
// Link wasmer, dart_api_dl, and finalizers to create the output library.
261
- await _run (' clang++' , [
345
+ await _run (clang, [
262
346
'-shared' ,
347
+ if (args['sysroot' ] != null ) '--sysroot=${args ['sysroot' ]}' ,
263
348
if (os != 'windows' ) '-fPIC' ,
264
349
if (os == 'windows' ) ...[
265
350
'-lws2_32' ,
@@ -271,6 +356,7 @@ Future<void> _main(String target) async {
271
356
'-z' ,
272
357
'/NODEFAULTLIB:MSVCRT' ,
273
358
],
359
+ '-lm' ,
274
360
'-target' ,
275
361
target,
276
362
outDir.resolve ('dart_api_dl.o' ).toFilePath (),
0 commit comments