Skip to content

Commit

Permalink
Auto merge of rust-lang#34492 - retep998:please-be-robust-already, r=…
Browse files Browse the repository at this point in the history
…alexcrichton

Make MSVC detection ludicrously robust

Resurrection of rust-lang#31158

r? @alexcrichton
  • Loading branch information
bors authored Jul 2, 2016
2 parents 32a6373 + a1b33b4 commit 7e07e31
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 181 deletions.
30 changes: 18 additions & 12 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,17 @@ pub fn build_link_meta<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
return r;
}

pub fn get_linker(sess: &Session) -> (String, Command) {
// The third parameter is for an extra path to add to PATH for MSVC
// cross linkers for host toolchain DLL dependencies
pub fn get_linker(sess: &Session) -> (String, Command, Option<PathBuf>) {
if let Some(ref linker) = sess.opts.cg.linker {
(linker.clone(), Command::new(linker))
(linker.clone(), Command::new(linker), None)
} else if sess.target.target.options.is_like_msvc {
("link.exe".to_string(), msvc::link_exe_cmd(sess))
let (cmd, host) = msvc::link_exe_cmd(sess);
("link.exe".to_string(), cmd, host)
} else {
(sess.target.target.options.linker.clone(),
Command::new(&sess.target.target.options.linker))
Command::new(&sess.target.target.options.linker), None)
}
}

Expand All @@ -153,17 +156,15 @@ pub fn get_ar_prog(sess: &Session) -> String {
})
}

fn command_path(sess: &Session) -> OsString {
fn command_path(sess: &Session, extra: Option<PathBuf>) -> OsString {
// The compiler's sysroot often has some bundled tools, so add it to the
// PATH for the child.
let mut new_path = sess.host_filesearch(PathKind::All)
.get_tools_search_paths();
if let Some(path) = env::var_os("PATH") {
new_path.extend(env::split_paths(&path));
}
if sess.target.target.options.is_like_msvc {
new_path.extend(msvc::host_dll_path());
}
new_path.extend(extra);
env::join_paths(new_path).unwrap()
}

Expand Down Expand Up @@ -379,7 +380,7 @@ fn archive_config<'a>(sess: &'a Session,
src: input.map(|p| p.to_path_buf()),
lib_search_paths: archive_search_paths(sess),
ar_prog: get_ar_prog(sess),
command_path: command_path(sess),
command_path: command_path(sess, None),
}
}

Expand Down Expand Up @@ -616,8 +617,8 @@ fn link_natively(sess: &Session,
info!("preparing {:?} from {:?} to {:?}", crate_type, objects, out_filename);

// The invocations of cc share some flags across platforms
let (pname, mut cmd) = get_linker(sess);
cmd.env("PATH", command_path(sess));
let (pname, mut cmd, extra) = get_linker(sess);
cmd.env("PATH", command_path(sess, extra));

let root = sess.target_filesearch(PathKind::Native).get_lib_path();
cmd.args(&sess.target.target.options.pre_link_args);
Expand Down Expand Up @@ -682,10 +683,15 @@ fn link_natively(sess: &Session,
info!("linker stdout:\n{}", escape_string(&prog.stdout[..]));
},
Err(e) => {
// Trying to diagnose https://github.com/rust-lang/rust/issues/33844
sess.struct_err(&format!("could not exec the linker `{}`: {}", pname, e))
.note(&format!("{:?}", &cmd))
.emit();
if sess.target.target.options.is_like_msvc && e.kind() == io::ErrorKind::NotFound {
sess.note_without_error("the msvc targets depend on the msvc linker \
but `link.exe` was not found");
sess.note_without_error("please ensure that VS 2013 or VS 2015 was installed \
with the Visual C++ option");
}
sess.abort_if_errors();
}
}
Expand Down
56 changes: 56 additions & 0 deletions src/librustc_trans/back/msvc/arch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_camel_case_types, non_snake_case)]

use libc::c_void;
use std::mem;

type DWORD = u32;
type WORD = u16;
type LPVOID = *mut c_void;
type DWORD_PTR = usize;

const PROCESSOR_ARCHITECTURE_INTEL: WORD = 0;
const PROCESSOR_ARCHITECTURE_AMD64: WORD = 9;

#[repr(C)]
struct SYSTEM_INFO {
wProcessorArchitecture: WORD,
_wReserved: WORD,
_dwPageSize: DWORD,
_lpMinimumApplicationAddress: LPVOID,
_lpMaximumApplicationAddress: LPVOID,
_dwActiveProcessorMask: DWORD_PTR,
_dwNumberOfProcessors: DWORD,
_dwProcessorType: DWORD,
_dwAllocationGranularity: DWORD,
_wProcessorLevel: WORD,
_wProcessorRevision: WORD,
}

extern "system" {
fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);
}

pub enum Arch {
X86,
Amd64,
}

pub fn host_arch() -> Option<Arch> {
let mut info = unsafe { mem::zeroed() };
unsafe { GetNativeSystemInfo(&mut info) };
match info.wProcessorArchitecture {
PROCESSOR_ARCHITECTURE_INTEL => Some(Arch::X86),
PROCESSOR_ARCHITECTURE_AMD64 => Some(Arch::Amd64),
_ => None,
}
}
Loading

0 comments on commit 7e07e31

Please sign in to comment.