1+ pub mod run;
2+
13use std:: env;
24use std:: path:: { Path , PathBuf } ;
35use std:: process:: { Command , Output } ;
46
57pub use object;
68pub use wasmparser;
79
10+ pub use run:: { run, run_fail} ;
11+
812pub fn out_dir ( ) -> PathBuf {
913 env:: var_os ( "TMPDIR" ) . unwrap ( ) . into ( )
1014}
@@ -25,65 +29,122 @@ fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> !
2529 std:: process:: exit ( 1 )
2630}
2731
28- pub fn rustc ( ) -> RustcInvocationBuilder {
29- RustcInvocationBuilder :: new ( )
32+ /// Construct a new `rustc` invocation.
33+ pub fn rustc ( ) -> Rustc {
34+ Rustc :: new ( )
3035}
3136
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 ( )
3440}
3541
42+ /// A `rustc` invocation builder.
3643#[ derive( Debug ) ]
37- pub struct RustcInvocationBuilder {
44+ pub struct Rustc {
3845 cmd : Command ,
3946}
4047
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 {
4353 let cmd = setup_common_build_cmd ( ) ;
4454 Self { cmd }
4555 }
4656
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) ;
4970 self
5071 }
5172
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" ) ;
5476 self
5577 }
5678
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+ }
6184
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
6798 }
68- }
6999
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+ }
74105
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
80111 }
81112
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+ ) ;
83121 self . cmd . arg ( arg) ;
84122 self
85123 }
86124
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.
87148 #[ track_caller]
88149 pub fn run ( & mut self ) -> Output {
89150 let caller_location = std:: panic:: Location :: caller ( ) ;
@@ -95,66 +156,10 @@ impl AuxBuildInvocationBuilder {
95156 }
96157 output
97158 }
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- } ) ;
122159
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
158164 }
159- output
160165}
0 commit comments