about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2017-05-23 19:02:23 -0700
committerBrian Anderson <banderson@mozilla.com>2017-06-01 20:41:38 +0000
commitda100fe0bb7ba77dbcc346018068dbfdba053f6b (patch)
tree6bd4b44d0ffb24e29ff297a3b9cca73cc884cb51 /src
parentf89d8d184490ecb3cf91f7b6bb7296d649f931ba (diff)
downloadrust-da100fe0bb7ba77dbcc346018068dbfdba053f6b.tar.gz
rust-da100fe0bb7ba77dbcc346018068dbfdba053f6b.zip
Support VS 2017
Fixes #38584
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock35
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/liballoc_jemalloc/Cargo.toml2
-rw-r--r--src/libcompiler_builtins/Cargo.toml2
-rw-r--r--src/libflate/Cargo.toml2
-rw-r--r--src/librustc_llvm/Cargo.toml2
-rw-r--r--src/librustc_trans/Cargo.toml3
-rw-r--r--src/librustc_trans/back/link.rs41
-rw-r--r--src/librustc_trans/back/msvc/arch.rs56
-rw-r--r--src/librustc_trans/back/msvc/mod.rs305
-rw-r--r--src/librustc_trans/back/msvc/registry.rs136
-rw-r--r--src/librustc_trans/lib.rs6
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/libstd/Cargo.toml2
14 files changed, 63 insertions, 533 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index d55dd919bdf..3e39893c3bd 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -44,7 +44,7 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
 ]
 
@@ -84,7 +84,7 @@ name = "backtrace-sys"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -110,7 +110,7 @@ dependencies = [
  "build_helper 0.1.0",
  "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -239,7 +239,7 @@ name = "cmake"
 version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -257,7 +257,7 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -308,7 +308,7 @@ name = "curl-sys"
 version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -411,7 +411,7 @@ name = "flate"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -444,7 +444,7 @@ dependencies = [
 
 [[package]]
 name = "gcc"
-version = "0.3.46"
+version = "0.3.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -605,7 +605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -630,7 +630,7 @@ name = "libz-sys"
 version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -650,7 +650,7 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -697,7 +697,7 @@ name = "miniz-sys"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -830,7 +830,7 @@ name = "openssl-sys"
 version = "0.9.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1248,7 +1248,7 @@ name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_bitflags 0.0.0",
 ]
 
@@ -1375,6 +1375,7 @@ name = "rustc_trans"
 version = "0.0.0"
 dependencies = [
  "flate 0.0.0",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -1425,7 +1426,7 @@ dependencies = [
  "arena 0.0.0",
  "build_helper 0.1.0",
  "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -1577,7 +1578,7 @@ dependencies = [
  "collections 0.0.0",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
- "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
@@ -2042,7 +2043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c"
 "checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
 "checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf"
-"checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f"
+"checksum gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)" = "5f837c392f2ea61cb1576eac188653df828c861b7137d74ea4a5caa89621f9e6"
 "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
 "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
 "checksum git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9de9df4358c17e448a778d90cd0272e1dab5eae30244502333fa2001c4e24357"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index cc560e0172e..8842dce0257 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -36,5 +36,5 @@ num_cpus = "1.0"
 toml = "0.1"
 getopts = "0.2"
 rustc-serialize = "0.3"
-gcc = "0.3.46"
+gcc = "0.3.50"
 libc = "0.2"
diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml
index 01393be9949..49e5baad74d 100644
--- a/src/liballoc_jemalloc/Cargo.toml
+++ b/src/liballoc_jemalloc/Cargo.toml
@@ -17,7 +17,7 @@ libc = { path = "../rustc/libc_shim" }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-gcc = "0.3.27"
+gcc = "0.3.50"
 
 [features]
 debug = []
diff --git a/src/libcompiler_builtins/Cargo.toml b/src/libcompiler_builtins/Cargo.toml
index 3f844b3f09e..2c9cee5e7a0 100644
--- a/src/libcompiler_builtins/Cargo.toml
+++ b/src/libcompiler_builtins/Cargo.toml
@@ -16,4 +16,4 @@ core = { path = "../libcore" }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-gcc = "0.3.27"
+gcc = "0.3.50"
diff --git a/src/libflate/Cargo.toml b/src/libflate/Cargo.toml
index 5423da9c81c..e5c611460f7 100644
--- a/src/libflate/Cargo.toml
+++ b/src/libflate/Cargo.toml
@@ -11,4 +11,4 @@ crate-type = ["dylib"]
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-gcc = "0.3.27"
+gcc = "0.3.50"
diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml
index f97daa22ff6..f2eea014dd3 100644
--- a/src/librustc_llvm/Cargo.toml
+++ b/src/librustc_llvm/Cargo.toml
@@ -17,4 +17,4 @@ rustc_bitflags = { path = "../librustc_bitflags" }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-gcc = "0.3.27"
+gcc = "0.3.50"
diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml
index 4ccc85257f3..7355b399360 100644
--- a/src/librustc_trans/Cargo.toml
+++ b/src/librustc_trans/Cargo.toml
@@ -25,3 +25,6 @@ rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+
+[target."cfg(windows)".dependencies]
+gcc = "0.3.50"
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index e4026723880..ee92a4b4a2d 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -12,7 +12,6 @@ use super::archive::{ArchiveBuilder, ArchiveConfig};
 use super::linker::Linker;
 use super::rpath::RPathConfig;
 use super::rpath;
-use super::msvc;
 use metadata::METADATA_FILENAME;
 use rustc::session::config::{self, NoDebugInfo, OutputFilenames, Input, OutputType};
 use rustc::session::filesearch;
@@ -142,20 +141,41 @@ pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMet
     return r;
 }
 
-// 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>) {
+// The third parameter is for an env vars, used to set up the path for MSVC
+// to find its DLLs
+pub fn get_linker(sess: &Session) -> (String, Command, Vec<(OsString, OsString)>) {
     if let Some(ref linker) = sess.opts.cg.linker {
-        (linker.clone(), Command::new(linker), None)
+        (linker.clone(), Command::new(linker), vec![])
     } else if sess.target.target.options.is_like_msvc {
-        let (cmd, host) = msvc::link_exe_cmd(sess);
-        ("link.exe".to_string(), cmd, host)
+        let (cmd, envs) = msvc_link_exe_cmd(sess);
+        ("link.exe".to_string(), cmd, envs)
     } else {
         (sess.target.target.options.linker.clone(),
-         Command::new(&sess.target.target.options.linker), None)
+         Command::new(&sess.target.target.options.linker), vec![])
     }
 }
 
+#[cfg(windows)]
+pub fn msvc_link_exe_cmd(sess: &Session) -> (Command, Vec<(OsString, OsString)>) {
+    use gcc::windows_registry;
+
+    let target = &sess.opts.target_triple;
+    let tool = windows_registry::find_tool(target, "link.exe");
+
+    if let Some(tool) = tool {
+        let envs = tool.env().to_vec();
+        (tool.to_command(), envs)
+    } else {
+        debug!("Failed to locate linker.");
+        (Command::new("link.exe"), vec![])
+    }
+}
+
+#[cfg(not(windows))]
+pub fn msvc_link_exe_cmd(_sess: &Session) -> (Command, Vec<(OsString, OsString)>) {
+    (Command::new("link.exe"), vec![])
+}
+
 pub fn get_ar_prog(sess: &Session) -> String {
     sess.opts.cg.ar.clone().unwrap_or_else(|| {
         sess.target.target.options.ar.clone()
@@ -706,8 +726,9 @@ fn link_natively(sess: &Session,
     let flavor = sess.linker_flavor();
 
     // The invocations of cc share some flags across platforms
-    let (pname, mut cmd, extra) = get_linker(sess);
-    cmd.env("PATH", command_path(sess, extra));
+    let (pname, mut cmd, envs) = get_linker(sess);
+    // This will set PATH on MSVC
+    cmd.envs(envs);
 
     let root = sess.target_filesearch(PathKind::Native).get_lib_path();
     if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
diff --git a/src/librustc_trans/back/msvc/arch.rs b/src/librustc_trans/back/msvc/arch.rs
deleted file mode 100644
index c10312a8e17..00000000000
--- a/src/librustc_trans/back/msvc/arch.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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,
-    }
-}
diff --git a/src/librustc_trans/back/msvc/mod.rs b/src/librustc_trans/back/msvc/mod.rs
deleted file mode 100644
index 97648888fa9..00000000000
--- a/src/librustc_trans/back/msvc/mod.rs
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright 2015 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.
-
-//! MSVC-specific logic for linkers and such.
-//!
-//! This module contains a cross-platform interface but has a blank unix
-//! implementation. The Windows implementation builds on top of Windows native
-//! libraries (reading registry keys), so it otherwise wouldn't link on unix.
-//!
-//! Note that we don't have much special logic for finding the system linker on
-//! any other platforms, so it may seem a little odd to single out MSVC to have
-//! a good deal of code just to find the linker. Unlike Unix systems, however,
-//! the MSVC linker is not in the system PATH by default. It also additionally
-//! needs a few environment variables or command line flags to be able to link
-//! against system libraries.
-//!
-//! In order to have a nice smooth experience on Windows, the logic in this file
-//! is here to find the MSVC linker and set it up in the default configuration
-//! one would need to set up anyway. This means that the Rust compiler can be
-//! run not only in the developer shells of MSVC but also the standard cmd.exe
-//! shell or MSYS shells.
-//!
-//! As a high-level note, all logic in this module for looking up various
-//! paths/files is based on Microsoft's logic in their vcvars bat files, but
-//! comments can also be found below leading through the various code paths.
-
-// A simple macro to make this option mess easier to read
-#[cfg(windows)]
-macro_rules! otry {
-    ($expr:expr) => (match $expr {
-        Some(val) => val,
-        None => return None,
-    })
-}
-
-#[cfg(windows)]
-mod registry;
-#[cfg(windows)]
-mod arch;
-
-#[cfg(windows)]
-mod platform {
-    use std::env;
-    use std::ffi::OsString;
-    use std::fs;
-    use std::path::{Path, PathBuf};
-    use std::process::Command;
-    use rustc::session::Session;
-    use super::arch::{host_arch, Arch};
-    use super::registry::LOCAL_MACHINE;
-
-    // First we need to figure out whether the environment is already correctly
-    // configured by vcvars. We do this by looking at the environment variable
-    // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set
-    // otherwise. If it is defined, then we find `link.exe` in `PATH and trust
-    // that everything else is configured correctly.
-    //
-    // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where
-    // it claimed it should be), then we resort to finding everything
-    // ourselves. First we find where the latest version of MSVC is installed
-    // and what version it is. Then based on the version we find the
-    // appropriate SDKs.
-    //
-    // If despite our best efforts we are still unable to find MSVC then we
-    // just blindly call `link.exe` and hope for the best.
-    //
-    // This code only supports VC 11 through 15. For versions older than that
-    // the user will need to manually execute the appropriate vcvars bat file
-    // and it should hopefully work.
-    //
-    // The second member of the tuple we return is the directory for the host
-    // linker toolchain, which is necessary when using the cross linkers.
-    pub fn link_exe_cmd(sess: &Session) -> (Command, Option<PathBuf>) {
-        let arch = &sess.target.target.arch;
-        env::var_os("VCINSTALLDIR").and_then(|_| {
-            debug!("Detected that vcvars was already run.");
-            let path = otry!(env::var_os("PATH"));
-            // Mingw has its own link which is not the link we want so we
-            // look for `cl.exe` too as a precaution.
-            env::split_paths(&path).find(|path| {
-                path.join("cl.exe").is_file()
-                    && path.join("link.exe").is_file()
-            }).map(|path| {
-                (Command::new(path.join("link.exe")), None)
-            })
-        }).or_else(|| {
-            None.or_else(|| {
-                find_msvc_latest(arch, "15.0")
-            }).or_else(|| {
-                find_msvc_latest(arch, "14.0")
-            }).or_else(|| {
-                find_msvc_12(arch)
-            }).or_else(|| {
-                find_msvc_11(arch)
-            }).map(|(cmd, path)| (cmd, Some(path)))
-        }).unwrap_or_else(|| {
-            debug!("Failed to locate linker.");
-            (Command::new("link.exe"), None)
-        })
-    }
-
-    // For MSVC 14 or newer we need to find the Universal CRT as well as either
-    // the Windows 10 SDK or Windows 8.1 SDK.
-    fn find_msvc_latest(arch: &str, ver: &str) -> Option<(Command, PathBuf)> {
-        let vcdir = otry!(get_vc_dir(ver));
-        let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
-        let sub = otry!(lib_subdir(arch));
-        let ucrt = otry!(get_ucrt_dir());
-        debug!("Found Universal CRT {:?}", ucrt);
-        add_lib(&mut cmd, &ucrt.join("ucrt").join(sub));
-        if let Some(dir) = get_sdk10_dir() {
-            debug!("Found Win10 SDK {:?}", dir);
-            add_lib(&mut cmd, &dir.join("um").join(sub));
-        } else if let Some(dir) = get_sdk81_dir() {
-            debug!("Found Win8.1 SDK {:?}", dir);
-            add_lib(&mut cmd, &dir.join("um").join(sub));
-        } else {
-            return None
-        }
-        Some((cmd, host))
-    }
-
-    // For MSVC 12 we need to find the Windows 8.1 SDK.
-    fn find_msvc_12(arch: &str) -> Option<(Command, PathBuf)> {
-        let vcdir = otry!(get_vc_dir("12.0"));
-        let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
-        let sub = otry!(lib_subdir(arch));
-        let sdk81 = otry!(get_sdk81_dir());
-        debug!("Found Win8.1 SDK {:?}", sdk81);
-        add_lib(&mut cmd, &sdk81.join("um").join(sub));
-        Some((cmd, host))
-    }
-
-    // For MSVC 11 we need to find the Windows 8 SDK.
-    fn find_msvc_11(arch: &str) -> Option<(Command, PathBuf)> {
-        let vcdir = otry!(get_vc_dir("11.0"));
-        let (mut cmd, host) = otry!(get_linker(&vcdir, arch));
-        let sub = otry!(lib_subdir(arch));
-        let sdk8 = otry!(get_sdk8_dir());
-        debug!("Found Win8 SDK {:?}", sdk8);
-        add_lib(&mut cmd, &sdk8.join("um").join(sub));
-        Some((cmd, host))
-    }
-
-    // A convenience function to append library paths.
-    fn add_lib(cmd: &mut Command, lib: &Path) {
-        let mut arg: OsString = "/LIBPATH:".into();
-        arg.push(lib);
-        cmd.arg(arg);
-    }
-
-    // Given a possible MSVC installation directory, we look for the linker and
-    // then add the MSVC library path.
-    fn get_linker(path: &Path, arch: &str) -> Option<(Command, PathBuf)> {
-        debug!("Looking for linker in {:?}", path);
-        bin_subdir(arch).into_iter().map(|(sub, host)| {
-            (path.join("bin").join(sub).join("link.exe"),
-             path.join("bin").join(host))
-        }).filter(|&(ref path, _)| {
-            path.is_file()
-        }).map(|(path, host)| {
-            (Command::new(path), host)
-        }).filter_map(|(mut cmd, host)| {
-            let sub = otry!(vc_lib_subdir(arch));
-            add_lib(&mut cmd, &path.join("lib").join(sub));
-            Some((cmd, host))
-        }).next()
-    }
-
-    // To find MSVC we look in a specific registry key for the version we are
-    // trying to find.
-    fn get_vc_dir(ver: &str) -> Option<PathBuf> {
-        let key = otry!(LOCAL_MACHINE
-            .open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".as_ref()).ok());
-        let path = otry!(key.query_str(ver).ok());
-        Some(path.into())
-    }
-
-    // To find the Universal CRT we look in a specific registry key for where
-    // all the Universal CRTs are located and then sort them asciibetically to
-    // find the newest version. While this sort of sorting isn't ideal,  it is
-    // what vcvars does so that's good enough for us.
-    fn get_ucrt_dir() -> Option<PathBuf> {
-        let key = otry!(LOCAL_MACHINE
-            .open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref()).ok());
-        let root = otry!(key.query_str("KitsRoot10").ok());
-        let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok());
-        readdir.filter_map(|dir| {
-            dir.ok()
-        }).map(|dir| {
-            dir.path()
-        }).filter(|dir| {
-            dir.components().last().and_then(|c| {
-                c.as_os_str().to_str()
-            }).map(|c| {
-                c.starts_with("10.") && dir.join("ucrt").is_dir()
-            }).unwrap_or(false)
-        }).max()
-    }
-
-    // Vcvars finds the correct version of the Windows 10 SDK by looking
-    // for the include `um\Windows.h` because sometimes a given version will
-    // only have UCRT bits without the rest of the SDK. Since we only care about
-    // libraries and not includes, we instead look for `um\x64\kernel32.lib`.
-    // Since the 32-bit and 64-bit libraries are always installed together we
-    // only need to bother checking x64, making this code a tiny bit simpler.
-    // Like we do for the Universal CRT, we sort the possibilities
-    // asciibetically to find the newest one as that is what vcvars does.
-    fn get_sdk10_dir() -> Option<PathBuf> {
-        let key = otry!(LOCAL_MACHINE
-            .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref()).ok());
-        let root = otry!(key.query_str("InstallationFolder").ok());
-        let readdir = otry!(fs::read_dir(Path::new(&root).join("lib")).ok());
-        let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
-            .map(|dir| dir.path()).collect();
-        dirs.sort();
-        dirs.into_iter().rev().filter(|dir| {
-            dir.join("um").join("x64").join("kernel32.lib").is_file()
-        }).next()
-    }
-
-    // Interestingly there are several subdirectories, `win7` `win8` and
-    // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same
-    // applies to us. Note that if we were targetting kernel mode drivers
-    // instead of user mode applications, we would care.
-    fn get_sdk81_dir() -> Option<PathBuf> {
-        let key = otry!(LOCAL_MACHINE
-            .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref()).ok());
-        let root = otry!(key.query_str("InstallationFolder").ok());
-        Some(Path::new(&root).join("lib").join("winv6.3"))
-    }
-
-    fn get_sdk8_dir() -> Option<PathBuf> {
-        let key = otry!(LOCAL_MACHINE
-            .open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref()).ok());
-        let root = otry!(key.query_str("InstallationFolder").ok());
-        Some(Path::new(&root).join("lib").join("win8"))
-    }
-
-    // When choosing the linker toolchain to use, we have to choose the one
-    // which matches the host architecture. Otherwise we end up in situations
-    // where someone on 32-bit Windows is trying to cross compile to 64-bit and
-    // it tries to invoke the native 64-bit linker which won't work.
-    //
-    // For the return value of this function, the first member of the tuple is
-    // the folder of the linker we will be invoking, while the second member
-    // is the folder of the host toolchain for that linker which is essential
-    // when using a cross linker. We return a Vec since on x64 there are often
-    // two linkers that can target the architecture we desire. The 64-bit host
-    // linker is preferred, and hence first, due to 64-bit allowing it more
-    // address space to work with and potentially being faster.
-    //
-    // FIXME - Figure out what happens when the host architecture is arm.
-    fn bin_subdir(arch: &str) -> Vec<(&'static str, &'static str)> {
-        match (arch, host_arch()) {
-            ("x86", Some(Arch::X86)) => vec![("", "")],
-            ("x86", Some(Arch::Amd64)) => vec![("amd64_x86", "amd64"), ("", "")],
-            ("x86_64", Some(Arch::X86)) => vec![("x86_amd64", "")],
-            ("x86_64", Some(Arch::Amd64)) => vec![("amd64", "amd64"), ("x86_amd64", "")],
-            ("arm", Some(Arch::X86)) => vec![("x86_arm", "")],
-            ("arm", Some(Arch::Amd64)) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
-            _ => vec![],
-        }
-    }
-
-    fn lib_subdir(arch: &str) -> Option<&'static str> {
-        match arch {
-            "x86" => Some("x86"),
-            "x86_64" => Some("x64"),
-            "arm" => Some("arm"),
-            _ => None,
-        }
-    }
-
-    // MSVC's x86 libraries are not in a subfolder
-    fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
-        match arch {
-            "x86" => Some(""),
-            "x86_64" => Some("amd64"),
-            "arm" => Some("arm"),
-            _ => None,
-        }
-    }
-}
-
-// If we're not on Windows, then there's no registry to search through and MSVC
-// wouldn't be able to run, so we just call `link.exe` and hope for the best.
-#[cfg(not(windows))]
-mod platform {
-    use std::path::PathBuf;
-    use std::process::Command;
-    use rustc::session::Session;
-    pub fn link_exe_cmd(_sess: &Session) -> (Command, Option<PathBuf>) {
-        (Command::new("link.exe"), None)
-    }
-}
-
-pub use self::platform::*;
diff --git a/src/librustc_trans/back/msvc/registry.rs b/src/librustc_trans/back/msvc/registry.rs
deleted file mode 100644
index 8242f53896a..00000000000
--- a/src/librustc_trans/back/msvc/registry.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2015 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.
-
-use std::io;
-use std::ffi::{OsString, OsStr};
-use std::os::windows::prelude::*;
-use std::ptr;
-use libc::c_long;
-
-pub type DWORD = u32;
-type LPCWSTR = *const u16;
-type LONG = c_long;
-type LPDWORD = *mut DWORD;
-type LPBYTE = *mut u8;
-
-
-const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
-const KEY_WOW64_32KEY: REGSAM = 0x0200;
-const KEY_READ: REGSAM = (STANDARD_RIGTS_READ | KEY_QUERY_VALUE |
-                          KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & !SYNCHRONIZE;
-const STANDARD_RIGTS_READ: REGSAM = READ_CONTROL;
-const READ_CONTROL: REGSAM = 0x00020000;
-const KEY_QUERY_VALUE: REGSAM = 0x0001;
-const KEY_ENUMERATE_SUB_KEYS: REGSAM = 0x0008;
-const KEY_NOTIFY: REGSAM = 0x0010;
-const SYNCHRONIZE: REGSAM = 0x00100000;
-const REG_SZ: DWORD = 1;
-const ERROR_SUCCESS: i32 = 0;
-
-pub enum __HKEY__ {}
-pub type HKEY = *mut __HKEY__;
-pub type PHKEY = *mut HKEY;
-pub type REGSAM = DWORD;
-
-#[link(name = "advapi32")]
-extern "system" {
-    fn RegOpenKeyExW(hKey: HKEY,
-                     lpSubKey: LPCWSTR,
-                     ulOptions: DWORD,
-                     samDesired: REGSAM,
-                     phkResult: PHKEY) -> LONG;
-    fn RegQueryValueExW(hKey: HKEY,
-                        lpValueName: LPCWSTR,
-                        lpReserved: LPDWORD,
-                        lpType: LPDWORD,
-                        lpData: LPBYTE,
-                        lpcbData: LPDWORD) -> LONG;
-    fn RegCloseKey(hKey: HKEY) -> LONG;
-}
-
-pub struct RegistryKey(Repr);
-
-struct OwnedKey(HKEY);
-
-enum Repr {
-    Const(HKEY),
-    Owned(OwnedKey),
-}
-
-unsafe impl Sync for RegistryKey {}
-unsafe impl Send for RegistryKey {}
-
-pub static LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE));
-
-impl RegistryKey {
-    fn raw(&self) -> HKEY {
-        match self.0 {
-            Repr::Const(val) => val,
-            Repr::Owned(ref val) => val.0,
-        }
-    }
-
-    pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
-        let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
-        let mut ret = ptr::null_mut();
-        let err = unsafe {
-            RegOpenKeyExW(self.raw(), key.as_ptr(), 0,
-                          KEY_READ | KEY_WOW64_32KEY, &mut ret)
-        };
-        if err == ERROR_SUCCESS {
-            Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
-        } else {
-            Err(io::Error::from_raw_os_error(err as i32))
-        }
-    }
-
-    pub fn query_str(&self, name: &str) -> io::Result<OsString> {
-        let name: &OsStr = name.as_ref();
-        let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();
-        let mut len = 0;
-        let mut kind = 0;
-        unsafe {
-            let err = RegQueryValueExW(self.raw(), name.as_ptr(), ptr::null_mut(),
-                                       &mut kind, ptr::null_mut(), &mut len);
-            if err != ERROR_SUCCESS {
-                return Err(io::Error::from_raw_os_error(err as i32))
-            }
-            if kind != REG_SZ {
-                return Err(io::Error::new(io::ErrorKind::Other,
-                                          "registry key wasn't a string"))
-            }
-
-            // The length here is the length in bytes, but we're using wide
-            // characters so we need to be sure to halve it for the capacity
-            // passed in.
-            let mut v = Vec::with_capacity(len as usize / 2);
-            let err = RegQueryValueExW(self.raw(), name.as_ptr(), ptr::null_mut(),
-                                       ptr::null_mut(), v.as_mut_ptr() as *mut _,
-                                       &mut len);
-            if err != ERROR_SUCCESS {
-                return Err(io::Error::from_raw_os_error(err as i32))
-            }
-            v.set_len(len as usize / 2);
-
-            // Some registry keys may have a terminating nul character, but
-            // we're not interested in that, so chop it off if it's there.
-            if v[v.len() - 1] == 0 {
-                v.pop();
-            }
-            Ok(OsString::from_wide(&v))
-        }
-    }
-}
-
-impl Drop for OwnedKey {
-    fn drop(&mut self) {
-        unsafe { RegCloseKey(self.0); }
-    }
-}
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index c111a3983e7..71fb2e5fb20 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -35,6 +35,7 @@
 #![feature(slice_patterns)]
 #![feature(unicode)]
 #![feature(conservative_impl_trait)]
+#![feature(command_envs)]
 
 #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
 #![cfg_attr(stage0, feature(rustc_private))]
@@ -62,6 +63,8 @@ extern crate rustc_bitflags;
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
 extern crate serialize;
+#[cfg(windows)]
+extern crate gcc; // Used to locate MSVC, not gcc :)
 
 pub use base::trans_crate;
 pub use back::symbol_names::provide;
@@ -77,8 +80,7 @@ pub mod back {
     pub(crate) mod symbol_export;
     pub(crate) mod symbol_names;
     pub mod write;
-    mod msvc;
-    mod rpath;
+    pub mod rpath;
 }
 
 mod diagnostics;
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 0e8a6606ae7..68f03d32e83 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -30,4 +30,4 @@ pulldown-cmark = { version = "0.0.14", default-features = false }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-gcc = "0.3.27"
+gcc = "0.3.50"
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 717892be2ab..e17918506fe 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -35,7 +35,7 @@ rustc_tsan = { path = "../librustc_tsan" }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
-gcc = "0.3.27"
+gcc = "0.3.50"
 
 [features]
 backtrace = []