1+ pub mod run;
2+
13use std:: env;
24use std:: path:: { Path , PathBuf } ;
35use std:: process:: { Command , Output } ;
46
57pub use wasmparser;
68
9+ pub use run:: { run, run_fail} ;
10+
711pub fn out_dir ( ) -> PathBuf {
812 env:: var_os ( "TMPDIR" ) . unwrap ( ) . into ( )
913}
@@ -24,65 +28,122 @@ fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> !
2428 std:: process:: exit ( 1 )
2529}
2630
27- pub fn rustc ( ) -> RustcInvocationBuilder {
28- RustcInvocationBuilder :: new ( )
31+ /// Construct a new `rustc` invocation.
32+ pub fn rustc ( ) -> Rustc {
33+ Rustc :: new ( )
2934}
3035
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 ( )
3339}
3440
41+ /// A `rustc` invocation builder.
3542#[ derive( Debug ) ]
36- pub struct RustcInvocationBuilder {
43+ pub struct Rustc {
3744 cmd : Command ,
3845}
3946
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 {
4252 let cmd = setup_common_build_cmd ( ) ;
4353 Self { cmd }
4454 }
4555
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) ;
4869 self
4970 }
5071
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" ) ;
5375 self
5476 }
5577
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+ }
6083
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
6697 }
67- }
6898
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+ }
73104
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
79110 }
80111
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+ ) ;
82120 self . cmd . arg ( arg) ;
83121 self
84122 }
85123
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.
86147 #[ track_caller]
87148 pub fn run ( & mut self ) -> Output {
88149 let caller_location = std:: panic:: Location :: caller ( ) ;
@@ -94,66 +155,10 @@ impl AuxBuildInvocationBuilder {
94155 }
95156 output
96157 }
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- } ) ;
121158
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
157163 }
158- output
159164}
0 commit comments