1
+ pub mod run;
2
+
1
3
use std:: env;
2
4
use std:: path:: { Path , PathBuf } ;
3
5
use std:: process:: { Command , Output } ;
4
6
5
7
pub use wasmparser;
6
8
9
+ pub use run:: { run, run_fail} ;
10
+
7
11
pub fn out_dir ( ) -> PathBuf {
8
12
env:: var_os ( "TMPDIR" ) . unwrap ( ) . into ( )
9
13
}
@@ -24,65 +28,122 @@ fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> !
24
28
std:: process:: exit ( 1 )
25
29
}
26
30
27
- pub fn rustc ( ) -> RustcInvocationBuilder {
28
- RustcInvocationBuilder :: new ( )
31
+ /// Construct a new `rustc` invocation.
32
+ pub fn rustc ( ) -> Rustc {
33
+ Rustc :: new ( )
29
34
}
30
35
31
- pub fn aux_build ( ) -> AuxBuildInvocationBuilder {
32
- AuxBuildInvocationBuilder :: new ( )
36
+ /// Construct a new `rustc` aux-build invocation.
37
+ pub fn aux_build ( ) -> Rustc {
38
+ Rustc :: new_aux_build ( )
33
39
}
34
40
41
+ /// A `rustc` invocation builder.
35
42
#[ derive( Debug ) ]
36
- pub struct RustcInvocationBuilder {
43
+ pub struct Rustc {
37
44
cmd : Command ,
38
45
}
39
46
40
- impl RustcInvocationBuilder {
41
- fn new ( ) -> Self {
47
+ impl Rustc {
48
+ // `rustc` invocation constructor methods
49
+
50
+ /// Construct a new `rustc` invocation.
51
+ pub fn new ( ) -> Self {
42
52
let cmd = setup_common_build_cmd ( ) ;
43
53
Self { cmd }
44
54
}
45
55
46
- pub fn arg ( & mut self , arg : & str ) -> & mut RustcInvocationBuilder {
47
- self . cmd . arg ( arg) ;
56
+ /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
57
+ pub fn new_aux_build ( ) -> Self {
58
+ let mut cmd = setup_common_build_cmd ( ) ;
59
+ cmd. arg ( "--crate-type=lib" ) ;
60
+ Self { cmd }
61
+ }
62
+
63
+ // Argument provider methods
64
+
65
+ /// Configure the compilation environment.
66
+ pub fn cfg ( & mut self , s : & str ) -> & mut Self {
67
+ self . cmd . arg ( "--cfg" ) ;
68
+ self . cmd . arg ( s) ;
48
69
self
49
70
}
50
71
51
- pub fn args ( & mut self , args : & [ & str ] ) -> & mut RustcInvocationBuilder {
52
- self . cmd . args ( args) ;
72
+ /// Specify default optimization level `-O` (alias for `-C opt-level=2`).
73
+ pub fn opt ( & mut self ) -> & mut Self {
74
+ self . cmd . arg ( "-O" ) ;
53
75
self
54
76
}
55
77
56
- #[ track_caller]
57
- pub fn run ( & mut self ) -> Output {
58
- let caller_location = std:: panic:: Location :: caller ( ) ;
59
- let caller_line_number = caller_location. line ( ) ;
78
+ /// Specify type(s) of output files to generate.
79
+ pub fn emit ( & mut self , kinds : & str ) -> & mut Self {
80
+ self . cmd . arg ( format ! ( "--emit={kinds}" ) ) ;
81
+ self
82
+ }
60
83
61
- let output = self . cmd . output ( ) . unwrap ( ) ;
62
- if !output. status . success ( ) {
63
- handle_failed_output ( & format ! ( "{:#?}" , self . cmd) , output, caller_line_number) ;
64
- }
65
- output
84
+ /// Specify where an external library is located.
85
+ pub fn extern_ < P : AsRef < Path > > ( & mut self , crate_name : & str , path : P ) -> & mut Self {
86
+ assert ! (
87
+ !crate_name. contains( |c: char | c. is_whitespace( ) || c == '\\' || c == '/' ) ,
88
+ "crate name cannot contain whitespace or path separators"
89
+ ) ;
90
+
91
+ let path = path. as_ref ( ) . to_string_lossy ( ) ;
92
+
93
+ self . cmd . arg ( "--extern" ) ;
94
+ self . cmd . arg ( format ! ( "{crate_name}={path}" ) ) ;
95
+
96
+ self
66
97
}
67
- }
68
98
69
- #[ derive( Debug ) ]
70
- pub struct AuxBuildInvocationBuilder {
71
- cmd : Command ,
72
- }
99
+ /// Specify path to the input file.
100
+ pub fn input < P : AsRef < Path > > ( & mut self , path : P ) -> & mut Self {
101
+ self . cmd . arg ( path. as_ref ( ) ) ;
102
+ self
103
+ }
73
104
74
- impl AuxBuildInvocationBuilder {
75
- fn new ( ) -> Self {
76
- let mut cmd = setup_common_build_cmd ( ) ;
77
- cmd. arg ( "--crate-type=lib" ) ;
78
- Self { cmd }
105
+ /// Specify target triple.
106
+ pub fn target ( & mut self , target : & str ) -> & mut Self {
107
+ assert ! ( !target . contains ( char :: is_whitespace ) , "target triple cannot contain spaces" ) ;
108
+ self . cmd . arg ( format ! ( "--target={target}" ) ) ;
109
+ self
79
110
}
80
111
81
- pub fn arg ( & mut self , arg : & str ) -> & mut AuxBuildInvocationBuilder {
112
+ /// Generic command argument provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`.
113
+ /// This method will panic if a plain `-Z` or `-C` is passed, or if `-Z <name>` or `-C <name>`
114
+ /// is passed (note the space).
115
+ pub fn arg ( & mut self , arg : & str ) -> & mut Self {
116
+ assert ! (
117
+ !( [ "-Z" , "-C" ] . contains( & arg) || arg. starts_with( "-Z " ) || arg. starts_with( "-C " ) ) ,
118
+ "use `-Zarg` or `-Carg` over split `-Z` `arg` or `-C` `arg`"
119
+ ) ;
82
120
self . cmd . arg ( arg) ;
83
121
self
84
122
}
85
123
124
+ /// Generic command arguments provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`.
125
+ /// This method will panic if a plain `-Z` or `-C` is passed, or if `-Z <name>` or `-C <name>`
126
+ /// is passed (note the space).
127
+ pub fn args ( & mut self , args : & [ & str ] ) -> & mut Self {
128
+ for arg in args {
129
+ assert ! (
130
+ !( [ "-Z" , "-C" ] . contains( & arg) || arg. starts_with( "-Z " ) || arg. starts_with( "-C " ) ) ,
131
+ "use `-Zarg` or `-Carg` over split `-Z` `arg` or `-C` `arg`"
132
+ ) ;
133
+ }
134
+
135
+ self . cmd . args ( args) ;
136
+ self
137
+ }
138
+
139
+ // Command inspection, output and running helper methods
140
+
141
+ /// Get the [`Output`][std::process::Output] of the finished `rustc` process.
142
+ pub fn output ( & mut self ) -> Output {
143
+ self . cmd . output ( ) . unwrap ( )
144
+ }
145
+
146
+ /// Run the constructed `rustc` command and assert that it is successfully run.
86
147
#[ track_caller]
87
148
pub fn run ( & mut self ) -> Output {
88
149
let caller_location = std:: panic:: Location :: caller ( ) ;
@@ -94,66 +155,10 @@ impl AuxBuildInvocationBuilder {
94
155
}
95
156
output
96
157
}
97
- }
98
-
99
- fn run_common ( bin_name : & str ) -> ( Command , Output ) {
100
- let target = env:: var ( "TARGET" ) . unwrap ( ) ;
101
-
102
- let bin_name =
103
- if target. contains ( "windows" ) { format ! ( "{}.exe" , bin_name) } else { bin_name. to_owned ( ) } ;
104
-
105
- let mut bin_path = PathBuf :: new ( ) ;
106
- bin_path. push ( env:: var ( "TMPDIR" ) . unwrap ( ) ) ;
107
- bin_path. push ( & bin_name) ;
108
- let ld_lib_path_envvar = env:: var ( "LD_LIB_PATH_ENVVAR" ) . unwrap ( ) ;
109
- let mut cmd = Command :: new ( bin_path) ;
110
- cmd. env ( & ld_lib_path_envvar, {
111
- let mut paths = vec ! [ ] ;
112
- paths. push ( PathBuf :: from ( env:: var ( "TMPDIR" ) . unwrap ( ) ) ) ;
113
- for p in env:: split_paths ( & env:: var ( "TARGET_RPATH_ENV" ) . unwrap ( ) ) {
114
- paths. push ( p. to_path_buf ( ) ) ;
115
- }
116
- for p in env:: split_paths ( & env:: var ( & ld_lib_path_envvar) . unwrap ( ) ) {
117
- paths. push ( p. to_path_buf ( ) ) ;
118
- }
119
- env:: join_paths ( paths. iter ( ) ) . unwrap ( )
120
- } ) ;
121
158
122
- if target. contains ( "windows" ) {
123
- let mut paths = vec ! [ ] ;
124
- for p in env:: split_paths ( & std:: env:: var ( "PATH" ) . unwrap_or ( String :: new ( ) ) ) {
125
- paths. push ( p. to_path_buf ( ) ) ;
126
- }
127
- paths. push ( Path :: new ( & std:: env:: var ( "TARGET_RPATH_DIR" ) . unwrap ( ) ) . to_path_buf ( ) ) ;
128
- cmd. env ( "PATH" , env:: join_paths ( paths. iter ( ) ) . unwrap ( ) ) ;
129
- }
130
-
131
- let output = cmd. output ( ) . unwrap ( ) ;
132
- ( cmd, output)
133
- }
134
-
135
- /// Run a built binary and make sure it succeeds.
136
- #[ track_caller]
137
- pub fn run ( bin_name : & str ) -> Output {
138
- let caller_location = std:: panic:: Location :: caller ( ) ;
139
- let caller_line_number = caller_location. line ( ) ;
140
-
141
- let ( cmd, output) = run_common ( bin_name) ;
142
- if !output. status . success ( ) {
143
- handle_failed_output ( & format ! ( "{:#?}" , cmd) , output, caller_line_number) ;
144
- }
145
- output
146
- }
147
-
148
- /// Run a built binary and make sure it fails.
149
- #[ track_caller]
150
- pub fn run_fail ( bin_name : & str ) -> Output {
151
- let caller_location = std:: panic:: Location :: caller ( ) ;
152
- let caller_line_number = caller_location. line ( ) ;
153
-
154
- let ( cmd, output) = run_common ( bin_name) ;
155
- if output. status . success ( ) {
156
- handle_failed_output ( & format ! ( "{:#?}" , cmd) , output, caller_line_number) ;
159
+ /// Inspect what the underlying [`Command`] is up to the current construction.
160
+ pub fn inspect ( & mut self , f : impl FnOnce ( & Command ) ) -> & mut Self {
161
+ f ( & self . cmd ) ;
162
+ self
157
163
}
158
- output
159
164
}
0 commit comments