diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-05-11 14:41:27 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-05-19 10:53:06 -0700 |
| commit | af56e2efde5cd82564e32598889d25d798c02722 (patch) | |
| tree | 108dd33084ff05b73137ea05aee3ef658940ffe0 | |
| parent | 37659a1803e398a5e374968aee5aabe541632021 (diff) | |
| download | rust-af56e2efde5cd82564e32598889d25d798c02722.tar.gz rust-af56e2efde5cd82564e32598889d25d798c02722.zip | |
rustc_back: Tweak the MSVC target spec
This change primarily changes the default ar utility used by MSVC-targeting compilers as `llvm-ar`, adding comments along the way as to why.
| -rw-r--r-- | src/librustc_back/target/mod.rs | 20 | ||||
| -rw-r--r-- | src/librustc_back/target/windows_msvc_base.rs | 38 | ||||
| -rw-r--r-- | src/librustc_back/target/x86_64_pc_windows_msvc.rs | 5 | ||||
| -rw-r--r-- | src/librustc_trans/back/link.rs | 10 |
4 files changed, 60 insertions, 13 deletions
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index a3cb357dc05..ceac37513ee 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -93,6 +93,8 @@ pub struct Target { pub struct TargetOptions { /// Linker to invoke. Defaults to "cc". pub linker: String, + /// Archive utility to use when managing archives. Defaults to "ar". + pub ar: String, /// Linker arguments that are unconditionally passed *before* any /// user-defined libraries. pub pre_link_args: Vec<String>, @@ -154,22 +156,24 @@ pub struct TargetOptions { pub linker_is_gnu: bool, /// Whether the linker support rpaths or not. Defaults to false. pub has_rpath: bool, - /// Whether to disable linking to compiler-rt. Defaults to false, as LLVM will emit references - /// to the functions that compiler-rt provides. + /// Whether to disable linking to compiler-rt. Defaults to false, as LLVM + /// will emit references to the functions that compiler-rt provides. pub no_compiler_rt: bool, - /// Dynamically linked executables can be compiled as position independent if the default - /// relocation model of position independent code is not changed. This is a requirement to take - /// advantage of ASLR, as otherwise the functions in the executable are not randomized and can - /// be used during an exploit of a vulnerability in any code. + /// Dynamically linked executables can be compiled as position independent + /// if the default relocation model of position independent code is not + /// changed. This is a requirement to take advantage of ASLR, as otherwise + /// the functions in the executable are not randomized and can be used + /// during an exploit of a vulnerability in any code. pub position_independent_executables: bool, } impl Default for TargetOptions { - /// Create a set of "sane defaults" for any target. This is still incomplete, and if used for - /// compilation, will certainly not work. + /// Create a set of "sane defaults" for any target. This is still + /// incomplete, and if used for compilation, will certainly not work. fn default() -> TargetOptions { TargetOptions { linker: "cc".to_string(), + ar: "ar".to_string(), pre_link_args: Vec::new(), post_link_args: Vec::new(), cpu: "generic".to_string(), diff --git a/src/librustc_back/target/windows_msvc_base.rs b/src/librustc_back/target/windows_msvc_base.rs index f4f25ea8569..30d74c80735 100644 --- a/src/librustc_back/target/windows_msvc_base.rs +++ b/src/librustc_back/target/windows_msvc_base.rs @@ -14,7 +14,38 @@ use std::default::Default; pub fn opts() -> TargetOptions { TargetOptions { function_sections: true, - linker: "link".to_string(), + linker: "link.exe".to_string(), + // When taking a look at the value of this `ar` field, one might expect + // `lib.exe` to be the value here! The `lib.exe` program is the default + // tool for managing `.lib` archives on Windows, but unfortunately the + // compiler cannot use it. + // + // To recap, we use `ar` here to manage rlibs (which are just archives). + // LLVM does not expose bindings for modifying archives so we have to + // invoke this utility for write operations (e.g. deleting files, adding + // files, etc). Normally archives only have object files within them, + // but the compiler also uses archives for storing metadata and + // compressed bytecode, so we don't exactly fall within "normal use + // cases". + // + // MSVC's `lib.exe` tool by default will choke when adding a non-object + // file to an archive, which we do on a regular basis, making it + // inoperable for us. Luckily, however, LLVM has already rewritten `ar` + // in the form of `llvm-ar` which is built by default when we build + // LLVM. This tool, unlike `lib.exe`, works just fine with non-object + // files, so we use it instead. + // + // Note that there's a few caveats associated with this: + // + // * This still requires that the *linker* (the consumer of rlibs) will + // ignore non-object files. Thankfully `link.exe` on Windows does + // indeed ignore non-object files in archives. + // * This requires `llvm-ar.exe` to be distributed with the compiler + // itself, but we already make sure of this elsewhere. + // + // Perhaps one day we won't even need this tool at all and we'll just be + // able to make library calls into LLVM! + ar: "llvm-ar.exe".to_string(), dynamic_linking: true, executables: true, dll_prefix: "".to_string(), @@ -25,7 +56,10 @@ pub fn opts() -> TargetOptions { morestack: false, is_like_windows: true, is_like_msvc: true, - pre_link_args: Vec::new(), + pre_link_args: vec![ + "/NOLOGO".to_string(), + "/NXCOMPAT".to_string(), + ], .. Default::default() } diff --git a/src/librustc_back/target/x86_64_pc_windows_msvc.rs b/src/librustc_back/target/x86_64_pc_windows_msvc.rs index aac1afbb97c..f7c3ca4b3f6 100644 --- a/src/librustc_back/target/x86_64_pc_windows_msvc.rs +++ b/src/librustc_back/target/x86_64_pc_windows_msvc.rs @@ -15,7 +15,10 @@ pub fn target() -> Target { base.cpu = "x86-64".to_string(); Target { - // FIXME: Test this. Copied from linux (#2398) + // This is currently in sync with the specification for + // x86_64-pc-windows-gnu but there's a comment in that file questioning + // whether this is valid or not. Sounds like the two should stay in sync + // at least for now. data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\ s0:64:64-f80:128:128-n8:16:32:64-S128".to_string(), diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e748f8b44cb..c6a59ff30a6 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -365,6 +365,12 @@ pub fn get_cc_prog(sess: &Session) -> String { } } +pub fn get_ar_prog(sess: &Session) -> String { + sess.opts.cg.ar.clone().unwrap_or_else(|| { + sess.target.target.options.ar.clone() + }) +} + pub fn remove(sess: &Session, path: &Path) { match fs::remove_file(path) { Ok(..) => {} @@ -547,7 +553,7 @@ fn link_rlib<'a>(sess: &'a Session, lib_search_paths: archive_search_paths(sess), slib_prefix: sess.target.target.options.staticlib_prefix.clone(), slib_suffix: sess.target.target.options.staticlib_suffix.clone(), - maybe_ar_prog: sess.opts.cg.ar.clone() + ar_prog: get_ar_prog(sess), }; let mut ab = ArchiveBuilder::create(config); ab.add_file(obj_filename).unwrap(); @@ -1181,7 +1187,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session, lib_search_paths: archive_search_paths(sess), slib_prefix: sess.target.target.options.staticlib_prefix.clone(), slib_suffix: sess.target.target.options.staticlib_suffix.clone(), - maybe_ar_prog: sess.opts.cg.ar.clone() + ar_prog: get_ar_prog(sess), }; let mut archive = Archive::open(config); archive.remove_file(&format!("{}.o", name)); |
