1010
1111// Context data structure used by rustpkg
1212
13- use std:: os ;
13+ use std:: { io , os } ;
1414use extra:: workcache;
15+ use rustc:: driver:: session:: { OptLevel , No } ;
1516
1617#[ deriving( Clone ) ]
1718pub struct Context {
19+ // Config strings that the user passed in with --cfg
20+ cfgs : ~[ ~str ] ,
21+ // Flags to pass to rustc
22+ rustc_flags : RustcFlags ,
1823 // If use_rust_path_hack is true, rustpkg searches for sources
1924 // in *package* directories that are in the RUST_PATH (for example,
2025 // FOO/src/bar-0.1 instead of FOO). The flag doesn't affect where
@@ -40,15 +45,82 @@ impl BuildContext {
4045 pub fn sysroot_to_use ( & self ) -> Path {
4146 self . context . sysroot_to_use ( )
4247 }
48+
49+ /// Returns the flags to pass to rustc, as a vector of strings
50+ pub fn flag_strs ( & self ) -> ~[ ~str ] {
51+ self . context . flag_strs ( )
52+ }
53+
54+ pub fn compile_upto ( & self ) -> StopBefore {
55+ self . context . compile_upto ( )
56+ }
57+ }
58+
59+ /*
60+ Deliberately unsupported rustc flags:
61+ --bin, --lib inferred from crate file names
62+ -L inferred from extern mods
63+ --out-dir inferred from RUST_PATH
64+ --test use `rustpkg test`
65+ -v -h --ls don't make sense with rustpkg
66+ -W -A -D -F - use pragmas instead
67+
68+ rustc flags that aren't implemented yet:
69+ --passes
70+ --llvm-arg
71+ --target-feature
72+ --android-cross-path
73+ */
74+ pub struct RustcFlags {
75+ compile_upto : StopBefore ,
76+ // Linker to use with the --linker flag
77+ linker : Option < ~str > ,
78+ // Extra arguments to pass to rustc with the --link-args flag
79+ link_args : Option < ~str > ,
80+ // Optimization level. 0 = default. -O = 2.
81+ optimization_level : OptLevel ,
82+ // True if the user passed in --save-temps
83+ save_temps : bool ,
84+ // Target (defaults to rustc's default target)
85+ target : Option < ~str > ,
86+ // Target CPU (defaults to rustc's default target CPU)
87+ target_cpu : Option < ~str > ,
88+ // Any -Z features
89+ experimental_features : Option < ~[ ~str ] >
90+ }
91+
92+ impl Clone for RustcFlags {
93+ fn clone ( & self ) -> RustcFlags {
94+ RustcFlags {
95+ compile_upto : self . compile_upto ,
96+ linker : self . linker . clone ( ) ,
97+ link_args : self . link_args . clone ( ) ,
98+ optimization_level : self . optimization_level ,
99+ save_temps : self . save_temps ,
100+ target : self . target . clone ( ) ,
101+ target_cpu : self . target_cpu . clone ( ) ,
102+ experimental_features : self . experimental_features . clone ( )
103+ }
104+ }
105+ }
106+
107+ #[ deriving( Eq ) ]
108+ pub enum StopBefore {
109+ Nothing , // compile everything
110+ Link , // --no-link
111+ LLVMCompileBitcode , // --emit-llvm without -S
112+ LLVMAssemble , // -S --emit-llvm
113+ Assemble , // -S without --emit-llvm
114+ Trans , // --no-trans
115+ Pretty , // --pretty
116+ Analysis , // --parse-only
43117}
44118
45119impl Context {
46120 pub fn sysroot ( & self ) -> Path {
47121 self . sysroot . clone ( )
48122 }
49- }
50123
51- impl Context {
52124 /// Debugging
53125 pub fn sysroot_str ( & self ) -> ~str {
54126 self . sysroot . to_str ( )
@@ -63,6 +135,15 @@ impl Context {
63135 self . sysroot . pop ( ) . pop ( ) . pop ( )
64136 }
65137 }
138+
139+ /// Returns the flags to pass to rustc, as a vector of strings
140+ pub fn flag_strs ( & self ) -> ~[ ~str ] {
141+ self . rustc_flags . flag_strs ( )
142+ }
143+
144+ pub fn compile_upto ( & self ) -> StopBefore {
145+ self . rustc_flags . compile_upto
146+ }
66147}
67148
68149/// We assume that if ../../rustc exists, then we're running
@@ -72,3 +153,141 @@ pub fn in_target(sysroot: &Path) -> bool {
72153 debug ! ( "Checking whether %s is in target" , sysroot. to_str( ) ) ;
73154 os:: path_is_dir ( & sysroot. pop ( ) . pop ( ) . push ( "rustc" ) )
74155}
156+
157+ impl RustcFlags {
158+ fn flag_strs ( & self ) -> ~[ ~str ] {
159+ let linker_flag = match self . linker {
160+ Some ( ref l) => ~[ ~"--linker", l. clone ( ) ] ,
161+ None => ~[ ]
162+ } ;
163+ let link_args_flag = match self . link_args {
164+ Some ( ref l) => ~[ ~"--link-args", l. clone ( ) ] ,
165+ None => ~[ ]
166+ } ;
167+ let save_temps_flag = if self . save_temps { ~[ ~"--save-temps"] } else { ~[ ] } ;
168+ let target_flag = match self . target {
169+ Some ( ref l) => ~[ ~"--target", l. clone ( ) ] ,
170+ None => ~[ ]
171+ } ;
172+ let target_cpu_flag = match self . target_cpu {
173+ Some ( ref l) => ~[ ~"--target-cpu", l. clone ( ) ] ,
174+ None => ~[ ]
175+ } ;
176+ let z_flags = match self . experimental_features {
177+ Some ( ref ls) => ls. flat_map ( |s| ~[ ~"-Z ", s. clone ( ) ] ) ,
178+ None => ~[ ]
179+ } ;
180+ linker_flag
181+ + link_args_flag
182+ + save_temps_flag
183+ + target_flag
184+ + target_cpu_flag
185+ + z_flags + ( match self . compile_upto {
186+ LLVMCompileBitcode => ~[ ~"--emit-llvm"] ,
187+ LLVMAssemble => ~[ ~"--emit-llvm", ~"-S "] ,
188+ Link => ~[ ~"-c"],
189+ Trans => ~[~" --no-trans"] ,
190+ Assemble => ~[ ~"-S "] ,
191+ // n.b. Doesn't support all flavors of --pretty (yet)
192+ Pretty => ~[ ~"--pretty"] ,
193+ Analysis => ~[ ~"--parse-only"] ,
194+ Nothing => ~[ ]
195+ } )
196+ }
197+
198+ pub fn default ( ) -> RustcFlags {
199+ RustcFlags {
200+ linker : None ,
201+ link_args : None ,
202+ compile_upto : Nothing ,
203+ optimization_level : No ,
204+ save_temps : false ,
205+ target : None ,
206+ target_cpu : None ,
207+ experimental_features : None
208+ }
209+ }
210+ }
211+
212+ /// Returns true if any of the flags given are incompatible with the cmd
213+ pub fn flags_ok_for_cmd ( flags : & RustcFlags ,
214+ cfgs : & [ ~str ] ,
215+ cmd : & str , user_supplied_opt_level : bool ) -> bool {
216+ let complain = |s| {
217+ io:: println ( fmt ! ( "The %s option can only be used with the build command:
218+ rustpkg [options..] build %s [package-ID]" , s, s) ) ;
219+ } ;
220+
221+ if flags. linker . is_some ( ) && cmd != "build" && cmd != "install" {
222+ io:: println ( "The --linker option can only be used with the build or install commands." ) ;
223+ return true ;
224+ }
225+ if flags. link_args . is_some ( ) && cmd != "build" && cmd != "install" {
226+ io:: println ( "The --link-args option can only be used with the build or install commands." ) ;
227+ return true ;
228+ }
229+
230+ if !cfgs. is_empty ( ) && cmd != "build" && cmd != "install" {
231+ io:: println ( "The --cfg option can only be used with the build or install commands." ) ;
232+ return true ;
233+ }
234+
235+ if user_supplied_opt_level && cmd != "build" && cmd != "install" {
236+ io:: println ( "The -O and --opt-level options can only be used with the build \
237+ or install commands.") ;
238+ return true ;
239+ }
240+
241+ if flags. save_temps && cmd != "build" && cmd != "install" {
242+ io:: println ( "The --save-temps option can only be used with the build \
243+ or install commands.") ;
244+ return true ;
245+ }
246+
247+ if flags. target . is_some ( ) && cmd != "build" && cmd != "install" {
248+ io:: println ( "The --target option can only be used with the build \
249+ or install commands.") ;
250+ return true ;
251+ }
252+ if flags. target_cpu . is_some ( ) && cmd != "build" && cmd != "install" {
253+ io:: println ( "The --target-cpu option can only be used with the build \
254+ or install commands.") ;
255+ return true ;
256+ }
257+ if flags. experimental_features . is_some ( ) && cmd != "build" && cmd != "install" {
258+ io:: println ( "The -Z option can only be used with the build or install commands." ) ;
259+ return true ;
260+ }
261+
262+ match flags. compile_upto {
263+ Link if cmd != "build" => {
264+ complain ( "--no-link" ) ;
265+ true
266+ }
267+ Trans if cmd != "build" => {
268+ complain ( "--no-trans" ) ;
269+ true
270+ }
271+ Assemble if cmd != "build" => {
272+ complain ( "-S" ) ;
273+ true
274+ }
275+ Pretty if cmd != "build" => {
276+ complain ( "--pretty" ) ;
277+ true
278+ }
279+ Analysis if cmd != "build" => {
280+ complain ( "--parse-only" ) ;
281+ true
282+ }
283+ LLVMCompileBitcode if cmd != "build" => {
284+ complain ( "--emit-llvm" ) ;
285+ true
286+ }
287+ LLVMAssemble if cmd != "build" => {
288+ complain ( "--emit-llvm" ) ;
289+ true
290+ }
291+ _ => false
292+ }
293+ }
0 commit comments