From da100fe0bb7ba77dbcc346018068dbfdba053f6b Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 23 May 2017 19:02:23 -0700 Subject: [PATCH] Support VS 2017 Fixes #38584 --- src/Cargo.lock | 35 +-- src/bootstrap/Cargo.toml | 2 +- src/liballoc_jemalloc/Cargo.toml | 2 +- src/libcompiler_builtins/Cargo.toml | 2 +- src/libflate/Cargo.toml | 2 +- src/librustc_llvm/Cargo.toml | 2 +- src/librustc_trans/Cargo.toml | 3 + src/librustc_trans/back/link.rs | 41 ++- src/librustc_trans/back/msvc/arch.rs | 56 ----- src/librustc_trans/back/msvc/mod.rs | 305 ----------------------- src/librustc_trans/back/msvc/registry.rs | 136 ---------- src/librustc_trans/lib.rs | 6 +- src/librustdoc/Cargo.toml | 2 +- src/libstd/Cargo.toml | 2 +- 14 files changed, 63 insertions(+), 533 deletions(-) delete mode 100644 src/librustc_trans/back/msvc/arch.rs delete mode 100644 src/librustc_trans/back/msvc/mod.rs delete mode 100644 src/librustc_trans/back/msvc/registry.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index d55dd919bdf28..3e39893c3bdb7 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 cc560e0172e3a..8842dce0257dd 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 01393be9949ae..49e5baad74dda 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 3f844b3f09e3a..2c9cee5e7a093 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 5423da9c81c02..e5c611460f738 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 f97daa22ff662..f2eea014dd302 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 4ccc85257f3c9..7355b399360a3 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 e40267238801c..ee92a4b4a2dfe 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) { +// 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 c10312a8e1710..0000000000000 --- 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 or the MIT license -// , 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 { - 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 97648888fa9b9..0000000000000 --- 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 or the MIT license -// , 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) { - 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 { - 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 { - 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 { - 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 { - 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 { - 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) { - (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 8242f53896afc..0000000000000 --- 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 or the MIT license -// , 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 { - let key = key.encode_wide().chain(Some(0)).collect::>(); - 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 { - let name: &OsStr = name.as_ref(); - let name = name.encode_wide().chain(Some(0)).collect::>(); - 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 c111a3983e7ea..71fb2e5fb202a 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 0e8a6606ae79f..68f03d32e83cf 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 717892be2abad..e17918506fe5a 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 = []