From de1b394c322a14b46724428d590089ee03b53dc8 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 20 Sep 2011 11:10:03 -0700 Subject: [PATCH] Move linker invocation from driver::rustc to back::link --- src/comp/back/link.rs | 94 +++++++++++++++++++++++++++++++++++++++- src/comp/driver/rustc.rs | 88 +------------------------------------ 2 files changed, 94 insertions(+), 88 deletions(-) diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index 03090276bff8..73df14621345 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -3,12 +3,13 @@ import driver::session; import lib::llvm::llvm; import front::attr; import middle::ty; -import metadata::encoder; +import metadata::{encoder, cstore}; import middle::trans_common::crate_ctxt; import std::str; import std::fs; import std::vec; import std::option; +import std::run; import option::some; import option::none; import std::sha1::sha1; @@ -490,6 +491,97 @@ fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: [str]) -> str { fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: str) -> str { ret ccx.names.next(flav); } + +// If the user wants an exe generated we need to invoke +// gcc to link the object file with some libs +fn link_binary(sess: session::session, + binary_dir: str, + saved_out_filename: str) { + let glu: str = binary_dir + "/lib/glue.o"; + let main: str = binary_dir + "/lib/main.o"; + let stage: str = "-L" + binary_dir + "/lib"; + let prog: str = "gcc"; + // The invocations of gcc share some flags across platforms + + let gcc_args = + [stage, "-Lrt", "-lrustrt", glu, "-m32", "-o", saved_out_filename, + saved_out_filename + ".o"]; + let lib_cmd; + + let os = sess.get_targ_cfg().os; + if os == session::os_macos { + lib_cmd = "-dynamiclib"; + } else { lib_cmd = "-shared"; } + + // Converts a library file name into a gcc -l argument + fn unlib(config: @session::config, filename: str) -> str { + let rmlib = + bind fn (config: @session::config, filename: str) -> str { + if config.os == session::os_macos || + config.os == session::os_linux && + str::find(filename, "lib") == 0 { + ret str::slice(filename, 3u, + str::byte_len(filename)); + } else { ret filename; } + }(config, _); + fn rmext(filename: str) -> str { + let parts = str::split(filename, '.' as u8); + vec::pop(parts); + ret str::connect(parts, "."); + } + ret alt config.os { + session::os_macos. { rmext(rmlib(filename)) } + session::os_linux. { rmext(rmlib(filename)) } + _ { rmext(filename) } + }; + } + + let cstore = sess.get_cstore(); + for cratepath: str in cstore::get_used_crate_files(cstore) { + if str::ends_with(cratepath, ".rlib") { + gcc_args += [cratepath]; + cont; + } + let cratepath = cratepath; + let dir = fs::dirname(cratepath); + if dir != "" { gcc_args += ["-L" + dir]; } + let libarg = unlib(sess.get_targ_cfg(), fs::basename(cratepath)); + gcc_args += ["-l" + libarg]; + } + + let ula = cstore::get_used_link_args(cstore); + for arg: str in ula { gcc_args += [arg]; } + + let used_libs = cstore::get_used_libraries(cstore); + for l: str in used_libs { gcc_args += ["-l" + l]; } + + if sess.get_opts().library { + gcc_args += [lib_cmd]; + } else { + // FIXME: why do we hardcode -lm? + gcc_args += ["-lm", main]; + } + // We run 'gcc' here + + let err_code = run::run_program(prog, gcc_args); + if 0 != err_code { + sess.err(#fmt["linking with gcc failed with code %d", err_code]); + sess.note(#fmt["gcc arguments: %s", str::connect(gcc_args, " ")]); + sess.abort_if_errors(); + } + // Clean up on Darwin + + if sess.get_targ_cfg().os == session::os_macos { + run::run_program("dsymutil", [saved_out_filename]); + } + + + // Remove the temporary object file if we aren't saving temps + if !sess.get_opts().save_temps { + run::run_program("rm", [saved_out_filename + ".o"]); + } +} + // // Local Variables: // mode: rust diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 20b34897162a..274ff3a38ec0 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -512,95 +512,9 @@ fn main(args: [str]) { } } - // If the user wants an exe generated we need to invoke - // gcc to link the object file with some libs - // - // TODO: Factor this out of main. if stop_after_codegen { ret; } - let glu: str = binary_dir + "/lib/glue.o"; - let main: str = binary_dir + "/lib/main.o"; - let stage: str = "-L" + binary_dir + "/lib"; - let prog: str = "gcc"; - // The invocations of gcc share some flags across platforms - - let gcc_args = - [stage, "-Lrt", "-lrustrt", glu, "-m32", "-o", saved_out_filename, - saved_out_filename + ".o"]; - let lib_cmd; - - let os = sess.get_targ_cfg().os; - if os == session::os_macos { - lib_cmd = "-dynamiclib"; - } else { lib_cmd = "-shared"; } - - // Converts a library file name into a gcc -l argument - fn unlib(config: @session::config, filename: str) -> str { - let rmlib = - bind fn (config: @session::config, filename: str) -> str { - if config.os == session::os_macos || - config.os == session::os_linux && - str::find(filename, "lib") == 0 { - ret str::slice(filename, 3u, - str::byte_len(filename)); - } else { ret filename; } - }(config, _); - fn rmext(filename: str) -> str { - let parts = str::split(filename, '.' as u8); - vec::pop(parts); - ret str::connect(parts, "."); - } - ret alt config.os { - session::os_macos. { rmext(rmlib(filename)) } - session::os_linux. { rmext(rmlib(filename)) } - _ { rmext(filename) } - }; - } - - let cstore = sess.get_cstore(); - for cratepath: str in cstore::get_used_crate_files(cstore) { - if str::ends_with(cratepath, ".rlib") { - gcc_args += [cratepath]; - cont; - } - let cratepath = cratepath; - let dir = fs::dirname(cratepath); - if dir != "" { gcc_args += ["-L" + dir]; } - let libarg = unlib(sess.get_targ_cfg(), fs::basename(cratepath)); - gcc_args += ["-l" + libarg]; - } - - let ula = cstore::get_used_link_args(cstore); - for arg: str in ula { gcc_args += [arg]; } - - let used_libs = cstore::get_used_libraries(cstore); - for l: str in used_libs { gcc_args += ["-l" + l]; } - - if sopts.library { - gcc_args += [lib_cmd]; - } else { - // FIXME: why do we hardcode -lm? - gcc_args += ["-lm", main]; - } - // We run 'gcc' here - - let err_code = run::run_program(prog, gcc_args); - if 0 != err_code { - sess.err(#fmt["linking with gcc failed with code %d", err_code]); - sess.note(#fmt["gcc arguments: %s", str::connect(gcc_args, " ")]); - sess.abort_if_errors(); - } - // Clean up on Darwin - - if sess.get_targ_cfg().os == session::os_macos { - run::run_program("dsymutil", [saved_out_filename]); - } - - - // Remove the temporary object file if we aren't saving temps - if !sopts.save_temps { - run::run_program("rm", [saved_out_filename + ".o"]); - } + link::link_binary(sess, binary_dir, saved_out_filename); } #[cfg(test)]