@@ -3,12 +3,13 @@ import driver::session;
3
3
import lib:: llvm:: llvm;
4
4
import front:: attr;
5
5
import middle:: ty;
6
- import metadata:: encoder;
6
+ import metadata :: { encoder, cstore } ;
7
7
import middle:: trans_common:: crate_ctxt;
8
8
import std:: str;
9
9
import std:: fs;
10
10
import std:: vec;
11
11
import std:: option;
12
+ import std:: run;
12
13
import option:: some;
13
14
import option:: none;
14
15
import std:: sha1:: sha1;
@@ -490,6 +491,97 @@ fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: [str]) -> str {
490
491
fn mangle_internal_name_by_seq ( ccx : @crate_ctxt , flav : str ) -> str {
491
492
ret ccx. names . next ( flav) ;
492
493
}
494
+
495
+ // If the user wants an exe generated we need to invoke
496
+ // gcc to link the object file with some libs
497
+ fn link_binary ( sess : session:: session ,
498
+ binary_dir : str ,
499
+ saved_out_filename : str ) {
500
+ let glu: str = binary_dir + "/lib/glue.o" ;
501
+ let main: str = binary_dir + "/lib/main.o" ;
502
+ let stage: str = "-L" + binary_dir + "/lib" ;
503
+ let prog: str = "gcc" ;
504
+ // The invocations of gcc share some flags across platforms
505
+
506
+ let gcc_args =
507
+ [ stage, "-Lrt" , "-lrustrt" , glu, "-m32" , "-o" , saved_out_filename,
508
+ saved_out_filename + ".o" ] ;
509
+ let lib_cmd;
510
+
511
+ let os = sess. get_targ_cfg ( ) . os ;
512
+ if os == session:: os_macos {
513
+ lib_cmd = "-dynamiclib" ;
514
+ } else { lib_cmd = "-shared" ; }
515
+
516
+ // Converts a library file name into a gcc -l argument
517
+ fn unlib ( config : @session:: config , filename : str ) -> str {
518
+ let rmlib =
519
+ bind fn ( config: @session:: config, filename: str ) -> str {
520
+ if config. os == session:: os_macos ||
521
+ config. os == session:: os_linux &&
522
+ str:: find ( filename, "lib" ) == 0 {
523
+ ret str:: slice ( filename, 3 u,
524
+ str:: byte_len ( filename) ) ;
525
+ } else { ret filename; }
526
+ } ( config, _) ;
527
+ fn rmext ( filename : str ) -> str {
528
+ let parts = str:: split ( filename, '.' as u8 ) ;
529
+ vec:: pop ( parts) ;
530
+ ret str:: connect ( parts, "." ) ;
531
+ }
532
+ ret alt config. os {
533
+ session:: os_macos. { rmext ( rmlib ( filename) ) }
534
+ session:: os_linux. { rmext ( rmlib ( filename) ) }
535
+ _ { rmext( filename) }
536
+ } ;
537
+ }
538
+
539
+ let cstore = sess. get_cstore ( ) ;
540
+ for cratepath: str in cstore:: get_used_crate_files ( cstore) {
541
+ if str:: ends_with ( cratepath, ".rlib" ) {
542
+ gcc_args += [ cratepath] ;
543
+ cont;
544
+ }
545
+ let cratepath = cratepath;
546
+ let dir = fs:: dirname ( cratepath) ;
547
+ if dir != "" { gcc_args += [ "-L" + dir] ; }
548
+ let libarg = unlib ( sess. get_targ_cfg ( ) , fs:: basename ( cratepath) ) ;
549
+ gcc_args += [ "-l" + libarg] ;
550
+ }
551
+
552
+ let ula = cstore:: get_used_link_args ( cstore) ;
553
+ for arg: str in ula { gcc_args += [ arg] ; }
554
+
555
+ let used_libs = cstore:: get_used_libraries ( cstore) ;
556
+ for l: str in used_libs { gcc_args += [ "-l" + l] ; }
557
+
558
+ if sess. get_opts ( ) . library {
559
+ gcc_args += [ lib_cmd] ;
560
+ } else {
561
+ // FIXME: why do we hardcode -lm?
562
+ gcc_args += [ "-lm" , main] ;
563
+ }
564
+ // We run 'gcc' here
565
+
566
+ let err_code = run:: run_program ( prog, gcc_args) ;
567
+ if 0 != err_code {
568
+ sess. err ( #fmt[ "linking with gcc failed with code %d" , err_code] ) ;
569
+ sess. note ( #fmt[ "gcc arguments: %s" , str:: connect ( gcc_args, " " ) ] ) ;
570
+ sess. abort_if_errors ( ) ;
571
+ }
572
+ // Clean up on Darwin
573
+
574
+ if sess. get_targ_cfg ( ) . os == session:: os_macos {
575
+ run:: run_program ( "dsymutil" , [ saved_out_filename] ) ;
576
+ }
577
+
578
+
579
+ // Remove the temporary object file if we aren't saving temps
580
+ if !sess. get_opts ( ) . save_temps {
581
+ run:: run_program ( "rm" , [ saved_out_filename + ".o" ] ) ;
582
+ }
583
+ }
584
+
493
585
//
494
586
// Local Variables:
495
587
// mode: rust
0 commit comments