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