@@ -22,6 +22,7 @@ import std::option::none;
22
22
import std:: _str;
23
23
import std:: _vec;
24
24
import std:: io;
25
+ import std:: run;
25
26
26
27
import std:: getopts;
27
28
import std:: getopts:: optopt;
@@ -154,6 +155,7 @@ options:
154
155
-O optimize
155
156
-S compile only; do not assemble or link
156
157
-c compile and assemble, but do not link
158
+ --bitcode produce an LLVM bitcode file
157
159
--save-temps write intermediate files in addition to normal output
158
160
--stats gather and report various compilation statistics
159
161
--time-passes time the individual phases of the compiler
@@ -205,7 +207,7 @@ fn main(vec[str] args) {
205
207
206
208
auto opts = vec ( optflag ( "h" ) , optflag ( "help" ) ,
207
209
optflag ( "v" ) , optflag ( "version" ) ,
208
- optflag ( "glue" ) ,
210
+ optflag ( "glue" ) , optflag ( "bitcode" ) ,
209
211
optflag ( "pretty" ) , optflag ( "ls" ) , optflag ( "parse-only" ) ,
210
212
optflag ( "O" ) , optflag ( "shared" ) , optmulti ( "L" ) ,
211
213
optflag ( "S" ) , optflag ( "c" ) , optopt ( "o" ) , optflag ( "g" ) ,
@@ -241,13 +243,15 @@ fn main(vec[str] args) {
241
243
auto output_file = getopts:: opt_maybe_str( match, "o" ) ;
242
244
auto library_search_paths = getopts:: opt_strs( match, "L" ) ;
243
245
244
- auto output_type = link:: output_type_bitcode ;
246
+ auto output_type = link:: output_type_exe ;
245
247
if ( opt_present( match , "parse-only" ) ) {
246
248
output_type = link:: output_type_none;
247
249
} else if ( opt_present( match , "S" ) ) {
248
250
output_type = link:: output_type_assembly;
249
251
} else if ( opt_present( match , "c" ) ) {
250
252
output_type = link:: output_type_object;
253
+ } else if ( opt_present( match , "bitcode" ) ) {
254
+ output_type = link:: output_type_bitcode;
251
255
}
252
256
253
257
auto verify = !opt_present( match , "noverify" ) ;
@@ -306,6 +310,7 @@ fn main(vec[str] args) {
306
310
}
307
311
308
312
auto ifile = match . free. ( 0 ) ;
313
+ let str saved_out_filename = "" ;
309
314
auto env = default_environment( sess, args. ( 0 ) , ifile) ;
310
315
if ( pretty) {
311
316
pretty_print_input ( sess, env, ifile) ;
@@ -316,20 +321,81 @@ fn main(vec[str] args) {
316
321
case ( none[ str] ) {
317
322
let vec[ str] parts = _str:: split ( ifile, '.' as u8 ) ;
318
323
_vec:: pop[ str] ( parts) ;
324
+ saved_out_filename = parts. ( 0 ) ;
319
325
alt ( output_type) {
320
326
case ( link:: output_type_none) { parts += vec ( "pp" ) ; }
321
327
case ( link:: output_type_bitcode) { parts += vec ( "bc" ) ; }
322
328
case ( link:: output_type_assembly) { parts += vec ( "s" ) ; }
329
+
330
+ // Object and exe output both use the '.o' extension here
323
331
case ( link:: output_type_object) { parts += vec ( "o" ) ; }
332
+ case ( link:: output_type_exe) { parts += vec ( "o" ) ; }
324
333
}
325
334
auto ofile = _str:: connect ( parts, "." ) ;
326
335
compile_input ( sess, env, ifile, ofile) ;
327
336
}
328
337
case ( some[ str] ( ?ofile) ) {
338
+ saved_out_filename = ofile;
329
339
compile_input ( sess, env, ifile, ofile) ;
330
340
}
331
341
}
332
342
}
343
+
344
+ // If the user wants an exe generated we need to invoke
345
+ // gcc to link the object file with some libs
346
+ if ( output_type == link:: output_type_exe) {
347
+
348
+ //FIXME: Should we make the 'stage3's variable here?
349
+ let str glu = "stage3/glue.o" ;
350
+ let str stage = "-Lstage3" ;
351
+ let vec[ str] gcc_args;
352
+ let str prog = "gcc" ;
353
+ let str exe_suffix = "" ;
354
+
355
+ // The invocations of gcc share some flags across platforms
356
+ let vec[ str] common_cflags = vec ( "-fno-strict-aliasing" , "-fPIC" ,
357
+ "-Wall" , "-fno-rtti" , "-fno-exceptions" , "-g" ) ;
358
+ let vec[ str] common_libs = vec ( stage, "-Lrustllvm" , "-Lrt" ,
359
+ "-lrustrt" , "-lrustllvm" , "-lstd" , "-lm" ) ;
360
+
361
+ alt ( sess. get_targ_cfg ( ) . os ) {
362
+ case ( session:: os_win32) {
363
+ exe_suffix = ".exe" ;
364
+ gcc_args = common_cflags + vec (
365
+ "-march=i686" , "-O2" ,
366
+ glu, "-o" ,
367
+ saved_out_filename + exe_suffix,
368
+ saved_out_filename + ".o" ) + common_libs;
369
+ }
370
+ case ( session:: os_macos) {
371
+ gcc_args = common_cflags + vec (
372
+ "-arch i386" , "-O0" , "-m32" ,
373
+ glu, "-o" ,
374
+ saved_out_filename + exe_suffix,
375
+ saved_out_filename + ".o" ) + common_libs;
376
+ }
377
+ case ( session:: os_linux) {
378
+ gcc_args = common_cflags + vec (
379
+ "-march=i686" , "-O2" , "-m32" ,
380
+ glu, "-o" ,
381
+ saved_out_filename + exe_suffix,
382
+ saved_out_filename + ".o" ) + common_libs;
383
+ }
384
+ }
385
+
386
+ // We run 'gcc' here
387
+ run:: run_program ( prog, gcc_args) ;
388
+
389
+ // Clean up on Darwin
390
+ if ( sess. get_targ_cfg ( ) . os == session:: os_macos) {
391
+ run:: run_program ( "dsymutil" , vec ( saved_out_filename) ) ;
392
+ }
393
+
394
+ // Remove the temporary object file if we aren't saving temps
395
+ if ( !save_temps) {
396
+ run:: run_program ( "rm" , vec ( saved_out_filename + ".o" ) ) ;
397
+ }
398
+ }
333
399
}
334
400
335
401
// Local Variables:
0 commit comments