10
10
11
11
// Context data structure used by rustpkg
12
12
13
- use std:: os ;
13
+ use std:: { io , os } ;
14
14
use extra:: workcache;
15
+ use rustc:: driver:: session:: { OptLevel , No } ;
15
16
16
17
#[ deriving( Clone ) ]
17
18
pub 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 ,
18
23
// If use_rust_path_hack is true, rustpkg searches for sources
19
24
// in *package* directories that are in the RUST_PATH (for example,
20
25
// FOO/src/bar-0.1 instead of FOO). The flag doesn't affect where
@@ -40,15 +45,82 @@ impl BuildContext {
40
45
pub fn sysroot_to_use ( & self ) -> Path {
41
46
self . context . sysroot_to_use ( )
42
47
}
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
43
117
}
44
118
45
119
impl Context {
46
120
pub fn sysroot ( & self ) -> Path {
47
121
self . sysroot . clone ( )
48
122
}
49
- }
50
123
51
- impl Context {
52
124
/// Debugging
53
125
pub fn sysroot_str ( & self ) -> ~str {
54
126
self . sysroot . to_str ( )
@@ -63,6 +135,15 @@ impl Context {
63
135
self . sysroot . pop ( ) . pop ( ) . pop ( )
64
136
}
65
137
}
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
+ }
66
147
}
67
148
68
149
/// We assume that if ../../rustc exists, then we're running
@@ -72,3 +153,141 @@ pub fn in_target(sysroot: &Path) -> bool {
72
153
debug ! ( "Checking whether %s is in target" , sysroot. to_str( ) ) ;
73
154
os:: path_is_dir ( & sysroot. pop ( ) . pop ( ) . push ( "rustc" ) )
74
155
}
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