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