1
+ use anyhow:: { bail, Context , Result } ;
1
2
use std:: env;
2
3
use std:: fs;
3
- use std:: io:: { Read , Write } ;
4
+ use std:: io:: Write ;
4
5
use std:: process:: { Command , Stdio } ;
5
6
6
7
fn compile ( args : & [ & str ] , src : & str ) -> Vec < u8 > {
@@ -22,11 +23,16 @@ impl Project {
22
23
}
23
24
24
25
fn compile ( & self , args : & [ & str ] , src : & str ) -> Vec < u8 > {
26
+ self . try_compile ( args, src, true ) . unwrap ( )
27
+ }
28
+
29
+ fn try_compile ( & self , args : & [ & str ] , src : & str , inherit_stderr : bool ) -> Result < Vec < u8 > > {
25
30
let mut myself = env:: current_exe ( ) . unwrap ( ) ;
26
31
myself. pop ( ) ; // exe name
27
32
myself. pop ( ) ; // 'deps'
28
33
myself. push ( "wasm-component-ld" ) ;
29
- let mut rustc = Command :: new ( "rustc" )
34
+ let mut rustc = Command :: new ( "rustc" ) ;
35
+ rustc
30
36
. arg ( "--target" )
31
37
. arg ( "wasm32-wasip1" )
32
38
. arg ( "-" )
@@ -35,22 +41,40 @@ impl Project {
35
41
. arg ( "-C" )
36
42
. arg ( & format ! ( "linker={}" , myself. to_str( ) . unwrap( ) ) )
37
43
. args ( args)
38
- . current_dir ( self . tempdir . path ( ) )
39
- . stdout ( Stdio :: piped ( ) )
40
44
. stdin ( Stdio :: piped ( ) )
41
- . spawn ( )
42
- . expect ( "failed to spawn rustc" ) ;
45
+ . stdout ( Stdio :: piped ( ) )
46
+ . current_dir ( self . tempdir . path ( ) ) ;
47
+ if !inherit_stderr {
48
+ rustc. stderr ( Stdio :: piped ( ) ) ;
49
+ }
50
+ let mut rustc = rustc. spawn ( ) . context ( "failed to spawn rustc" ) ?;
43
51
44
52
rustc
45
53
. stdin
46
54
. take ( )
47
- . unwrap ( )
55
+ . context ( "stdin should be present" ) ?
48
56
. write_all ( src. as_bytes ( ) )
49
- . unwrap ( ) ;
50
- let mut ret = Vec :: new ( ) ;
51
- rustc. stdout . take ( ) . unwrap ( ) . read_to_end ( & mut ret) . unwrap ( ) ;
52
- assert ! ( rustc. wait( ) . unwrap( ) . success( ) ) ;
53
- ret
57
+ . context ( "failed to write stdin" ) ?;
58
+ let output = rustc
59
+ . wait_with_output ( )
60
+ . context ( "failed to wait for subprocess" ) ?;
61
+ if !output. status . success ( ) {
62
+ let mut error = format ! ( "subprocess failed: {:?}" , output. status) ;
63
+ if !output. stdout . is_empty ( ) {
64
+ error. push_str ( & format ! (
65
+ "\n stdout: {}" ,
66
+ String :: from_utf8_lossy( & output. stdout)
67
+ ) ) ;
68
+ }
69
+ if !output. stderr . is_empty ( ) {
70
+ error. push_str ( & format ! (
71
+ "\n stderr: {}" ,
72
+ String :: from_utf8_lossy( & output. stderr)
73
+ ) ) ;
74
+ }
75
+ bail ! ( "{error}" )
76
+ }
77
+ Ok ( output. stdout )
54
78
}
55
79
}
56
80
@@ -227,3 +251,35 @@ fn rustc_using_argfile() {
227
251
let output = p. compile ( & [ "-Ccodegen-units=1000" , "-Clink-arg=@args" ] , & src) ;
228
252
assert_module ( & output) ;
229
253
}
254
+
255
+ #[ test]
256
+ fn hello_world_with_realloc_as_memory_grow ( ) {
257
+ let output = compile (
258
+ & [ "-Clink-arg=--realloc-via-memory-grow" ] ,
259
+ r#"
260
+ fn main() {
261
+ println!("hello!");
262
+ }
263
+ "# ,
264
+ ) ;
265
+ assert_component ( & output) ;
266
+ }
267
+
268
+ // The adapter uses legacy names, so this option will always result in an error
269
+ // right now.
270
+ #[ test]
271
+ fn legacy_names_currently_required ( ) {
272
+ let result = Project :: new ( ) . try_compile (
273
+ & [ "-Clink-arg=--reject-legacy-names" ] ,
274
+ r#"
275
+ fn main() {
276
+ println!("hello!");
277
+ }
278
+ "# ,
279
+ false ,
280
+ ) ;
281
+ let err = result. unwrap_err ( ) ;
282
+ let err = format ! ( "{err:?}" ) ;
283
+ println ! ( "error: {err}" ) ;
284
+ assert ! ( err. contains( "unknown or invalid component model import syntax" ) ) ;
285
+ }
0 commit comments