From d76b8b20334d238906daf04e415a922072e51c8a Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@gnome.org>
Date: Tue, 2 Oct 2018 17:57:39 -0500
Subject: [PATCH] Update cc crate version

---
 Cargo.lock                                  |  12 +-
 third_party/rust/cc/.cargo-checksum.json    |   2 +-
 third_party/rust/cc/.travis.yml             |  23 +-
 third_party/rust/cc/Cargo.toml              |   4 +-
 third_party/rust/cc/README.md               |   2 +-
 third_party/rust/cc/src/lib.rs              | 709 ++++++++++++++------
 third_party/rust/cc/src/windows_registry.rs | 186 +++--
 third_party/rust/cc/tests/test.rs           | 142 ++--
 14 files changed, 940 insertions(+), 451 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e25b35203..eff696abe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -194,13 +194,13 @@ name = "bzip2-sys"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cc"
-version = "1.0.9"
+version = "1.0.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -255,7 +255,7 @@ name = "cmake"
 version = "0.1.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -896,7 +896,7 @@ name = "libloading"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1027,7 +1027,7 @@ name = "miniz_oxide_c_api"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2241,7 +2241,7 @@ dependencies = [
 "checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
 "checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24"
 "checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b"
-"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
+"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
 "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
diff -ru a/third_party/rust/cc/.cargo-checksum.json b/third_party/rust/cc/.cargo-checksum.json
--- a/third_party/rust/cc/.cargo-checksum.json	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/.cargo-checksum.json	2018-10-25 15:52:01.238237107 +0200
@@ -1 +1 @@
-{"files":{".travis.yml":"04e69a35c252b62a8b2a47c5bd2b8dcdfbfb97e9457fe78b2f310eb710a2a781","Cargo.toml":"8829f9474c56e0deb7279d19a303243130a46e2f0b46731c5fa68eddfa5824b1","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"186c5c8a62520cb7a3d90d77161c954b52ae8456fca0e0669bc3a5b889592a43","appveyor.yml":"ab45bfdcf2596f357225a54e730c34d518a8f3ad56c2ed33af682cfd45bddc02","src/bin/gcc-shim.rs":"d6be9137cb48b86891e7b263adbf492e1193ffe682db9ba4a88eb1079b874b58","src/com.rs":"8b9a54af5400c259f877126cc68ea63ada4fe66e84c9b840711c95e570b15774","src/lib.rs":"6e8cea99f5fc8e5982b1ea9a336ee2f9a6158a9498c8f0c36f1e8cee8c99716e","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"f5c45afc99ad3b7c1311242bc4baf37e861d740ab81bf6ca90e2aa283672e65a","src/winapi.rs":"d7929b36130e33f1caa6bd444b378b83023b2b82d589c6e0ab38c4ff6c950da8","src/windows_registry.rs":"5caea0d9ff6513a1fa2908cf8f72906da981af8de8756bae3ca182d755bdf552","tests/cc_env.rs":"bf7b14aa52af04294f648b2934f0f1830c5a0bdac1676310b8aa1f61458e7782","tests/support/mod.rs":"80dc87e54025197104cfb62d1af7a3400a3a0ddf0f2d98ea4ef4111cb1f0c890","tests/test.rs":"42a771b1b6e1ed83b31204439b8ba5190b151ae93d5fa402a18851273df39cc0"},"package":"2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"}
\ No newline at end of file
+{"files":{".travis.yml":"7b18272b20d4b58996deb3e2d5d76f15a27d6a63a061abeefb6553a2b8650736","Cargo.toml":"8b0ccc57b8ea0c2bfc417cc2e5c3a6750eec5c0a82d3de0ce09fe2197d2867af","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"3eeb4b0488908876c439a87cfe2bec6d550b37388993b2d8863fb1c587a84f46","appveyor.yml":"ab45bfdcf2596f357225a54e730c34d518a8f3ad56c2ed33af682cfd45bddc02","src/bin/gcc-shim.rs":"d6be9137cb48b86891e7b263adbf492e1193ffe682db9ba4a88eb1079b874b58","src/com.rs":"8b9a54af5400c259f877126cc68ea63ada4fe66e84c9b840711c95e570b15774","src/lib.rs":"a9c3515602e52501ef43dd4383418baa1e2eb66d250575d16dfcd3e60801bb25","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"f5c45afc99ad3b7c1311242bc4baf37e861d740ab81bf6ca90e2aa283672e65a","src/winapi.rs":"d7929b36130e33f1caa6bd444b378b83023b2b82d589c6e0ab38c4ff6c950da8","src/windows_registry.rs":"bdf8d441c57e3247a305a593e6280f41021ac81f45c2f3299c406b9a68817b20","tests/cc_env.rs":"bf7b14aa52af04294f648b2934f0f1830c5a0bdac1676310b8aa1f61458e7782","tests/support/mod.rs":"80dc87e54025197104cfb62d1af7a3400a3a0ddf0f2d98ea4ef4111cb1f0c890","tests/test.rs":"653b7d9ad6503aaf2ffc6c9b86014dbad456b53bcd124c9de4714067f49e5095"},"package":"f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"}
\ No newline at end of file
diff -ru a/third_party/rust/cc/.travis.yml b/third_party/rust/cc/.travis.yml
--- a/third_party/rust/cc/.travis.yml	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/.travis.yml	2018-10-25 15:52:01.238237107 +0200
@@ -3,7 +3,7 @@
 
 matrix:
   include:
-    - rust: 1.13.0
+    - rust: 1.16.0
       install:
       script: cargo build
     - rust: stable
@@ -18,10 +18,6 @@
       env: TARGET=x86_64-unknown-linux-gnu NO_ADD=1
     - rust: nightly
       env: TARGET=x86_64-unknown-linux-gnu NO_ADD=1
-    - install: rustup component add rustfmt-preview
-      script:
-        - cargo fmt -- --write-mode diff
-        - (cd cc-test && cargo fmt -- --write-mode diff)
 
     - rust: nightly
       before_script:
@@ -37,8 +33,17 @@
 
 script:
   - cargo build --verbose
-  - cargo test --verbose $NO_RUN
-  - cargo test --verbose --features parallel $NO_RUN
+  # FIXME: no idea why `--test-threads=1` is required on the OSX builder, it
+  # just randomly broke one day when the travis image was upgraded, and
+  # debugging turned up no easily found source of bugs...
+  #
+  # good build - https://travis-ci.org/alexcrichton/cc-rs/builds/409602374
+  #  bad build - https://travis-ci.org/alexcrichton/cc-rs/builds/410489079
+  #
+  # Those are using the same compiler, same commit, same... everything. Except
+  # the OSX image! No idea what changed...
+  - cargo test --verbose $NO_RUN -- --test-threads=1
+  - cargo test --verbose --features parallel $NO_RUN -- --test-threads=1
   - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET $NO_RUN
   - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET --features parallel $NO_RUN
   - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET --release $NO_RUN
diff -ru a/third_party/rust/cc/Cargo.toml b/third_party/rust/cc/Cargo.toml
--- a/third_party/rust/cc/Cargo.toml	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/Cargo.toml	2018-10-25 15:52:01.238237107 +0200
@@ -12,7 +12,7 @@
 
 [package]
 name = "cc"
-version = "1.0.9"
+version = "1.0.25"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n"
 homepage = "https://github.com/alexcrichton/cc-rs"
diff -ru a/third_party/rust/cc/README.md b/third_party/rust/cc/README.md
--- a/third_party/rust/cc/README.md	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/README.md	2018-10-25 15:52:01.238237107 +0200
@@ -198,5 +198,5 @@
 ### Contribution
 
 Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be
+for inclusion in cc-rs by you, as defined in the Apache-2.0 license, shall be
 dual licensed as above, without any additional terms or conditions.
diff -ru a/third_party/rust/cc/src/lib.rs b/third_party/rust/cc/src/lib.rs
--- a/third_party/rust/cc/src/lib.rs	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/src/lib.rs	2018-10-25 15:52:01.238237107 +0200
@@ -116,7 +116,9 @@
     shared_flag: Option<bool>,
     static_flag: Option<bool>,
     warnings_into_errors: bool,
-    warnings: bool,
+    warnings: Option<bool>,
+    extra_warnings: Option<bool>,
+    env_cache: Arc<Mutex<HashMap<String, Option<String>>>>,
 }
 
 /// Represents the types of errors that may occur while using cc-rs.
@@ -174,6 +176,7 @@
     env: Vec<(OsString, OsString)>,
     family: ToolFamily,
     cuda: bool,
+    removed_args: Vec<OsString>,
 }
 
 /// Represents the family of tools this tool belongs to.
@@ -189,22 +192,27 @@
     /// and its cross-compilation approach is different.
     Clang,
     /// Tool is the MSVC cl.exe.
-    Msvc,
+    Msvc { clang_cl: bool },
 }
 
 impl ToolFamily {
     /// What the flag to request debug info for this family of tools look like
-    fn debug_flag(&self) -> &'static str {
+    fn add_debug_flags(&self, cmd: &mut Tool) {
         match *self {
-            ToolFamily::Msvc => "/Z7",
-            ToolFamily::Gnu | ToolFamily::Clang => "-g",
+            ToolFamily::Msvc { .. } => {
+                cmd.push_cc_arg("/Z7".into());
+            }
+            ToolFamily::Gnu | ToolFamily::Clang => {
+                cmd.push_cc_arg("-g".into());
+                cmd.push_cc_arg("-fno-omit-frame-pointer".into());
+            }
         }
     }
 
     /// What the flag to include directories into header search path looks like
     fn include_flag(&self) -> &'static str {
         match *self {
-            ToolFamily::Msvc => "/I",
+            ToolFamily::Msvc { .. } => "/I",
             ToolFamily::Gnu | ToolFamily::Clang => "-I",
         }
     }
@@ -212,26 +220,31 @@
     /// What the flag to request macro-expanded source output looks like
     fn expand_flag(&self) -> &'static str {
         match *self {
-            ToolFamily::Msvc => "/E",
+            ToolFamily::Msvc { .. } => "/E",
             ToolFamily::Gnu | ToolFamily::Clang => "-E",
         }
     }
 
     /// What the flags to enable all warnings
-    fn warnings_flags(&self) -> &'static [&'static str] {
-        static MSVC_FLAGS: &'static [&'static str] = &["/W4"];
-        static GNU_CLANG_FLAGS: &'static [&'static str] = &["-Wall", "-Wextra"];
+    fn warnings_flags(&self) -> &'static str {
+        match *self {
+            ToolFamily::Msvc { .. } => "/W4",
+            ToolFamily::Gnu | ToolFamily::Clang => "-Wall",
+        }
+    }
 
+    /// What the flags to enable extra warnings
+    fn extra_warnings_flags(&self) -> Option<&'static str> {
         match *self {
-            ToolFamily::Msvc => &MSVC_FLAGS,
-            ToolFamily::Gnu | ToolFamily::Clang => &GNU_CLANG_FLAGS,
+            ToolFamily::Msvc { .. } => None,
+            ToolFamily::Gnu | ToolFamily::Clang => Some("-Wextra"),
         }
     }
 
     /// What the flag to turn warning into errors
     fn warnings_to_errors_flag(&self) -> &'static str {
         match *self {
-            ToolFamily::Msvc => "/WX",
+            ToolFamily::Msvc { .. } => "/WX",
             ToolFamily::Gnu | ToolFamily::Clang => "-Werror",
         }
     }
@@ -240,7 +253,7 @@
     /// debug info flag passed to the C++ compiler.
     fn nvcc_debug_flag(&self) -> &'static str {
         match *self {
-            ToolFamily::Msvc => unimplemented!(),
+            ToolFamily::Msvc { .. } => unimplemented!(),
             ToolFamily::Gnu | ToolFamily::Clang => "-G",
         }
     }
@@ -249,10 +262,14 @@
     /// compiler.
     fn nvcc_redirect_flag(&self) -> &'static str {
         match *self {
-            ToolFamily::Msvc => unimplemented!(),
+            ToolFamily::Msvc { .. } => unimplemented!(),
             ToolFamily::Gnu | ToolFamily::Clang => "-Xcompiler",
         }
     }
+
+    fn verbose_stderr(&self) -> bool {
+        *self == ToolFamily::Clang
+    }
 }
 
 /// Represents an object.
@@ -303,8 +320,10 @@
             cargo_metadata: true,
             pic: None,
             static_crt: None,
-            warnings: true,
+            warnings: None,
+            extra_warnings: None,
             warnings_into_errors: false,
+            env_cache: Arc::new(Mutex::new(HashMap::new())),
         }
     }
 
@@ -406,15 +425,23 @@
         let src = self.ensure_check_file()?;
         let obj = out_dir.join("flag_check");
         let target = self.get_target()?;
+        let host = self.get_host()?;
         let mut cfg = Build::new();
         cfg.flag(flag)
             .target(&target)
             .opt_level(0)
-            .host(&target)
+            .host(&host)
             .debug(false)
             .cpp(self.cpp)
             .cuda(self.cuda);
-        let compiler = cfg.try_get_compiler()?;
+        let mut compiler = cfg.try_get_compiler()?;
+
+        // Clang uses stderr for verbose output, which yields a false positive
+        // result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
+        if compiler.family.verbose_stderr() {
+            compiler.remove_arg("-v".into());
+        }
+
         let mut cmd = compiler.to_command();
         let is_arm = target.contains("aarch64") || target.contains("arm");
         command_add_output_file(&mut cmd, &obj, target.contains("msvc"), false, is_arm);
@@ -572,7 +599,30 @@
     ///     .compile("libfoo.a");
     /// ```
     pub fn warnings(&mut self, warnings: bool) -> &mut Build {
-        self.warnings = warnings;
+        self.warnings = Some(warnings);
+        self.extra_warnings = Some(warnings);
+        self
+    }
+
+    /// Set extra warnings flags.
+    ///
+    /// Adds some flags:
+    /// - nothing for MSVC.
+    /// - "-Wextra" for GNU and Clang.
+    ///
+    /// Enabled by default.
+    ///
+    /// # Example
+    ///
+    /// ```no_run
+    /// // Disables -Wextra, -Wall remains enabled:
+    /// cc::Build::new()
+    ///     .file("src/foo.c")
+    ///     .extra_warnings(false)
+    ///     .compile("libfoo.a");
+    /// ```
+    pub fn extra_warnings(&mut self, warnings: bool) -> &mut Build {
+        self.extra_warnings = Some(warnings);
         self
     }
 
@@ -582,6 +632,8 @@
     /// The default value of this property depends on the current target: On
     /// OS X `Some("c++")` is used, when compiling for a Visual Studio based
     /// target `None` is used and for other targets `Some("stdc++")` is used.
+    /// If the `CXXSTDLIB` environment variable is set, its value will
+    /// override the default value.
     ///
     /// A value of `None` indicates that no automatic linking should happen,
     /// otherwise cargo will link against the specified library.
@@ -1027,7 +1079,7 @@
         // Non-target flags
         // If the flag is not conditioned on target variable, it belongs here :)
         match cmd.family {
-            ToolFamily::Msvc => {
+            ToolFamily::Msvc { .. } => {
                 assert!(!self.cuda,
                     "CUDA C++ compilation not supported for MSVC, yet... but you are welcome to implement it :)");
 
@@ -1083,8 +1135,8 @@
                 let nvcc_debug_flag = cmd.family.nvcc_debug_flag().into();
                 cmd.args.push(nvcc_debug_flag);
             }
-            let debug_flag = cmd.family.debug_flag().into();
-            cmd.push_cc_arg(debug_flag);
+            let family = cmd.family;
+            family.add_debug_flags(&mut cmd);
         }
 
         // Target flags
@@ -1092,9 +1144,20 @@
             ToolFamily::Clang => {
                 cmd.args.push(format!("--target={}", target).into());
             }
-            ToolFamily::Msvc => {
-                if target.contains("i586") {
-                    cmd.args.push("/ARCH:IA32".into());
+            ToolFamily::Msvc { clang_cl } => {
+                if clang_cl {
+                    if target.contains("x86_64") {
+                        cmd.args.push("-m64".into());
+                    } else if target.contains("i586") {
+                        cmd.args.push("-m32".into());
+                        cmd.args.push("/arch:IA32".into());
+                    } else {
+                        cmd.args.push("-m32".into());
+                    }
+                } else {
+                    if target.contains("i586") {
+                        cmd.args.push("/ARCH:IA32".into());
+                    }
                 }
             }
             ToolFamily::Gnu => {
@@ -1106,24 +1169,35 @@
                     cmd.args.push("-m64".into());
                 }
 
-                if self.static_flag.is_none() && target.contains("musl") {
-                    cmd.args.push("-static".into());
+                if self.static_flag.is_none() {
+                    let features = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new());
+                    if features.contains("crt-static") {
+                        cmd.args.push("-static".into());
+                    }
                 }
 
                 // armv7 targets get to use armv7 instructions
-                if target.starts_with("armv7-") && target.contains("-linux-") {
+                if (target.starts_with("armv7") || target.starts_with("thumbv7")) && target.contains("-linux-") {
                     cmd.args.push("-march=armv7-a".into());
                 }
 
-                // On android we can guarantee some extra float instructions
-                // (specified in the android spec online)
-                if target.starts_with("armv7-linux-androideabi") {
-                    cmd.args.push("-march=armv7-a".into());
+                // (x86 Android doesn't say "eabi")
+                if target.contains("-androideabi") && target.contains("v7") {
+                    // -march=armv7-a handled above
                     cmd.args.push("-mthumb".into());
-                    cmd.args.push("-mfpu=vfpv3-d16".into());
+                    if !target.contains("neon") {
+                        // On android we can guarantee some extra float instructions
+                        // (specified in the android spec online)
+                        // NEON guarantees even more; see below.
+                        cmd.args.push("-mfpu=vfpv3-d16".into());
+                    }
                     cmd.args.push("-mfloat-abi=softfp".into());
                 }
 
+                if target.contains("neon") {
+                    cmd.args.push("-mfpu=neon-vfpv4".into());
+                }
+
                 if target.starts_with("armv4t-unknown-linux-") {
                     cmd.args.push("-march=armv4t".into());
                     cmd.args.push("-marm".into());
@@ -1190,6 +1264,31 @@
                 if target.starts_with("thumbv7m") {
                     cmd.args.push("-march=armv7-m".into());
                 }
+                if target.starts_with("armebv7r") | target.starts_with("armv7r") {
+                    if target.starts_with("armeb") {
+                        cmd.args.push("-mbig-endian".into());
+                    } else {
+                        cmd.args.push("-mlittle-endian".into());
+                    }
+
+                    // ARM mode
+                    cmd.args.push("-marm".into());
+
+                    // R Profile
+                    cmd.args.push("-march=armv7-r".into());
+
+                    if target.ends_with("eabihf") {
+                        // Calling convention
+                        cmd.args.push("-mfloat-abi=hard".into());
+
+                        // lowest common denominator FPU
+                        // (see Cortex-R4 technical reference manual)
+                        cmd.args.push("-mfpu=vfpv3-d16".into())
+                    } else {
+                        // Calling convention
+                        cmd.args.push("-mfloat-abi=soft".into());
+                    }
+                }
             }
         }
 
@@ -1227,9 +1326,19 @@
             cmd.args.push(directory.into());
         }
 
-        if self.warnings {
-            for flag in cmd.family.warnings_flags().iter() {
-                cmd.push_cc_arg(flag.into());
+        // If warnings and/or extra_warnings haven't been explicitly set,
+        // then we set them only if the environment doesn't already have
+        // CFLAGS/CXXFLAGS, since those variables presumably already contain
+        // the desired set of warnings flags.
+
+        if self.warnings.unwrap_or(if self.has_flags() { false } else { true }) {
+            let wflags = cmd.family.warnings_flags().into();
+            cmd.push_cc_arg(wflags);
+        }
+
+        if self.extra_warnings.unwrap_or(if self.has_flags() { false } else { true }) {
+            if let Some(wflags) = cmd.family.extra_warnings_flags() {
+                cmd.push_cc_arg(wflags.into());
             }
         }
 
@@ -1244,7 +1353,7 @@
         }
 
         for &(ref key, ref value) in self.definitions.iter() {
-            let lead = if let ToolFamily::Msvc = cmd.family {
+            let lead = if let ToolFamily::Msvc { .. } = cmd.family {
                 "/"
             } else {
                 "-"
@@ -1264,6 +1373,12 @@
         Ok(cmd)
     }
 
+    fn has_flags(&self) -> bool {
+        let flags_env_var_name = if self.cpp { "CXXFLAGS" } else { "CFLAGS" };
+        let flags_env_var_value = self.get_var(flags_env_var_name);
+        if let Ok(_) = flags_env_var_value { true } else { false }
+    }
+
     fn msvc_macro_assembler(&self) -> Result<(Command, String), Error> {
         let target = self.get_target()?;
         let tool = if target.contains("x86_64") {
@@ -1477,10 +1592,10 @@
         }
         let host = self.get_host()?;
         let target = self.get_target()?;
-        let (env, msvc, gnu, traditional) = if self.cpp {
-            ("CXX", "cl.exe", "g++", "c++")
+        let (env, msvc, gnu, traditional, clang) = if self.cpp {
+            ("CXX", "cl.exe", "g++", "c++", "clang++")
         } else {
-            ("CC", "cl.exe", "gcc", "cc")
+            ("CC", "cl.exe", "gcc", "cc", "clang")
         };
 
         // On Solaris, c++/cc unlikely to exist or be correct.
@@ -1490,6 +1605,8 @@
             traditional
         };
 
+        let cl_exe = windows_registry::find_tool(&target, "cl.exe");
+
         let tool_opt: Option<Tool> = self.env_tool(env)
             .map(|(tool, cc, args)| {
                 // chop off leading/trailing whitespace to work around
@@ -1521,7 +1638,7 @@
                     None
                 }
             })
-            .or_else(|| windows_registry::find_tool(&target, "cl.exe"));
+            .or_else(|| cl_exe.clone());
 
         let tool = match tool_opt {
             Some(t) => t,
@@ -1533,7 +1650,20 @@
                         format!("{}.exe", gnu)
                     }
                 } else if target.contains("android") {
-                    format!("{}-{}", target.replace("armv7", "arm"), gnu)
+                    let target = target
+                        .replace("armv7neon", "arm")
+                        .replace("armv7", "arm")
+                        .replace("thumbv7neon", "arm")
+                        .replace("thumbv7", "arm");
+                    let gnu_compiler = format!("{}-{}", target, gnu);
+                    let clang_compiler = format!("{}-{}", target, clang);
+                    // Check if gnu compiler is present
+                    // if not, use clang
+                    if Command::new(&gnu_compiler).spawn().is_ok() {
+                        gnu_compiler
+                    } else {
+                        clang_compiler
+                    }
                 } else if target.contains("cloudabi") {
                     format!("{}-{}", target, traditional)
                 } else if self.get_host()? != target {
@@ -1543,6 +1673,7 @@
                     let prefix = cross_compile.or(match &target[..] {
                         "aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"),
                         "aarch64-unknown-linux-musl" => Some("aarch64-linux-musl"),
+                        "aarch64-unknown-netbsd" => Some("aarch64--netbsd"),
                         "arm-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
                         "armv4t-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
                         "armv5te-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
@@ -1554,6 +1685,12 @@
                         "armv6-unknown-netbsd-eabihf" => Some("armv6--netbsdelf-eabihf"),
                         "armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                         "armv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
+                        "armv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
+                        "armv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
+                        "thumbv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
+                        "thumbv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
+                        "thumbv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
+                        "thumbv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                         "armv7-unknown-netbsd-eabihf" => Some("armv7--netbsdelf-eabihf"),
                         "i586-unknown-linux-musl" => Some("musl"),
                         "i686-pc-windows-gnu" => Some("i686-w64-mingw32"),
@@ -1573,6 +1710,10 @@
                         "sparc64-unknown-linux-gnu" => Some("sparc64-linux-gnu"),
                         "sparc64-unknown-netbsd" => Some("sparc64--netbsd"),
                         "sparcv9-sun-solaris" => Some("sparcv9-sun-solaris"),
+                        "armebv7r-none-eabi" => Some("arm-none-eabi"),
+                        "armebv7r-none-eabihf" => Some("arm-none-eabi"),
+                        "armv7r-none-eabi" => Some("arm-none-eabi"),
+                        "armv7r-none-eabihf" => Some("arm-none-eabi"),
                         "thumbv6m-none-eabi" => Some("arm-none-eabi"),
                         "thumbv7em-none-eabi" => Some("arm-none-eabi"),
                         "thumbv7em-none-eabihf" => Some("arm-none-eabi"),
@@ -1594,7 +1735,7 @@
             }
         };
 
-        let tool = if self.cuda {
+        let mut tool = if self.cuda {
             assert!(
                 tool.args.is_empty(),
                 "CUDA compilation currently assumes empty pre-existing args"
@@ -1612,6 +1753,27 @@
             tool
         };
 
+        // If we found `cl.exe` in our environment, the tool we're returning is
+        // an MSVC-like tool, *and* no env vars were set then set env vars for
+        // the tool that we're returning.
+        //
+        // Env vars are needed for things like `link.exe` being put into PATH as
+        // well as header include paths sometimes. These paths are automatically
+        // included by default but if the `CC` or `CXX` env vars are set these
+        // won't be used. This'll ensure that when the env vars are used to
+        // configure for invocations like `clang-cl` we still get a "works out
+        // of the box" experience.
+        if let Some(cl_exe) = cl_exe {
+            if tool.family == (ToolFamily::Msvc { clang_cl: true }) &&
+                tool.env.len() == 0 &&
+                target.contains("msvc")
+            {
+                for &(ref k, ref v) in cl_exe.env.iter() {
+                    tool.env.push((k.to_owned(), v.to_owned()));
+                }
+            }
+        }
+
         Ok(tool)
     }
 
@@ -1713,17 +1875,25 @@
         match self.cpp_link_stdlib.clone() {
             Some(s) => Ok(s),
             None => {
-                let target = self.get_target()?;
-                if target.contains("msvc") {
-                    Ok(None)
-                } else if target.contains("apple") {
-                    Ok(Some("c++".to_string()))
-                } else if target.contains("freebsd") {
-                    Ok(Some("c++".to_string()))
-                } else if target.contains("openbsd") {
-                    Ok(Some("c++".to_string()))
+                if let Ok(stdlib) = self.get_var("CXXSTDLIB") {
+                    if stdlib.is_empty() {
+                        Ok(None)
+                    } else {
+                        Ok(Some(stdlib))
+                    }
                 } else {
-                    Ok(Some("stdc++".to_string()))
+                    let target = self.get_target()?;
+                    if target.contains("msvc") {
+                        Ok(None)
+                    } else if target.contains("apple") {
+                        Ok(Some("c++".to_string()))
+                    } else if target.contains("freebsd") {
+                        Ok(Some("c++".to_string()))
+                    } else if target.contains("openbsd") {
+                        Ok(Some("c++".to_string()))
+                    } else {
+                        Ok(Some("stdc++".to_string()))
+                    }
                 }
             }
         }
@@ -1795,8 +1965,13 @@
     }
 
     fn getenv(&self, v: &str) -> Option<String> {
+        let mut cache = self.env_cache.lock().unwrap();
+        if let Some(val) = cache.get(v) {
+            return val.clone()
+        }
         let r = env::var(v).ok();
         self.print(&format!("{} = {:?}", v, r));
+        cache.insert(v.to_string(), r.clone());
         r
     }
 
@@ -1831,12 +2006,15 @@
     fn with_features(path: PathBuf, cuda: bool) -> Tool {
         // Try to detect family of the tool from its name, falling back to Gnu.
         let family = if let Some(fname) = path.file_name().and_then(|p| p.to_str()) {
-            if fname.contains("clang") {
+            if fname.contains("clang-cl") {
+                ToolFamily::Msvc { clang_cl: true }
+            } else if fname.contains("cl") &&
+                !fname.contains("cloudabi") &&
+                !fname.contains("uclibc") &&
+                !fname.contains("clang") {
+                ToolFamily::Msvc { clang_cl: false }
+            } else if fname.contains("clang") {
                 ToolFamily::Clang
-            } else if fname.contains("cl") && !fname.contains("cloudabi")
-                && !fname.contains("uclibc")
-            {
-                ToolFamily::Msvc
             } else {
                 ToolFamily::Gnu
             }
@@ -1851,9 +2029,15 @@
             env: Vec::new(),
             family: family,
             cuda: cuda,
+            removed_args: Vec::new(),
         }
     }
 
+    /// Add an argument to be stripped from the final command arguments.
+    fn remove_arg(&mut self, flag: OsString) {
+        self.removed_args.push(flag);
+    }
+
     /// Add a flag, and optionally prepend the NVCC wrapper flag "-Xcompiler".
     ///
     /// Currently this is only used for compiling CUDA sources, since NVCC only
@@ -1876,12 +2060,15 @@
             Some(ref cc_wrapper_path) => {
                 let mut cmd = Command::new(&cc_wrapper_path);
                 cmd.arg(&self.path);
-                cmd.args(&self.cc_wrapper_args);
                 cmd
             }
             None => Command::new(&self.path),
         };
-        cmd.args(&self.args);
+        cmd.args(&self.cc_wrapper_args);
+
+        let value = self.args.iter().filter(|a| !self.removed_args.contains(a)).collect::<Vec<_>>();
+        cmd.args(&value);
+
         for &(ref k, ref v) in self.env.iter() {
             cmd.env(k, v);
         }
@@ -1956,7 +2143,10 @@
 
     /// Whether the tool is MSVC-like.
     pub fn is_like_msvc(&self) -> bool {
-        self.family == ToolFamily::Msvc
+        match self.family {
+            ToolFamily::Msvc { .. } => true,
+            _ => false,
+        }
     }
 }
 
diff -ru a/third_party/rust/cc/src/windows_registry.rs b/third_party/rust/cc/src/windows_registry.rs
--- a/third_party/rust/cc/src/windows_registry.rs	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/src/windows_registry.rs	2018-10-25 15:52:01.238237107 +0200
@@ -65,6 +65,10 @@
         return impl_::find_msbuild(target);
     }
 
+    if tool.contains("devenv") {
+        return impl_::find_devenv(target);
+    }
+
     // If VCINSTALLDIR is set, then someone's probably already run vcvars and we
     // should just find whatever that indicates.
     if env::var_os("VCINSTALLDIR").is_some() {
@@ -325,6 +329,7 @@
             tool.libs.push(sdk_lib.join("um").join(sub));
             let sdk_include = sdk.join("include").join(&version);
             tool.include.push(sdk_include.join("um"));
+            tool.include.push(sdk_include.join("cppwinrt"));
             tool.include.push(sdk_include.join("winrt"));
             tool.include.push(sdk_include.join("shared"));
         } else if let Some(sdk) = get_sdk81_dir() {
@@ -518,8 +523,8 @@
             ("i586", X86_64) | ("i686", X86_64) => vec![("amd64_x86", "amd64"), ("", "")],
             ("x86_64", X86) => vec![("x86_amd64", "")],
             ("x86_64", X86_64) => vec![("amd64", "amd64"), ("x86_amd64", "")],
-            ("arm", X86) => vec![("x86_arm", "")],
-            ("arm", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
+            ("arm", X86) | ("thumbv7a", X86) => vec![("x86_arm", "")],
+            ("arm", X86_64) | ("thumbv7a", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
             _ => vec![],
         }
     }
@@ -529,7 +534,7 @@
         match arch {
             "i586" | "i686" => Some("x86"),
             "x86_64" => Some("x64"),
-            "arm" => Some("arm"),
+            "arm" | "thumbv7a" => Some("arm"),
             "aarch64" => Some("arm64"),
             _ => None,
         }
@@ -541,7 +546,7 @@
         match arch {
             "i586" | "i686" => Some(""),
             "x86_64" => Some("amd64"),
-            "arm" => Some("arm"),
+            "arm" | "thumbv7a" => Some("arm"),
             "aarch64" => Some("arm64"),
             _ => None,
         }
@@ -621,6 +626,26 @@
         }
     }
 
+    pub fn find_devenv(target: &str) -> Option<Tool> {
+        find_devenv_vs15(&target)
+    }
+
+    fn find_devenv_vs15(target: &str) -> Option<Tool> {
+        let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7";
+        LOCAL_MACHINE
+            .open(key.as_ref())
+            .ok()
+            .and_then(|key| key.query_str("15.0").ok())
+            .map(|path| {
+                let path = PathBuf::from(path).join(r"Common7\IDE\devenv.exe");
+                let mut tool = Tool::new(path);
+                if target.contains("x86_64") {
+                    tool.env.push(("Platform".into(), "X64".into()));
+                }
+                tool
+            })
+    }
+
     // see http://stackoverflow.com/questions/328017/path-to-msbuild
     pub fn find_msbuild(target: &str) -> Option<Tool> {
         // VS 15 (2017) changed how to locate msbuild
diff -ru a/third_party/rust/cc/tests/test.rs b/third_party/rust/cc/tests/test.rs
--- a/third_party/rust/cc/tests/test.rs	2018-10-17 22:39:45.000000000 +0200
+++ b/third_party/rust/cc/tests/test.rs	2018-10-25 15:52:01.242237138 +0200
@@ -1,6 +1,7 @@
 extern crate cc;
 extern crate tempdir;
 
+use std::env;
 use support::Test;
 
 mod support;
@@ -72,6 +73,32 @@
 }
 
 #[test]
+fn gnu_extra_warnings0() {
+    let test = Test::gnu();
+    test.gcc()
+        .warnings(true)
+        .extra_warnings(false)
+        .flag("-Wno-missing-field-initializers")
+        .file("foo.c")
+        .compile("foo");
+
+    test.cmd(0).must_have("-Wall").must_not_have("-Wextra");
+}
+
+#[test]
+fn gnu_extra_warnings1() {
+    let test = Test::gnu();
+    test.gcc()
+        .warnings(false)
+        .extra_warnings(true)
+        .flag("-Wno-missing-field-initializers")
+        .file("foo.c")
+        .compile("foo");
+
+    test.cmd(0).must_not_have("-Wall").must_have("-Wextra");
+}
+
+#[test]
 fn gnu_warnings_overridable() {
     let test = Test::gnu();
     test.gcc()
@@ -85,6 +112,30 @@
 }
 
 #[test]
+fn gnu_no_warnings_if_cflags() {
+    env::set_var("CFLAGS", "-Wflag-does-not-exist");
+    let test = Test::gnu();
+    test.gcc()
+        .file("foo.c")
+        .compile("foo");
+
+    test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra");
+    env::set_var("CFLAGS", "");
+}
+
+#[test]
+fn gnu_no_warnings_if_cxxflags() {
+    env::set_var("CXXFLAGS", "-Wflag-does-not-exist");
+    let test = Test::gnu();
+    test.gcc()
+        .file("foo.c")
+        .compile("foo");
+
+    test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra");
+    env::set_var("CXXFLAGS", "");
+}
+
+#[test]
 fn gnu_x86_64() {
     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
         let target = format!("x86_64-{}", vendor);
@@ -204,12 +255,14 @@
     let test = Test::gnu();
     test.gcc()
         .file("foo.c")
+        .flag("-v")
         .flag_if_supported("-Wall")
         .flag_if_supported("-Wflag-does-not-exist")
         .flag_if_supported("-std=c++11")
         .compile("foo");
 
     test.cmd(0)
+        .must_have("-v")
         .must_have("-Wall")
         .must_not_have("-Wflag-does-not-exist")
         .must_not_have("-std=c++11");
