Skip to content

Commit 3a825e4

Browse files
committed
---
yaml --- r: 5381 b: refs/heads/master c: de1b394 h: refs/heads/master i: 5379: 4098ac2 v: v3
1 parent 1582415 commit 3a825e4

File tree

3 files changed

+95
-89
lines changed

3 files changed

+95
-89
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 870117f44e37bbff5463852224186a266868bf6e
2+
refs/heads/master: de1b394c322a14b46724428d590089ee03b53dc8

trunk/src/comp/back/link.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import driver::session;
33
import lib::llvm::llvm;
44
import front::attr;
55
import middle::ty;
6-
import metadata::encoder;
6+
import metadata::{encoder, cstore};
77
import middle::trans_common::crate_ctxt;
88
import std::str;
99
import std::fs;
1010
import std::vec;
1111
import std::option;
12+
import std::run;
1213
import option::some;
1314
import option::none;
1415
import std::sha1::sha1;
@@ -490,6 +491,97 @@ fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: [str]) -> str {
490491
fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: str) -> str {
491492
ret ccx.names.next(flav);
492493
}
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, 3u,
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+
493585
//
494586
// Local Variables:
495587
// mode: rust

trunk/src/comp/driver/rustc.rs

Lines changed: 1 addition & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -512,95 +512,9 @@ fn main(args: [str]) {
512512
}
513513
}
514514

515-
// If the user wants an exe generated we need to invoke
516-
// gcc to link the object file with some libs
517-
//
518-
// TODO: Factor this out of main.
519515
if stop_after_codegen { ret; }
520516

521-
let glu: str = binary_dir + "/lib/glue.o";
522-
let main: str = binary_dir + "/lib/main.o";
523-
let stage: str = "-L" + binary_dir + "/lib";
524-
let prog: str = "gcc";
525-
// The invocations of gcc share some flags across platforms
526-
527-
let gcc_args =
528-
[stage, "-Lrt", "-lrustrt", glu, "-m32", "-o", saved_out_filename,
529-
saved_out_filename + ".o"];
530-
let lib_cmd;
531-
532-
let os = sess.get_targ_cfg().os;
533-
if os == session::os_macos {
534-
lib_cmd = "-dynamiclib";
535-
} else { lib_cmd = "-shared"; }
536-
537-
// Converts a library file name into a gcc -l argument
538-
fn unlib(config: @session::config, filename: str) -> str {
539-
let rmlib =
540-
bind fn (config: @session::config, filename: str) -> str {
541-
if config.os == session::os_macos ||
542-
config.os == session::os_linux &&
543-
str::find(filename, "lib") == 0 {
544-
ret str::slice(filename, 3u,
545-
str::byte_len(filename));
546-
} else { ret filename; }
547-
}(config, _);
548-
fn rmext(filename: str) -> str {
549-
let parts = str::split(filename, '.' as u8);
550-
vec::pop(parts);
551-
ret str::connect(parts, ".");
552-
}
553-
ret alt config.os {
554-
session::os_macos. { rmext(rmlib(filename)) }
555-
session::os_linux. { rmext(rmlib(filename)) }
556-
_ { rmext(filename) }
557-
};
558-
}
559-
560-
let cstore = sess.get_cstore();
561-
for cratepath: str in cstore::get_used_crate_files(cstore) {
562-
if str::ends_with(cratepath, ".rlib") {
563-
gcc_args += [cratepath];
564-
cont;
565-
}
566-
let cratepath = cratepath;
567-
let dir = fs::dirname(cratepath);
568-
if dir != "" { gcc_args += ["-L" + dir]; }
569-
let libarg = unlib(sess.get_targ_cfg(), fs::basename(cratepath));
570-
gcc_args += ["-l" + libarg];
571-
}
572-
573-
let ula = cstore::get_used_link_args(cstore);
574-
for arg: str in ula { gcc_args += [arg]; }
575-
576-
let used_libs = cstore::get_used_libraries(cstore);
577-
for l: str in used_libs { gcc_args += ["-l" + l]; }
578-
579-
if sopts.library {
580-
gcc_args += [lib_cmd];
581-
} else {
582-
// FIXME: why do we hardcode -lm?
583-
gcc_args += ["-lm", main];
584-
}
585-
// We run 'gcc' here
586-
587-
let err_code = run::run_program(prog, gcc_args);
588-
if 0 != err_code {
589-
sess.err(#fmt["linking with gcc failed with code %d", err_code]);
590-
sess.note(#fmt["gcc arguments: %s", str::connect(gcc_args, " ")]);
591-
sess.abort_if_errors();
592-
}
593-
// Clean up on Darwin
594-
595-
if sess.get_targ_cfg().os == session::os_macos {
596-
run::run_program("dsymutil", [saved_out_filename]);
597-
}
598-
599-
600-
// Remove the temporary object file if we aren't saving temps
601-
if !sopts.save_temps {
602-
run::run_program("rm", [saved_out_filename + ".o"]);
603-
}
517+
link::link_binary(sess, binary_dir, saved_out_filename);
604518
}
605519

606520
#[cfg(test)]

0 commit comments

Comments
 (0)