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.
This commit is contained in:
parent
37659a1803
commit
af56e2efde
4 changed files with 60 additions and 13 deletions
|
@ -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(),
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue