Bug 1445528: Update 'cc' crate to version 1.0.9. r?jgraham draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 22 Mar 2018 13:43:03 -0700
changeset 771250 2987be11629754517924155b3439568b9976dfc1
parent 770820 68464218a41a5350ffa926e1b5d77fde75bc4e01
push id103638
push userdholbert@mozilla.com
push dateThu, 22 Mar 2018 20:43:13 +0000
reviewersjgraham
bugs1445528
milestone61.0a1
Bug 1445528: Update 'cc' crate to version 1.0.9. r?jgraham This patch was automatically generated by running the following commands: $ cargo update -p cc $ ./mach vendor rust MozReview-Commit-ID: 51NVIhtno6O
Cargo.lock
third_party/rust/cc/.cargo-checksum.json
third_party/rust/cc/.travis.yml
third_party/rust/cc/Cargo.toml
third_party/rust/cc/src/com.rs
third_party/rust/cc/src/lib.rs
third_party/rust/cc/src/registry.rs
third_party/rust/cc/src/setup_config.rs
third_party/rust/cc/src/winapi.rs
third_party/rust/cc/src/windows_registry.rs
third_party/rust/cc/tests/cc_env.rs
third_party/rust/cc/tests/support/mod.rs
third_party/rust/cc/tests/test.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -188,23 +188,23 @@ dependencies = [
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bzip2-sys"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cc"
-version = "1.0.4"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cexpr"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -249,17 +249,17 @@ dependencies = [
  "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cmake"
 version = "0.1.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cookie"
 version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -891,17 +891,17 @@ name = "libc"
 version = "0.2.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libloading"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libudev"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -1014,17 +1014,17 @@ dependencies = [
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "miniz_oxide_c_api"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.9 (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.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mio"
 version = "0.6.9"
@@ -2202,17 +2202,17 @@ dependencies = [
 "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
 "checksum bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"
 "checksum boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8380105befe91099e6f69206164072c05bc92427ff6aa8a5171388317346dd75"
 "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9"
 "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
 "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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0"
+"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
 "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"
 "checksum clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538"
 "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f"
 "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
 "checksum cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "746858cae4eae40fff37e1998320068df317bc247dc91a67c6cfa053afdc2abb"
 "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980"
--- a/third_party/rust/cc/.cargo-checksum.json
+++ b/third_party/rust/cc/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".travis.yml":"1a4a3f7f90349924378e93acbb524b9127e37c02cfbc6dc59fd904bbdc1c8d0b","Cargo.toml":"623dd06a83bcbf2f292ab51af93e9b79b689e3be06a62968b79f4e36f1bb769f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"186c5c8a62520cb7a3d90d77161c954b52ae8456fca0e0669bc3a5b889592a43","appveyor.yml":"ab45bfdcf2596f357225a54e730c34d518a8f3ad56c2ed33af682cfd45bddc02","src/bin/gcc-shim.rs":"d6be9137cb48b86891e7b263adbf492e1193ffe682db9ba4a88eb1079b874b58","src/com.rs":"0cb06f5db0fb70d27db0e5917ca337de6e7032119e6aabfea1bad9c719f5f34b","src/lib.rs":"996b650e19d5ccd6e64e741789427017c913644e980862a7286ec4ed53c14a17","src/registry.rs":"3876ef9573e3bbc050aef41a684b9a510cc1a91b15ae874fe032cf4377b4d116","src/setup_config.rs":"1a3eeb11c6847c31f2a4685b62ab35c76f0b6d5a17f7ed99e9df164283a771f7","src/winapi.rs":"cb5e6cab3eb570b0f97c660ca448ccfb5024262c0c7b245c181daad91a79f211","src/windows_registry.rs":"6de548aa94215e449f0e58e9a3b1702939d7c2f7b63a9040901c948bf138201d","tests/cc_env.rs":"7402315eea7ffa23b29b393c1de8e236294ede9de562ff0a562704a157135341","tests/support/mod.rs":"092551f9f6e3a999fa0aa02f93314aac0bda2b09268f948c423df56a43575e0b","tests/test.rs":"b1164258714e13173f3861126e97bedf1e29aa24618993c4eb0edd57c431dcc7"},"package":"deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0"}
\ No newline at end of file
+{"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
--- a/third_party/rust/cc/.travis.yml
+++ b/third_party/rust/cc/.travis.yml
@@ -7,40 +7,46 @@ matrix:
       install:
       script: cargo build
     - rust: stable
       env: TARGET=x86_64-unknown-linux-gnu NO_ADD=1
     - rust: stable
       env: TARGET=i686-unknown-linux-gnu
     - os: osx
       env: TARGET=x86_64-apple-darwin NO_ADD=1
+    - os: osx
+      env: TARGET=aarch64-apple-ios NO_RUN=--no-run TARGET_SYSROOT=$(xcrun -sdk iphoneos --show-sdk-path)
     - rust: beta
       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:
         - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
       install:
       script:
         - cargo doc --no-deps --all-features
       after_success:
         - travis-cargo --only nightly doc-upload
 
 install:
   - if [ -z "$NO_ADD" ]; then rustup target add $TARGET; fi
 
 script:
   - cargo build --verbose
-  - cargo test --verbose
-  - cargo test --verbose --features parallel
-  - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET
-  - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET --features parallel
-  - cargo test --manifest-path cc-test/Cargo.toml --target $TARGET --release
+  - cargo test --verbose $NO_RUN
+  - cargo test --verbose --features parallel $NO_RUN
+  - 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
   - cargo doc
   - cargo clean && cargo build
   - rustdoc --test README.md -L target/debug -L target/debug/deps
 
 env:
   global:
     secure: "CBtqrudgE0PS8x3kTr44jKbC2D4nfnmdYVecooNm0qnER4B4TSvZpZSQoCgKK6k4BYQuOSyFTOwYx6M79w39ZMOgyCP9ytB+tyMWL0/+ZuUQL04yVg4M5vd3oJMkOaXbvG56ncgPyFrseY+FPDg+mXAzvJk/nily37YXjkQj2D0="
 
--- a/third_party/rust/cc/Cargo.toml
+++ b/third_party/rust/cc/Cargo.toml
@@ -7,28 +7,28 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cc"
-version = "1.0.4"
+version = "1.0.9"
 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"
 documentation = "https://docs.rs/cc"
 readme = "README.md"
 keywords = ["build-dependencies"]
 categories = ["development-tools"]
 license = "MIT/Apache-2.0"
 repository = "https://github.com/alexcrichton/cc-rs"
 [dependencies.rayon]
-version = "0.9"
+version = "1.0"
 optional = true
 [dev-dependencies.tempdir]
 version = "0.3"
 
 [features]
 parallel = ["rayon"]
 [badges.appveyor]
 repository = "alexcrichton/cc-rs"
--- a/third_party/rust/cc/src/com.rs
+++ b/third_party/rust/cc/src/com.rs
@@ -14,76 +14,101 @@ use std::os::windows::ffi::{OsStrExt, Os
 use std::ptr::null_mut;
 use std::slice::from_raw_parts;
 use winapi::Interface;
 use winapi::BSTR;
 use winapi::CoInitializeEx;
 use winapi::COINIT_MULTITHREADED;
 use winapi::{SysFreeString, SysStringLen};
 use winapi::IUnknown;
-use winapi::{S_OK, S_FALSE, HRESULT};
+use winapi::{HRESULT, S_FALSE, S_OK};
 
 pub fn initialize() -> Result<(), HRESULT> {
     let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) };
     if err != S_OK && err != S_FALSE {
         // S_FALSE just means COM is already initialized
         return Err(err);
     }
     Ok(())
 }
 
-pub struct ComPtr<T>(*mut T) where T: Interface;
-impl<T> ComPtr<T> where T: Interface {
+pub struct ComPtr<T>(*mut T)
+where
+    T: Interface;
+impl<T> ComPtr<T>
+where
+    T: Interface,
+{
     /// Creates a `ComPtr` to wrap a raw pointer.
     /// It takes ownership over the pointer which means it does __not__ call `AddRef`.
     /// `T` __must__ be a COM interface that inherits from `IUnknown`.
     pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {
         assert!(!ptr.is_null());
         ComPtr(ptr)
     }
     /// Casts up the inheritance chain
-    pub fn up<U>(self) -> ComPtr<U> where T: Deref<Target=U>, U: Interface {
+    pub fn up<U>(self) -> ComPtr<U>
+    where
+        T: Deref<Target = U>,
+        U: Interface,
+    {
         ComPtr(self.into_raw() as *mut U)
     }
     /// Extracts the raw pointer.
     /// You are now responsible for releasing it yourself.
     pub fn into_raw(self) -> *mut T {
         let p = self.0;
         forget(self);
         p
     }
     /// For internal use only.
     fn as_unknown(&self) -> &IUnknown {
         unsafe { &*(self.0 as *mut IUnknown) }
     }
     /// Performs QueryInterface fun.
-    pub fn cast<U>(&self) -> Result<ComPtr<U>, i32> where U: Interface {
+    pub fn cast<U>(&self) -> Result<ComPtr<U>, i32>
+    where
+        U: Interface,
+    {
         let mut obj = null_mut();
         let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(unsafe { ComPtr::from_raw(obj as *mut U) })
     }
 }
-impl<T> Deref for ComPtr<T> where T: Interface {
+impl<T> Deref for ComPtr<T>
+where
+    T: Interface,
+{
     type Target = T;
     fn deref(&self) -> &T {
         unsafe { &*self.0 }
     }
 }
-impl<T> Clone for ComPtr<T> where T: Interface {
+impl<T> Clone for ComPtr<T>
+where
+    T: Interface,
+{
     fn clone(&self) -> Self {
         unsafe {
             self.as_unknown().AddRef();
             ComPtr::from_raw(self.0)
         }
     }
 }
-impl<T> Drop for ComPtr<T> where T: Interface {
+impl<T> Drop for ComPtr<T>
+where
+    T: Interface,
+{
     fn drop(&mut self) {
-        unsafe { self.as_unknown().Release(); }
+        unsafe {
+            self.as_unknown().Release();
+        }
     }
 }
 pub struct BStr(BSTR);
 impl BStr {
     pub unsafe fn from_raw(s: BSTR) -> BStr {
         BStr(s)
     }
     pub fn to_osstring(&self) -> OsString {
@@ -97,29 +122,34 @@ impl Drop for BStr {
         unsafe { SysFreeString(self.0) };
     }
 }
 
 pub trait ToWide {
     fn to_wide(&self) -> Vec<u16>;
     fn to_wide_null(&self) -> Vec<u16>;
 }
-impl<T> ToWide for T where T: AsRef<OsStr> {
+impl<T> ToWide for T
+where
+    T: AsRef<OsStr>,
+{
     fn to_wide(&self) -> Vec<u16> {
         self.as_ref().encode_wide().collect()
     }
     fn to_wide_null(&self) -> Vec<u16> {
         self.as_ref().encode_wide().chain(Some(0)).collect()
     }
 }
-pub trait FromWide where Self: Sized {
+pub trait FromWide
+where
+    Self: Sized,
+{
     fn from_wide(wide: &[u16]) -> Self;
     fn from_wide_null(wide: &[u16]) -> Self {
         let len = wide.iter().take_while(|&&c| c != 0).count();
         Self::from_wide(&wide[..len])
     }
 }
 impl FromWide for OsString {
     fn from_wide(wide: &[u16]) -> OsString {
         OsStringExt::from_wide(wide)
     }
 }
-
--- a/third_party/rust/cc/src/lib.rs
+++ b/third_party/rust/cc/src/lib.rs
@@ -56,25 +56,24 @@
 #![doc(html_root_url = "https://docs.rs/cc/1.0")]
 #![cfg_attr(test, deny(warnings))]
 #![deny(missing_docs)]
 
 #[cfg(feature = "parallel")]
 extern crate rayon;
 
 use std::env;
-use std::ffi::{OsString, OsStr};
+use std::ffi::{OsStr, OsString};
 use std::fs;
-use std::path::{PathBuf, Path};
-use std::process::{Command, Stdio, Child};
-use std::io::{self, BufReader, BufRead, Read, Write};
+use std::path::{Path, PathBuf};
+use std::process::{Child, Command, Stdio};
+use std::io::{self, BufRead, BufReader, Read, Write};
 use std::thread::{self, JoinHandle};
-
-#[cfg(feature = "parallel")]
-use std::sync::Mutex;
+use std::collections::HashMap;
+use std::sync::{Arc, Mutex};
 
 // These modules are all glue to support reading the MSVC version from
 // the registry and from COM interfaces
 #[cfg(windows)]
 mod registry;
 #[cfg(windows)]
 #[macro_use]
 mod winapi;
@@ -92,16 +91,17 @@ pub mod windows_registry;
 /// documentation on each method itself.
 #[derive(Clone, Debug)]
 pub struct Build {
     include_directories: Vec<PathBuf>,
     definitions: Vec<(String, Option<String>)>,
     objects: Vec<PathBuf>,
     flags: Vec<String>,
     flags_supported: Vec<String>,
+    known_flag_support_status: Arc<Mutex<HashMap<String, bool>>>,
     files: Vec<PathBuf>,
     cpp: bool,
     cpp_link_stdlib: Option<Option<String>>,
     cpp_set_stdlib: Option<String>,
     cuda: bool,
     target: Option<String>,
     host: Option<String>,
     out_dir: Option<PathBuf>,
@@ -236,64 +236,60 @@ impl ToolFamily {
         }
     }
 
     /// NVCC-specific. Device code debug info flag. This is separate from the
     /// debug info flag passed to the C++ compiler.
     fn nvcc_debug_flag(&self) -> &'static str {
         match *self {
             ToolFamily::Msvc => unimplemented!(),
-            ToolFamily::Gnu |
-            ToolFamily::Clang => "-G",
+            ToolFamily::Gnu | ToolFamily::Clang => "-G",
         }
     }
 
     /// NVCC-specific. Redirect the following flag to the underlying C++
     /// compiler.
     fn nvcc_redirect_flag(&self) -> &'static str {
         match *self {
             ToolFamily::Msvc => unimplemented!(),
-            ToolFamily::Gnu |
-            ToolFamily::Clang => "-Xcompiler",
+            ToolFamily::Gnu | ToolFamily::Clang => "-Xcompiler",
         }
     }
 }
 
 /// Represents an object.
 ///
 /// This is a source file -> object file pair.
 #[derive(Clone, Debug)]
 struct Object {
     src: PathBuf,
     dst: PathBuf,
 }
 
 impl Object {
     /// Create a new source file -> object file pair.
     fn new(src: PathBuf, dst: PathBuf) -> Object {
-        Object {
-            src: src,
-            dst: dst,
-        }
+        Object { src: src, dst: dst }
     }
 }
 
 impl Build {
     /// Construct a new instance of a blank set of configuration.
     ///
     /// This builder is finished with the [`compile`] function.
     ///
     /// [`compile`]: struct.Build.html#method.compile
     pub fn new() -> Build {
         Build {
             include_directories: Vec::new(),
             definitions: Vec::new(),
             objects: Vec::new(),
             flags: Vec::new(),
             flags_supported: Vec::new(),
+            known_flag_support_status: Arc::new(Mutex::new(HashMap::new())),
             files: Vec::new(),
             shared_flag: None,
             static_flag: None,
             cpp: false,
             cpp_link_stdlib: None,
             cpp_set_stdlib: None,
             cuda: false,
             target: None,
@@ -339,20 +335,18 @@ impl Build {
     /// ```no_run
     /// cc::Build::new()
     ///     .file("src/foo.c")
     ///     .define("FOO", "BAR")
     ///     .define("BAZ", None)
     ///     .compile("foo");
     /// ```
     pub fn define<'a, V: Into<Option<&'a str>>>(&mut self, var: &str, val: V) -> &mut Build {
-        self.definitions.push((
-            var.to_string(),
-            val.into().map(|s| s.to_string()),
-        ));
+        self.definitions
+            .push((var.to_string(), val.into().map(|s| s.to_string())));
         self
     }
 
     /// Add an arbitrary object file to link in
     pub fn object<P: AsRef<Path>>(&mut self, obj: P) -> &mut Build {
         self.objects.push(obj.as_ref().to_path_buf());
         self
     }
@@ -393,43 +387,56 @@ impl Build {
 
     /// Run the compiler to test if it accepts the given flag.
     ///
     /// For a convenience method for setting flags conditionally,
     /// see `flag_if_supported()`.
     ///
     /// It may return error if it's unable to run the compilier with a test file
     /// (e.g. the compiler is missing or a write to the `out_dir` failed).
+    ///
+    /// Note: Once computed, the result of this call is stored in the
+    /// `known_flag_support` field. If `is_flag_supported(flag)`
+    /// is called again, the result will be read from the hash table.
     pub fn is_flag_supported(&self, flag: &str) -> Result<bool, Error> {
+        let mut known_status = self.known_flag_support_status.lock().unwrap();
+        if let Some(is_supported) = known_status.get(flag).cloned() {
+            return Ok(is_supported);
+        }
+
         let out_dir = self.get_out_dir()?;
         let src = self.ensure_check_file()?;
         let obj = out_dir.join("flag_check");
         let target = self.get_target()?;
         let mut cfg = Build::new();
         cfg.flag(flag)
             .target(&target)
             .opt_level(0)
             .host(&target)
             .debug(false)
             .cpp(self.cpp)
             .cuda(self.cuda);
         let compiler = cfg.try_get_compiler()?;
         let mut cmd = compiler.to_command();
-        command_add_output_file(&mut cmd, &obj, target.contains("msvc"), false);
+        let is_arm = target.contains("aarch64") || target.contains("arm");
+        command_add_output_file(&mut cmd, &obj, target.contains("msvc"), false, is_arm);
 
         // We need to explicitly tell msvc not to link and create an exe
         // in the root directory of the crate
         if target.contains("msvc") {
             cmd.arg("/c");
         }
 
         cmd.arg(&src);
 
         let output = cmd.output()?;
-        Ok(output.stderr.is_empty())
+        let is_supported = output.stderr.is_empty();
+
+        known_status.insert(flag.to_owned(), is_supported);
+        Ok(is_supported)
     }
 
     /// Add an arbitrary flag to the invocation of the compiler if it supports it
     ///
     /// # Example
     ///
     /// ```no_run
     /// cc::Build::new()
@@ -772,19 +779,18 @@ impl Build {
     }
 
     #[doc(hidden)]
     pub fn __set_env<A, B>(&mut self, a: A, b: B) -> &mut Build
     where
         A: AsRef<OsStr>,
         B: AsRef<OsStr>,
     {
-        self.env.push(
-            (a.as_ref().to_owned(), b.as_ref().to_owned()),
-        );
+        self.env
+            .push((a.as_ref().to_owned(), b.as_ref().to_owned()));
         self
     }
 
     /// Run the compiler, generating the file `output`
     ///
     /// This will return a result instead of panicing; see compile() for the complete description.
     pub fn try_compile(&self, output: &str) -> Result<(), Error> {
         let (lib_name, gnu_lib_name) = if output.starts_with("lib") && output.ends_with(".a") {
@@ -875,76 +881,67 @@ impl Build {
             fail(&e.message);
         }
     }
 
     #[cfg(feature = "parallel")]
     fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> {
         use self::rayon::prelude::*;
 
-        let mut cfg = rayon::Configuration::new();
         if let Ok(amt) = env::var("NUM_JOBS") {
             if let Ok(amt) = amt.parse() {
-                cfg = cfg.num_threads(amt);
-            }
-        }
-        drop(rayon::initialize(cfg));
-
-        let results: Mutex<Vec<Result<(), Error>>> = Mutex::new(Vec::new());
-
-        objs.par_iter().with_max_len(1).for_each(
-            |obj| {
-                let res = self.compile_object(obj);
-                results.lock().unwrap().push(res)
-            },
-        );
-
-        // Check for any errors and return the first one found.
-        for result in results.into_inner().unwrap().iter() {
-            if result.is_err() {
-                return result.clone();
+                let _ = rayon::ThreadPoolBuilder::new()
+                    .num_threads(amt)
+                    .build_global();
             }
         }
 
-        Ok(())
+        // Check for any errors and return the first one found.
+        objs.par_iter()
+            .with_max_len(1)
+            .map(|obj| self.compile_object(obj))
+            .collect()
     }
 
     #[cfg(not(feature = "parallel"))]
     fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> {
         for obj in objs {
             self.compile_object(obj)?;
         }
         Ok(())
     }
 
     fn compile_object(&self, obj: &Object) -> Result<(), Error> {
         let is_asm = obj.src.extension().and_then(|s| s.to_str()) == Some("asm");
-        let msvc = self.get_target()?.contains("msvc");
+        let target = self.get_target()?;
+        let msvc = target.contains("msvc");
         let (mut cmd, name) = if msvc && is_asm {
             self.msvc_macro_assembler()?
         } else {
             let compiler = self.try_get_compiler()?;
             let mut cmd = compiler.to_command();
             for &(ref a, ref b) in self.env.iter() {
                 cmd.env(a, b);
             }
             (
                 cmd,
                 compiler
                     .path
                     .file_name()
-                    .ok_or_else(|| {
-                        Error::new(ErrorKind::IOError, "Failed to get compiler path.")
-                    })?
+                    .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))?
                     .to_string_lossy()
                     .into_owned(),
             )
         };
-        command_add_output_file(&mut cmd, &obj.dst, msvc, is_asm);
-        cmd.arg(if msvc { "/c" } else { "-c" });
+        let is_arm = target.contains("aarch64") || target.contains("arm");
+        command_add_output_file(&mut cmd, &obj.dst, msvc, is_asm, is_arm);
+        // armasm and armasm64 don't requrie -c option
+        if !msvc || !is_asm || !is_arm {
+            cmd.arg(if msvc { "/c" } else { "-c" });
+        }
         cmd.arg(&obj.src);
 
         run(&mut cmd, &name)?;
         Ok(())
     }
 
     /// This will return a result instead of panicing; see expand() for the complete description.
     pub fn try_expand(&self) -> Result<Vec<u8>, Error> {
@@ -962,19 +959,17 @@ impl Build {
 
         for file in self.files.iter() {
             cmd.arg(file);
         }
 
         let name = compiler
             .path
             .file_name()
-            .ok_or_else(|| {
-                Error::new(ErrorKind::IOError, "Failed to get compiler path.")
-            })?
+            .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))?
             .to_string_lossy()
             .into_owned();
 
         Ok(run_output(&mut cmd, &name)?)
     }
 
     /// Run the compiler, returning the macro-expanded version of the input files.
     ///
@@ -1049,34 +1044,36 @@ impl Build {
                         } else {
                             "/MD"
                         }
                     }
                 };
                 cmd.args.push(crt_flag.into());
 
                 match &opt_level[..] {
-                    "z" | "s" => cmd.args.push("/Os".into()),
-                    "1" => cmd.args.push("/O1".into()),
+                    // Msvc uses /O1 to enable all optimizations that minimize code size.
+                    "z" | "s" | "1" => cmd.args.push("/O1".into()),
                     // -O3 is a valid value for gcc and clang compilers, but not msvc. Cap to /O2.
                     "2" | "3" => cmd.args.push("/O2".into()),
                     _ => {}
                 }
             }
             ToolFamily::Gnu | ToolFamily::Clang => {
                 // arm-linux-androideabi-gcc 4.8 shipped with Android NDK does
                 // not support '-Oz'
                 if opt_level == "z" && cmd.family != ToolFamily::Clang {
                     cmd.args.push("-Os".into());
                 } else {
                     cmd.args.push(format!("-O{}", opt_level).into());
                 }
 
-                cmd.push_cc_arg("-ffunction-sections".into());
-                cmd.push_cc_arg("-fdata-sections".into());
+                if !target.contains("-ios") {
+                    cmd.push_cc_arg("-ffunction-sections".into());
+                    cmd.push_cc_arg("-fdata-sections".into());
+                }
                 if self.pic.unwrap_or(!target.contains("windows-gnu")) {
                     cmd.push_cc_arg("-fPIC".into());
                 }
             }
         }
         for arg in self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }) {
             cmd.args.push(arg.into());
         }
@@ -1164,17 +1161,17 @@ impl Build {
                     cmd.args.push("-march=i686".into());
                 }
 
                 // Looks like `musl-gcc` makes is hard for `-m32` to make its way
                 // all the way to the linker, so we need to actually instruct the
                 // linker that we're generating 32-bit executables as well. This'll
                 // typically only be used for build scripts which transitively use
                 // these flags that try to compile executables.
-                if target == "i686-unknown-linux-musl" {
+                if target == "i686-unknown-linux-musl" || target == "i586-unknown-linux-musl" {
                     cmd.args.push("-Wl,-melf_i386".into());
                 }
 
                 if target.starts_with("thumb") {
                     cmd.args.push("-mthumb".into());
 
                     if target.ends_with("eabihf") {
                         cmd.args.push("-mfloat-abi=hard".into())
@@ -1207,24 +1204,23 @@ impl Build {
         }
         if self.shared_flag.unwrap_or(false) {
             cmd.args.push("-shared".into());
         }
 
         if self.cpp {
             match (self.cpp_set_stdlib.as_ref(), cmd.family) {
                 (None, _) => {}
-                (Some(stdlib), ToolFamily::Gnu) |
-                (Some(stdlib), ToolFamily::Clang) => {
+                (Some(stdlib), ToolFamily::Gnu) | (Some(stdlib), ToolFamily::Clang) => {
                     cmd.push_cc_arg(format!("-stdlib=lib{}", stdlib).into());
                 }
                 _ => {
                     println!(
                         "cargo:warning=cpp_set_stdlib is specified, but the {:?} compiler \
-                              does not support this option, ignored",
+                         does not support this option, ignored",
                         cmd.family
                     );
                 }
             }
         }
 
         for directory in self.include_directories.iter() {
             cmd.args.push(cmd.family.include_flag().into());
@@ -1267,16 +1263,20 @@ impl Build {
 
         Ok(cmd)
     }
 
     fn msvc_macro_assembler(&self) -> Result<(Command, String), Error> {
         let target = self.get_target()?;
         let tool = if target.contains("x86_64") {
             "ml64.exe"
+        } else if target.contains("arm") {
+            "armasm.exe"
+        } else if target.contains("aarch64") {
+            "armasm64.exe"
         } else {
             "ml.exe"
         };
         let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| self.cmd(tool));
         for directory in self.include_directories.iter() {
             cmd.arg("/I").arg(directory);
         }
         for &(ref key, ref value) in self.definitions.iter() {
@@ -1302,30 +1302,65 @@ impl Build {
         // appends to it, which we don't want.
         let _ = fs::remove_file(&dst);
 
         let objects: Vec<_> = objs.iter().map(|obj| obj.dst.clone()).collect();
         let target = self.get_target()?;
         if target.contains("msvc") {
             let mut cmd = match self.archiver {
                 Some(ref s) => self.cmd(s),
-                None => {
-                    windows_registry::find(&target, "lib.exe").unwrap_or_else(
-                        || {
-                            self.cmd("lib.exe")
-                        },
-                    )
-                }
+                None => windows_registry::find(&target, "lib.exe")
+                    .unwrap_or_else(|| self.cmd("lib.exe")),
             };
+
             let mut out = OsString::from("/OUT:");
             out.push(dst);
-            run(
-                cmd.arg(out).arg("/nologo").args(&objects).args(&self.objects),
-                "lib.exe",
-            )?;
+            cmd.arg(out).arg("/nologo");
+
+            // Similar to https://github.com/rust-lang/rust/pull/47507
+            // and https://github.com/rust-lang/rust/pull/48548
+            let estimated_command_line_len = objects
+                .iter()
+                .chain(&self.objects)
+                .map(|a| a.as_os_str().len())
+                .sum::<usize>();
+            if estimated_command_line_len > 1024 * 6 {
+                let mut args = String::from("\u{FEFF}"); // BOM
+                for arg in objects.iter().chain(&self.objects) {
+                    args.push('"');
+                    for c in arg.to_str().unwrap().chars() {
+                        if c == '"' {
+                            args.push('\\')
+                        }
+                        args.push(c)
+                    }
+                    args.push('"');
+                    args.push('\n');
+                }
+
+                let mut utf16le = Vec::new();
+                for code_unit in args.encode_utf16() {
+                    utf16le.push(code_unit as u8);
+                    utf16le.push((code_unit >> 8) as u8);
+                }
+
+                let mut args_file = OsString::from(dst);
+                args_file.push(".args");
+                fs::File::create(&args_file)
+                    .unwrap()
+                    .write_all(&utf16le)
+                    .unwrap();
+
+                let mut args_file_arg = OsString::from("@");
+                args_file_arg.push(args_file);
+                cmd.arg(args_file_arg);
+            } else {
+                cmd.args(&objects).args(&self.objects);
+            }
+            run(&mut cmd, "lib.exe")?;
 
             // The Rust compiler will look for libfoo.a and foo.lib, but the
             // MSVC linker will also be passed foo.lib, so be sure that both
             // exist for now.
             let lib_dst = dst.with_file_name(format!("{}.lib", lib_name));
             let _ = fs::remove_file(&lib_dst);
             match fs::hard_link(&dst, &lib_dst).or_else(|_| {
                 // if hard-link fails, just copy (ignoring the number of bytes written)
@@ -1407,16 +1442,28 @@ impl Build {
                     ErrorKind::IOError,
                     "Unable to determine iOS SDK path.",
                 ))
             }
         };
 
         cmd.args.push("-isysroot".into());
         cmd.args.push(sdk_path.trim().into());
+        cmd.args.push("-fembed-bitcode".into());
+        /*
+         * TODO we probably ultimatedly want the -fembed-bitcode-marker flag
+         * but can't have it now because of an issue in LLVM:
+         * https://github.com/alexcrichton/cc-rs/issues/301
+         * https://github.com/rust-lang/rust/pull/48896#comment-372192660
+         */
+        /*
+        if self.get_opt_level()? == "0" {
+            cmd.args.push("-fembed-bitcode-marker".into());
+        }
+        */
 
         Ok(())
     }
 
     fn cmd<P: AsRef<OsStr>>(&self, prog: P) -> Command {
         let mut cmd = Command::new(prog);
         for &(ref a, ref b) in self.env.iter() {
             cmd.env(a, b);
@@ -1432,47 +1479,54 @@ impl Build {
         let target = self.get_target()?;
         let (env, msvc, gnu, traditional) = if self.cpp {
             ("CXX", "cl.exe", "g++", "c++")
         } else {
             ("CC", "cl.exe", "gcc", "cc")
         };
 
         // On Solaris, c++/cc unlikely to exist or be correct.
-        let default = if host.contains("solaris") { gnu } else { traditional };
+        let default = if host.contains("solaris") {
+            gnu
+        } else {
+            traditional
+        };
 
-        let tool_opt: Option<Tool> =
-            self.env_tool(env)
-                .map(|(tool, cc, args)| {
-                    let mut t = Tool::new(PathBuf::from(tool));
-                    if let Some(cc) = cc {
-                        t.cc_wrapper_path = Some(PathBuf::from(cc));
-                    }
-                    for arg in args {
-                        t.cc_wrapper_args.push(arg.into());
+        let tool_opt: Option<Tool> = self.env_tool(env)
+            .map(|(tool, cc, args)| {
+                // chop off leading/trailing whitespace to work around
+                // semi-buggy build scripts which are shared in
+                // makefiles/configure scripts (where spaces are far more
+                // lenient)
+                let mut t = Tool::new(PathBuf::from(tool.trim()));
+                if let Some(cc) = cc {
+                    t.cc_wrapper_path = Some(PathBuf::from(cc));
+                }
+                for arg in args {
+                    t.cc_wrapper_args.push(arg.into());
+                }
+                t
+            })
+            .or_else(|| {
+                if target.contains("emscripten") {
+                    let tool = if self.cpp { "em++" } else { "emcc" };
+                    // Windows uses bat file so we have to be a bit more specific
+                    if cfg!(windows) {
+                        let mut t = Tool::new(PathBuf::from("cmd"));
+                        t.args.push("/c".into());
+                        t.args.push(format!("{}.bat", tool).into());
+                        Some(t)
+                    } else {
+                        Some(Tool::new(PathBuf::from(tool)))
                     }
-                    t
-                })
-                .or_else(|| {
-                    if target.contains("emscripten") {
-                        let tool = if self.cpp { "em++" } else { "emcc" };
-                        // Windows uses bat file so we have to be a bit more specific
-                        if cfg!(windows) {
-                            let mut t = Tool::new(PathBuf::from("cmd"));
-                            t.args.push("/c".into());
-                            t.args.push(format!("{}.bat", tool).into());
-                            Some(t)
-                        } else {
-                            Some(Tool::new(PathBuf::from(tool)))
-                        }
-                    } else {
-                        None
-                    }
-                })
-                .or_else(|| windows_registry::find_tool(&target, "cl.exe"));
+                } else {
+                    None
+                }
+            })
+            .or_else(|| windows_registry::find_tool(&target, "cl.exe"));
 
         let tool = match tool_opt {
             Some(t) => t,
             None => {
                 let compiler = if host.contains("windows") && target.contains("windows") {
                     if target.contains("msvc") {
                         msvc.to_string()
                     } else {
@@ -1496,28 +1550,31 @@ impl Build {
                         "arm-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                         "arm-unknown-linux-musleabi" => Some("arm-linux-musleabi"),
                         "arm-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
                         "arm-unknown-netbsd-eabi" => Some("arm--netbsdelf-eabi"),
                         "armv6-unknown-netbsd-eabihf" => Some("armv6--netbsdelf-eabihf"),
                         "armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
                         "armv7-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"),
                         "i686-unknown-linux-musl" => Some("musl"),
                         "i686-unknown-netbsd" => Some("i486--netbsdelf"),
                         "mips-unknown-linux-gnu" => Some("mips-linux-gnu"),
                         "mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"),
                         "mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"),
                         "mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"),
                         "powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
+                        "powerpc-unknown-linux-gnuspe" => Some("powerpc-linux-gnuspe"),
                         "powerpc-unknown-netbsd" => Some("powerpc--netbsd"),
                         "powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
                         "powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"),
                         "s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"),
+                        "sparc-unknown-linux-gnu" => Some("sparc-linux-gnu"),
                         "sparc64-unknown-linux-gnu" => Some("sparc64-linux-gnu"),
                         "sparc64-unknown-netbsd" => Some("sparc64--netbsd"),
                         "sparcv9-sun-solaris" => Some("sparcv9-sun-solaris"),
                         "thumbv6m-none-eabi" => Some("arm-none-eabi"),
                         "thumbv7em-none-eabi" => Some("arm-none-eabi"),
                         "thumbv7em-none-eabihf" => Some("arm-none-eabi"),
                         "thumbv7m-none-eabi" => Some("arm-none-eabi"),
                         "x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"),
@@ -1533,24 +1590,28 @@ impl Build {
                 } else {
                     default.to_string()
                 };
                 Tool::new(PathBuf::from(compiler))
             }
         };
 
         let tool = if self.cuda {
-            assert!(tool.args.is_empty(),
-                "CUDA compilation currently assumes empty pre-existing args");
+            assert!(
+                tool.args.is_empty(),
+                "CUDA compilation currently assumes empty pre-existing args"
+            );
             let nvcc = match self.get_var("NVCC") {
                 Err(_) => "nvcc".into(),
                 Ok(nvcc) => nvcc,
             };
             let mut nvcc_tool = Tool::with_features(PathBuf::from(nvcc), self.cuda);
-            nvcc_tool.args.push(format!("-ccbin={}", tool.path.display()).into());
+            nvcc_tool
+                .args
+                .push(format!("-ccbin={}", tool.path.display()).into());
             nvcc_tool
         } else {
             tool
         };
 
         Ok(tool)
     }
 
@@ -1563,60 +1624,104 @@ impl Build {
             .or_else(|| self.getenv(&format!("{}_{}", var_base, target_u)))
             .or_else(|| self.getenv(&format!("{}_{}", kind, var_base)))
             .or_else(|| self.getenv(var_base));
 
         match res {
             Some(res) => Ok(res),
             None => Err(Error::new(
                 ErrorKind::EnvVarNotFound,
-                &format!(
-                    "Could not find environment variable {}.",
-                    var_base
-                ),
+                &format!("Could not find environment variable {}.", var_base),
             )),
         }
     }
 
     fn envflags(&self, name: &str) -> Vec<String> {
         self.get_var(name)
             .unwrap_or(String::new())
             .split(|c: char| c.is_whitespace())
             .filter(|s| !s.is_empty())
             .map(|s| s.to_string())
             .collect()
     }
 
-
     /// Returns compiler path, optional modifier name from whitelist, and arguments vec
     fn env_tool(&self, name: &str) -> Option<(String, Option<String>, Vec<String>)> {
-        self.get_var(name).ok().map(|tool| {
-            let whitelist = ["ccache", "distcc", "sccache"];
+        let tool = match self.get_var(name) {
+            Ok(tool) => tool,
+            Err(_) => return None,
+        };
+
+        // If this is an exact path on the filesystem we don't want to do any
+        // interpretation at all, just pass it on through. This'll hopefully get
+        // us to support spaces-in-paths.
+        if Path::new(&tool).exists() {
+            return Some((tool, None, Vec::new()));
+        }
 
-            for t in whitelist.iter() {
-                if tool.starts_with(t) && tool[t.len()..].starts_with(' ')  {
-                    let args = tool.split_whitespace().collect::<Vec<_>>();
+        // Ok now we want to handle a couple of scenarios. We'll assume from
+        // here on out that spaces are splitting separate arguments. Two major
+        // features we want to support are:
+        //
+        //      CC='sccache cc'
+        //
+        // aka using `sccache` or any other wrapper/caching-like-thing for
+        // compilations. We want to know what the actual compiler is still,
+        // though, because our `Tool` API support introspection of it to see
+        // what compiler is in use.
+        //
+        // additionally we want to support
+        //
+        //      CC='cc -flag'
+        //
+        // where the CC env var is used to also pass default flags to the C
+        // compiler.
+        //
+        // It's true that everything here is a bit of a pain, but apparently if
+        // you're not literally make or bash then you get a lot of bug reports.
+        let known_wrappers = ["ccache", "distcc", "sccache", "icecc"];
 
-                    return (args[1].to_string(), Some(t.to_string()), args[2..].iter().map(|s| s.to_string()).collect());
-                }
+        let mut parts = tool.split_whitespace();
+        let maybe_wrapper = match parts.next() {
+            Some(s) => s,
+            None => return None,
+        };
+
+        let file_stem = Path::new(maybe_wrapper)
+            .file_stem()
+            .unwrap()
+            .to_str()
+            .unwrap();
+        if known_wrappers.contains(&file_stem) {
+            if let Some(compiler) = parts.next() {
+                return Some((
+                    compiler.to_string(),
+                    Some(maybe_wrapper.to_string()),
+                    parts.map(|s| s.to_string()).collect(),
+                ));
             }
-            (tool, None, Vec::new())
-        })
+        }
+
+        Some((
+            maybe_wrapper.to_string(),
+            None,
+            parts.map(|s| s.to_string()).collect(),
+        ))
     }
 
     /// Returns the default C++ standard library for the current target: `libc++`
     /// for OS X and `libstdc++` for anything else.
     fn get_cpp_link_stdlib(&self) -> Result<Option<String>, Error> {
         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("darwin") {
+                } 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()))
                 }
@@ -1695,20 +1800,17 @@ impl Build {
         r
     }
 
     fn getenv_unwrap(&self, v: &str) -> Result<String, Error> {
         match self.getenv(v) {
             Some(s) => Ok(s),
             None => Err(Error::new(
                 ErrorKind::EnvVarNotFound,
-                &format!(
-                    "Environment variable {} not defined.",
-                    v.to_string()
-                ),
+                &format!("Environment variable {} not defined.", v.to_string()),
             )),
         }
     }
 
     fn print(&self, s: &str) {
         if self.cargo_metadata {
             println!("{}", s);
         }
@@ -1726,18 +1828,19 @@ impl Tool {
         Tool::with_features(path, false)
     }
 
     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") {
                 ToolFamily::Clang
-            } else if fname.contains("cl") && !fname.contains("cloudabi") &&
-                      !fname.contains("uclibc") {
+            } else if fname.contains("cl") && !fname.contains("cloudabi")
+                && !fname.contains("uclibc")
+            {
                 ToolFamily::Msvc
             } else {
                 ToolFamily::Gnu
             }
         } else {
             ToolFamily::Gnu
         };
         Tool {
@@ -1770,18 +1873,18 @@ impl Tool {
     /// variables configured.
     pub fn to_command(&self) -> Command {
         let mut cmd = match self.cc_wrapper_path {
             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)
+            }
+            None => Command::new(&self.path),
         };
         cmd.args(&self.args);
         for &(ref k, ref v) in self.env.iter() {
             cmd.env(k, v);
         }
         cmd
     }
 
@@ -1817,20 +1920,18 @@ impl Tool {
                 let mut cc_env = cc_wrapper_path.as_os_str().to_owned();
                 cc_env.push(" ");
                 cc_env.push(self.path.to_path_buf().into_os_string());
                 for arg in self.cc_wrapper_args.iter() {
                     cc_env.push(" ");
                     cc_env.push(arg);
                 }
                 cc_env
-            },
-            None => {
-                OsString::from("")
             }
+            None => OsString::from(""),
         }
     }
 
     /// Returns the compiler flags in format of CFLAGS environment variable.
     /// Important here - this will not be CFLAGS from env, its internal gcc's flags to use as CFLAGS
     /// This is typically used by configure script
     pub fn cflags_env(&self) -> OsString {
         let mut flags = OsString::new();
@@ -1863,35 +1964,32 @@ fn run(cmd: &mut Command, program: &str)
     let (mut child, print) = spawn(cmd, program)?;
     let status = match child.wait() {
         Ok(s) => s,
         Err(_) => {
             return Err(Error::new(
                 ErrorKind::ToolExecError,
                 &format!(
                     "Failed to wait on spawned child process, command {:?} with args {:?}.",
-                    cmd,
-                    program
+                    cmd, program
                 ),
             ))
         }
     };
     print.join().unwrap();
     println!("{}", status);
 
     if status.success() {
         Ok(())
     } else {
         Err(Error::new(
             ErrorKind::ToolExecError,
             &format!(
                 "Command {:?} with args {:?} did not execute successfully (status code {}).",
-                cmd,
-                program,
-                status
+                cmd, program, status
             ),
         ))
     }
 }
 
 fn run_output(cmd: &mut Command, program: &str) -> Result<Vec<u8>, Error> {
     cmd.stdout(Stdio::piped());
     let (mut child, print) = spawn(cmd, program)?;
@@ -1904,94 +2002,83 @@ fn run_output(cmd: &mut Command, program
         .unwrap();
     let status = match child.wait() {
         Ok(s) => s,
         Err(_) => {
             return Err(Error::new(
                 ErrorKind::ToolExecError,
                 &format!(
                     "Failed to wait on spawned child process, command {:?} with args {:?}.",
-                    cmd,
-                    program
+                    cmd, program
                 ),
             ))
         }
     };
     print.join().unwrap();
     println!("{}", status);
 
     if status.success() {
         Ok(stdout)
     } else {
         Err(Error::new(
             ErrorKind::ToolExecError,
             &format!(
                 "Command {:?} with args {:?} did not execute successfully (status code {}).",
-                cmd,
-                program,
-                status
+                cmd, program, status
             ),
         ))
     }
 }
 
 fn spawn(cmd: &mut Command, program: &str) -> Result<(Child, JoinHandle<()>), Error> {
     println!("running: {:?}", cmd);
 
     // Capture the standard error coming from these programs, and write it out
     // with cargo:warning= prefixes. Note that this is a bit wonky to avoid
     // requiring the output to be UTF-8, we instead just ship bytes from one
     // location to another.
     match cmd.stderr(Stdio::piped()).spawn() {
         Ok(mut child) => {
             let stderr = BufReader::new(child.stderr.take().unwrap());
-            let print = thread::spawn(move || for line in stderr.split(b'\n').filter_map(
-                |l| l.ok(),
-            )
-            {
-                print!("cargo:warning=");
-                std::io::stdout().write_all(&line).unwrap();
-                println!("");
+            let print = thread::spawn(move || {
+                for line in stderr.split(b'\n').filter_map(|l| l.ok()) {
+                    print!("cargo:warning=");
+                    std::io::stdout().write_all(&line).unwrap();
+                    println!("");
+                }
             });
             Ok((child, print))
         }
         Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
             let extra = if cfg!(windows) {
                 " (see https://github.com/alexcrichton/cc-rs#compile-time-requirements \
-                   for help)"
+                 for help)"
             } else {
                 ""
             };
             Err(Error::new(
                 ErrorKind::ToolNotFound,
-                &format!(
-                    "Failed to find tool. Is `{}` installed?{}",
-                    program,
-                    extra
-                ),
+                &format!("Failed to find tool. Is `{}` installed?{}", program, extra),
             ))
         }
         Err(_) => Err(Error::new(
             ErrorKind::ToolExecError,
-            &format!(
-                "Command {:?} with args {:?} failed to start.",
-                cmd,
-                program
-            ),
+            &format!("Command {:?} with args {:?} failed to start.", cmd, program),
         )),
     }
 }
 
 fn fail(s: &str) -> ! {
     panic!("\n\nInternal error occurred: {}\n\n", s)
 }
 
-
-fn command_add_output_file(cmd: &mut Command, dst: &Path, msvc: bool, is_asm: bool) {
-    if msvc && is_asm {
+fn command_add_output_file(cmd: &mut Command, dst: &Path, msvc: bool, is_asm: bool, is_arm: bool) {
+    if msvc && is_asm && is_arm {
+        cmd.arg("-o").arg(&dst);
+    } else if msvc && is_asm {
         cmd.arg("/Fo").arg(dst);
     } else if msvc {
         let mut s = OsString::from("/Fo");
         s.push(&dst);
         cmd.arg(s);
     } else {
         cmd.arg("-o").arg(&dst);
     }
--- a/third_party/rust/cc/src/registry.rs
+++ b/third_party/rust/cc/src/registry.rs
@@ -3,17 +3,17 @@
 // 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::ffi::{OsString, OsStr};
+use std::ffi::{OsStr, OsString};
 use std::io;
 use std::ops::RangeFrom;
 use std::os::raw;
 use std::os::windows::prelude::*;
 
 pub struct RegistryKey(Repr);
 
 type HKEY = *mut u8;
@@ -31,38 +31,41 @@ const ERROR_SUCCESS: DWORD = 0;
 const ERROR_NO_MORE_ITEMS: DWORD = 259;
 const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
 const REG_SZ: DWORD = 1;
 const KEY_READ: DWORD = 0x20019;
 const KEY_WOW64_32KEY: DWORD = 0x200;
 
 #[link(name = "advapi32")]
 extern "system" {
-    fn RegOpenKeyExW(key: HKEY,
-                     lpSubKey: LPCWSTR,
-                     ulOptions: DWORD,
-                     samDesired: REGSAM,
-                     phkResult: PHKEY)
-                     -> LONG;
-    fn RegEnumKeyExW(key: HKEY,
-                     dwIndex: DWORD,
-                     lpName: LPWSTR,
-                     lpcName: LPDWORD,
-                     lpReserved: LPDWORD,
-                     lpClass: LPWSTR,
-                     lpcClass: LPDWORD,
-                     lpftLastWriteTime: PFILETIME)
-                     -> LONG;
-    fn RegQueryValueExW(hKey: HKEY,
-                        lpValueName: LPCWSTR,
-                        lpReserved: LPDWORD,
-                        lpType: LPDWORD,
-                        lpData: LPBYTE,
-                        lpcbData: LPDWORD)
-                        -> LONG;
+    fn RegOpenKeyExW(
+        key: HKEY,
+        lpSubKey: LPCWSTR,
+        ulOptions: DWORD,
+        samDesired: REGSAM,
+        phkResult: PHKEY,
+    ) -> LONG;
+    fn RegEnumKeyExW(
+        key: HKEY,
+        dwIndex: DWORD,
+        lpName: LPWSTR,
+        lpcName: LPDWORD,
+        lpReserved: LPDWORD,
+        lpClass: LPWSTR,
+        lpcClass: LPDWORD,
+        lpftLastWriteTime: PFILETIME,
+    ) -> LONG;
+    fn RegQueryValueExW(
+        hKey: HKEY,
+        lpValueName: LPCWSTR,
+        lpReserved: LPDWORD,
+        lpType: LPDWORD,
+        lpData: LPBYTE,
+        lpcbData: LPDWORD,
+    ) -> LONG;
     fn RegCloseKey(hKey: HKEY) -> LONG;
 }
 
 struct OwnedKey(HKEY);
 
 enum Repr {
     Const(HKEY),
     Owned(OwnedKey),
@@ -85,21 +88,23 @@ impl RegistryKey {
             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 = 0 as *mut _;
         let err = unsafe {
-            RegOpenKeyExW(self.raw(),
-                          key.as_ptr(),
-                          0,
-                          KEY_READ | KEY_WOW64_32KEY,
-                          &mut ret)
+            RegOpenKeyExW(
+                self.raw(),
+                key.as_ptr(),
+                0,
+                KEY_READ | KEY_WOW64_32KEY,
+                &mut ret,
+            )
         };
         if err == ERROR_SUCCESS as LONG {
             Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
         } else {
             Err(io::Error::from_raw_os_error(err as i32))
         }
     }
 
@@ -111,39 +116,46 @@ impl RegistryKey {
     }
 
     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(),
-                                       0 as *mut _,
-                                       &mut kind,
-                                       0 as *mut _,
-                                       &mut len);
+            let err = RegQueryValueExW(
+                self.raw(),
+                name.as_ptr(),
+                0 as *mut _,
+                &mut kind,
+                0 as *mut _,
+                &mut len,
+            );
             if err != ERROR_SUCCESS as LONG {
                 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"));
+                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(),
-                                       0 as *mut _,
-                                       0 as *mut _,
-                                       v.as_mut_ptr() as *mut _,
-                                       &mut len);
+            let err = RegQueryValueExW(
+                self.raw(),
+                name.as_ptr(),
+                0 as *mut _,
+                0 as *mut _,
+                v.as_mut_ptr() as *mut _,
+                &mut len,
+            );
             if err != ERROR_SUCCESS as LONG {
                 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 {
@@ -164,24 +176,26 @@ impl Drop for OwnedKey {
 
 impl<'a> Iterator for Iter<'a> {
     type Item = io::Result<OsString>;
 
     fn next(&mut self) -> Option<io::Result<OsString>> {
         self.idx.next().and_then(|i| unsafe {
             let mut v = Vec::with_capacity(256);
             let mut len = v.capacity() as DWORD;
-            let ret = RegEnumKeyExW(self.key.raw(),
-                                    i,
-                                    v.as_mut_ptr(),
-                                    &mut len,
-                                    0 as *mut _,
-                                    0 as *mut _,
-                                    0 as *mut _,
-                                    0 as *mut _);
+            let ret = RegEnumKeyExW(
+                self.key.raw(),
+                i,
+                v.as_mut_ptr(),
+                &mut len,
+                0 as *mut _,
+                0 as *mut _,
+                0 as *mut _,
+                0 as *mut _,
+            );
             if ret == ERROR_NO_MORE_ITEMS as LONG {
                 None
             } else if ret != ERROR_SUCCESS as LONG {
                 Some(Err(io::Error::from_raw_os_error(ret as i32)))
             } else {
                 v.set_len(len as usize);
                 Some(Ok(OsString::from_wide(&v)))
             }
--- a/third_party/rust/cc/src/setup_config.rs
+++ b/third_party/rust/cc/src/setup_config.rs
@@ -10,17 +10,17 @@
 
 use std::ffi::OsString;
 use std::ptr::null_mut;
 use winapi::Interface;
 use winapi::{LPFILETIME, ULONG};
 use winapi::S_FALSE;
 use winapi::BSTR;
 use winapi::LPCOLESTR;
-use winapi::{CLSCTX_ALL, CoCreateInstance};
+use winapi::{CoCreateInstance, CLSCTX_ALL};
 use winapi::LPSAFEARRAY;
 use winapi::{IUnknown, IUnknownVtbl};
 use winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG};
 
 use com::{BStr, ComPtr};
 
 // Bindings to the Setup.Configuration stuff
 pub type InstanceState = u32;
@@ -150,93 +150,116 @@ interface ISetupHelper(ISetupHelperVtbl)
     fn ParseVersionRange(
         pwszVersionRange: LPCOLESTR,
         pullMinVersion: PULONGLONG,
         pullMaxVersion: PULONGLONG,
     ) -> HRESULT,
 }}
 
 DEFINE_GUID!{CLSID_SetupConfiguration,
-    0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d}
+0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d}
 
 // Safe wrapper around the COM interfaces
 pub struct SetupConfiguration(ComPtr<ISetupConfiguration>);
 
 impl SetupConfiguration {
     pub fn new() -> Result<SetupConfiguration, i32> {
         let mut obj = null_mut();
-        let err = unsafe { CoCreateInstance(
-            &CLSID_SetupConfiguration, null_mut(), CLSCTX_ALL,
-            &ISetupConfiguration::uuidof(), &mut obj,
-        ) };
-        if err < 0 { return Err(err); }
+        let err = unsafe {
+            CoCreateInstance(
+                &CLSID_SetupConfiguration,
+                null_mut(),
+                CLSCTX_ALL,
+                &ISetupConfiguration::uuidof(),
+                &mut obj,
+            )
+        };
+        if err < 0 {
+            return Err(err);
+        }
         let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) };
         Ok(SetupConfiguration(obj))
     }
     pub fn get_instance_for_current_process(&self) -> Result<SetupInstance, i32> {
         let mut obj = null_mut();
         let err = unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(unsafe { SetupInstance::from_raw(obj) })
     }
     pub fn enum_instances(&self) -> Result<EnumSetupInstances, i32> {
         let mut obj = null_mut();
         let err = unsafe { self.0.EnumInstances(&mut obj) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(unsafe { EnumSetupInstances::from_raw(obj) })
     }
     pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> {
         let mut obj = null_mut();
         let this = try!(self.0.cast::<ISetupConfiguration2>());
         let err = unsafe { this.EnumAllInstances(&mut obj) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(unsafe { EnumSetupInstances::from_raw(obj) })
     }
 }
 
 pub struct SetupInstance(ComPtr<ISetupInstance>);
 
 impl SetupInstance {
     pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance {
         SetupInstance(ComPtr::from_raw(obj))
     }
     pub fn instance_id(&self) -> Result<OsString, i32> {
         let mut s = null_mut();
         let err = unsafe { self.0.GetInstanceId(&mut s) };
         let bstr = unsafe { BStr::from_raw(s) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(bstr.to_osstring())
     }
     pub fn installation_name(&self) -> Result<OsString, i32> {
         let mut s = null_mut();
         let err = unsafe { self.0.GetInstallationName(&mut s) };
         let bstr = unsafe { BStr::from_raw(s) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(bstr.to_osstring())
     }
     pub fn installation_path(&self) -> Result<OsString, i32> {
         let mut s = null_mut();
         let err = unsafe { self.0.GetInstallationPath(&mut s) };
         let bstr = unsafe { BStr::from_raw(s) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(bstr.to_osstring())
     }
     pub fn installation_version(&self) -> Result<OsString, i32> {
         let mut s = null_mut();
         let err = unsafe { self.0.GetInstallationVersion(&mut s) };
         let bstr = unsafe { BStr::from_raw(s) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(bstr.to_osstring())
     }
     pub fn product_path(&self) -> Result<OsString, i32> {
         let mut s = null_mut();
         let this = try!(self.0.cast::<ISetupInstance2>());
         let err = unsafe { this.GetProductPath(&mut s) };
         let bstr = unsafe { BStr::from_raw(s) };
-        if err < 0 { return Err(err); }
+        if err < 0 {
+            return Err(err);
+        }
         Ok(bstr.to_osstring())
     }
 }
 
 pub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>);
 
 impl EnumSetupInstances {
     pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances {
@@ -244,14 +267,17 @@ impl EnumSetupInstances {
     }
 }
 
 impl Iterator for EnumSetupInstances {
     type Item = Result<SetupInstance, i32>;
     fn next(&mut self) -> Option<Result<SetupInstance, i32>> {
         let mut obj = null_mut();
         let err = unsafe { self.0.Next(1, &mut obj, null_mut()) };
-        if err < 0 { return Some(Err(err)); }
-        if err == S_FALSE { return None; }
+        if err < 0 {
+            return Some(Err(err));
+        }
+        if err == S_FALSE {
+            return None;
+        }
         Some(Ok(unsafe { SetupInstance::from_raw(obj) }))
     }
 }
-
--- a/third_party/rust/cc/src/winapi.rs
+++ b/third_party/rust/cc/src/winapi.rs
@@ -39,18 +39,18 @@ pub const COINIT_MULTITHREADED: u32 = 0x
 
 pub type CLSCTX = u32;
 
 pub const CLSCTX_INPROC_SERVER: CLSCTX = 0x1;
 pub const CLSCTX_INPROC_HANDLER: CLSCTX = 0x2;
 pub const CLSCTX_LOCAL_SERVER: CLSCTX = 0x4;
 pub const CLSCTX_REMOTE_SERVER: CLSCTX = 0x10;
 
-pub const CLSCTX_ALL: CLSCTX = CLSCTX_INPROC_SERVER |
-    CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER;
+pub const CLSCTX_ALL: CLSCTX =
+    CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER;
 
 #[repr(C)]
 #[derive(Copy, Clone)]
 pub struct GUID {
     pub Data1: raw::c_ulong,
     pub Data2: raw::c_ushort,
     pub Data3: raw::c_ushort,
     pub Data4: [raw::c_uchar; 8],
@@ -64,23 +64,27 @@ pub struct FILETIME {
 }
 
 pub trait Interface {
     fn uuidof() -> GUID;
 }
 
 #[link(name = "ole32")]
 #[link(name = "oleaut32")]
-extern { }
+extern "C" {}
 
 extern "system" {
     pub fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) -> HRESULT;
-    pub fn CoCreateInstance(rclsid: REFCLSID, pUnkOuter: LPUNKNOWN,
-                            dwClsContext: DWORD, riid: REFIID,
-                            ppv: *mut LPVOID) -> HRESULT;
+    pub fn CoCreateInstance(
+        rclsid: REFCLSID,
+        pUnkOuter: LPUNKNOWN,
+        dwClsContext: DWORD,
+        riid: REFIID,
+        ppv: *mut LPVOID,
+    ) -> HRESULT;
     pub fn SysFreeString(bstrString: BSTR);
     pub fn SysStringLen(pbstr: BSTR) -> UINT;
 }
 
 #[repr(C)]
 #[derive(Copy, Clone)]
 pub struct SAFEARRAYBOUND {
     pub cElements: ULONG,
--- a/third_party/rust/cc/src/windows_registry.rs
+++ b/third_party/rust/cc/src/windows_registry.rs
@@ -64,17 +64,21 @@ pub fn find_tool(target: &str, tool: &st
     if tool.contains("msbuild") {
         return impl_::find_msbuild(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() {
         return env::var_os("PATH")
-            .and_then(|path| env::split_paths(&path).map(|p| p.join(tool)).find(|p| p.exists()))
+            .and_then(|path| {
+                env::split_paths(&path)
+                    .map(|p| p.join(tool))
+                    .find(|p| p.exists())
+            })
             .map(|path| Tool::new(path.into()));
     }
 
     // Ok, if we're here, now comes the fun part of the probing. Default shells
     // or shells like MSYS aren't really configured to execute `cl.exe` and the
     // various compiler tools shipped as part of Visual Studio. Here we try to
     // first find the relevant tool, then we also have to be sure to fill in
     // environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that
@@ -114,45 +118,48 @@ pub fn find_vs_version() -> Result<VsVer
 }
 
 /// Documented above
 #[cfg(windows)]
 pub fn find_vs_version() -> Result<VsVers, String> {
     use std::env;
 
     match env::var("VisualStudioVersion") {
-        Ok(version) => {
-            match &version[..] {
-                "15.0" => Ok(VsVers::Vs15),
-                "14.0" => Ok(VsVers::Vs14),
-                "12.0" => Ok(VsVers::Vs12),
-                vers => Err(format!("\n\n\
-                                     unsupported or unknown VisualStudio version: {}\n\
-                                     if another version is installed consider running \
-                                     the appropriate vcvars script before building this \
-                                     crate\n\
-                                     ", vers)),
-            }
-        }
+        Ok(version) => match &version[..] {
+            "15.0" => Ok(VsVers::Vs15),
+            "14.0" => Ok(VsVers::Vs14),
+            "12.0" => Ok(VsVers::Vs12),
+            vers => Err(format!(
+                "\n\n\
+                 unsupported or unknown VisualStudio version: {}\n\
+                 if another version is installed consider running \
+                 the appropriate vcvars script before building this \
+                 crate\n\
+                 ",
+                vers
+            )),
+        },
         _ => {
             // Check for the presense of a specific registry key
             // that indicates visual studio is installed.
             if impl_::has_msbuild_version("15.0") {
                 Ok(VsVers::Vs15)
             } else if impl_::has_msbuild_version("14.0") {
                 Ok(VsVers::Vs14)
             } else if impl_::has_msbuild_version("12.0") {
                 Ok(VsVers::Vs12)
             } else {
-                Err(format!("\n\n\
-                             couldn't determine visual studio generator\n\
-                             if VisualStudio is installed, however, consider \
-                             running the appropriate vcvars script before building \
-                             this crate\n\
-                             "))
+                Err(format!(
+                    "\n\n\
+                     couldn't determine visual studio generator\n\
+                     if VisualStudio is installed, however, consider \
+                     running the appropriate vcvars script before building \
+                     this crate\n\
+                     "
+                ))
             }
         }
     }
 }
 
 #[cfg(windows)]
 mod impl_ {
     use std::env;
@@ -180,17 +187,22 @@ mod impl_ {
                 tool: tool,
                 libs: Vec::new(),
                 path: Vec::new(),
                 include: Vec::new(),
             }
         }
 
         fn into_tool(self) -> Tool {
-            let MsvcTool { tool, libs, path, include } = self;
+            let MsvcTool {
+                tool,
+                libs,
+                path,
+                include,
+            } = self;
             let mut tool = Tool::new(tool.into());
             add_env(&mut tool, "LIB", libs);
             add_env(&mut tool, "PATH", path);
             add_env(&mut tool, "INCLUDE", include);
             tool
         }
     }
 
@@ -212,59 +224,69 @@ mod impl_ {
             if tool.is_some() {
                 return tool;
             }
         }
 
         None
     }
 
-    fn tool_from_vs15_instance(tool: &str, target: &str,
-                               instance: &SetupInstance) -> Option<Tool> {
-        let (bin_path, host_dylib_path, lib_path, include_path) = otry!(vs15_vc_paths(target, instance));
+    fn tool_from_vs15_instance(tool: &str, target: &str, instance: &SetupInstance) -> Option<Tool> {
+        let (bin_path, host_dylib_path, lib_path, include_path) =
+            otry!(vs15_vc_paths(target, instance));
         let tool_path = bin_path.join(tool);
-        if !tool_path.exists() { return None };
+        if !tool_path.exists() {
+            return None;
+        };
 
         let mut tool = MsvcTool::new(tool_path);
         tool.path.push(host_dylib_path);
         tool.libs.push(lib_path);
         tool.include.push(include_path);
 
         if let Some((atl_lib_path, atl_include_path)) = atl_paths(target, &bin_path) {
             tool.libs.push(atl_lib_path);
             tool.include.push(atl_include_path);
         }
 
         otry!(add_sdks(&mut tool, target));
 
         Some(tool.into_tool())
     }
 
-    fn vs15_vc_paths(target: &str, instance: &SetupInstance) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> {
+    fn vs15_vc_paths(
+        target: &str,
+        instance: &SetupInstance,
+    ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> {
         let instance_path: PathBuf = otry!(instance.installation_path().ok()).into();
-        let version_path = instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt");
+        let version_path =
+            instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt");
         let mut version_file = otry!(File::open(version_path).ok());
         let mut version = String::new();
         otry!(version_file.read_to_string(&mut version).ok());
         let version = version.trim();
         let host = match host_arch() {
             X86 => "X86",
             X86_64 => "X64",
             _ => return None,
         };
         let target = otry!(lib_subdir(target));
         // The directory layout here is MSVC/bin/Host$host/$target/
         let path = instance_path.join(r"VC\Tools\MSVC").join(version);
         // This is the path to the toolchain for a particular target, running
         // on a given host
-        let bin_path = path.join("bin").join(&format!("Host{}", host)).join(&target);
+        let bin_path = path.join("bin")
+            .join(&format!("Host{}", host))
+            .join(&target);
         // But! we also need PATH to contain the target directory for the host
         // architecture, because it contains dlls like mspdb140.dll compiled for
         // the host architecture.
-        let host_dylib_path = path.join("bin").join(&format!("Host{}", host)).join(&host.to_lowercase());
+        let host_dylib_path = path.join("bin")
+            .join(&format!("Host{}", host))
+            .join(&host.to_lowercase());
         let lib_path = path.join("lib").join(&target);
         let include_path = path.join("include");
         Some((bin_path, host_dylib_path, lib_path, include_path))
     }
 
     fn atl_paths(target: &str, path: &Path) -> Option<(PathBuf, PathBuf)> {
         let atl_path = path.join("atlfmc");
         let sub = otry!(lib_subdir(target));
@@ -283,17 +305,18 @@ mod impl_ {
         otry!(add_sdks(&mut tool, target));
         Some(tool.into_tool())
     }
 
     fn add_sdks(tool: &mut MsvcTool, target: &str) -> Option<()> {
         let sub = otry!(lib_subdir(target));
         let (ucrt, ucrt_version) = otry!(get_ucrt_dir());
 
-        tool.path.push(ucrt.join("bin").join(&ucrt_version).join(sub));
+        tool.path
+            .push(ucrt.join("bin").join(&ucrt_version).join(sub));
 
         let ucrt_include = ucrt.join("include").join(&ucrt_version);
         tool.include.push(ucrt_include.join("ucrt"));
 
         let ucrt_lib = ucrt.join("lib").join(&ucrt_version);
         tool.libs.push(ucrt_lib.join("ucrt").join(sub));
 
         if let Some((sdk, version)) = get_sdk10_dir() {
@@ -348,25 +371,31 @@ mod impl_ {
         tool.include.push(sdk_include.join("winrt"));
         Some(tool.into_tool())
     }
 
     fn add_env(tool: &mut Tool, env: &str, paths: Vec<PathBuf>) {
         let prev = env::var_os(env).unwrap_or(OsString::new());
         let prev = env::split_paths(&prev);
         let new = paths.into_iter().chain(prev);
-        tool.env.push((env.to_string().into(), env::join_paths(new).unwrap()));
+        tool.env
+            .push((env.to_string().into(), env::join_paths(new).unwrap()));
     }
 
     // Given a possible MSVC installation directory, we look for the linker and
     // then add the MSVC library path.
     fn get_tool(tool: &str, path: &Path, target: &str) -> Option<MsvcTool> {
         bin_subdir(target)
             .into_iter()
-            .map(|(sub, host)| (path.join("bin").join(sub).join(tool), path.join("bin").join(host)))
+            .map(|(sub, host)| {
+                (
+                    path.join("bin").join(sub).join(tool),
+                    path.join("bin").join(host),
+                )
+            })
             .filter(|&(ref path, _)| path.is_file())
             .map(|(path, host)| {
                 let mut tool = MsvcTool::new(path);
                 tool.path.push(host);
                 tool
             })
             .filter_map(|mut tool| {
                 let sub = otry!(vc_lib_subdir(target));
@@ -397,26 +426,27 @@ mod impl_ {
     // what vcvars does so that's good enough for us.
     //
     // Returns a pair of (root, version) for the ucrt dir if found
     fn get_ucrt_dir() -> Option<(PathBuf, String)> {
         let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots";
         let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
         let root = otry!(key.query_str("KitsRoot10").ok());
         let readdir = otry!(Path::new(&root).join("lib").read_dir().ok());
-        let max_libdir = otry!(readdir.filter_map(|dir| dir.ok())
-            .map(|dir| dir.path())
-            .filter(|dir| {
-                dir.components()
+        let max_libdir = otry!(
+            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());
+                    .unwrap_or(false))
+                .max()
+        );
         let version = max_libdir.components().last().unwrap();
         let version = version.as_os_str().to_str().unwrap().to_string();
         Some((root.into(), version))
     }
 
     // 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
@@ -425,24 +455,27 @@ mod impl_ {
     // 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, String)> {
         let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0";
         let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
         let root = otry!(key.query_str("InstallationFolder").ok());
         let readdir = otry!(Path::new(&root).join("lib").read_dir().ok());
-        let mut dirs = readdir.filter_map(|dir| dir.ok())
+        let mut dirs = readdir
+            .filter_map(|dir| dir.ok())
             .map(|dir| dir.path())
             .collect::<Vec<_>>();
         dirs.sort();
-        let dir = otry!(dirs.into_iter()
-            .rev()
-            .filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file())
-            .next());
+        let dir = otry!(
+            dirs.into_iter()
+                .rev()
+                .filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file())
+                .next()
+        );
         let version = dir.components().last().unwrap();
         let version = version.as_os_str().to_str().unwrap().to_string();
         Some((root.into(), version))
     }
 
     // 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
@@ -492,27 +525,29 @@ mod impl_ {
     }
 
     fn lib_subdir(target: &str) -> Option<&'static str> {
         let arch = target.split('-').next().unwrap();
         match arch {
             "i586" | "i686" => Some("x86"),
             "x86_64" => Some("x64"),
             "arm" => Some("arm"),
+            "aarch64" => Some("arm64"),
             _ => None,
         }
     }
 
     // MSVC's x86 libraries are not in a subfolder
     fn vc_lib_subdir(target: &str) -> Option<&'static str> {
         let arch = target.split('-').next().unwrap();
         match arch {
             "i586" | "i686" => Some(""),
             "x86_64" => Some("amd64"),
             "arm" => Some("arm"),
+            "aarch64" => Some("arm64"),
             _ => None,
         }
     }
 
     #[allow(bad_style)]
     fn host_arch() -> u16 {
         type DWORD = u32;
         type WORD = u16;
@@ -548,17 +583,18 @@ mod impl_ {
     // Given a registry key, look at all the sub keys and find the one which has
     // the maximal numeric value.
     //
     // Returns the name of the maximal key as well as the opened maximal key.
     fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> {
         let mut max_vers = 0;
         let mut max_key = None;
         for subkey in key.iter().filter_map(|k| k.ok()) {
-            let val = subkey.to_str()
+            let val = subkey
+                .to_str()
                 .and_then(|s| s.trim_left_matches("v").replace(".", "").parse().ok());
             let val = match val {
                 Some(s) => s,
                 None => continue,
             };
             if val > max_vers {
                 if let Ok(k) = key.open(&subkey) {
                     max_vers = val;
@@ -567,25 +603,26 @@ mod impl_ {
             }
         }
         max_key
     }
 
     pub fn has_msbuild_version(version: &str) -> bool {
         match version {
             "15.0" => {
-                find_msbuild_vs15("x86_64-pc-windows-msvc").is_some() ||
-                    find_msbuild_vs15("i686-pc-windows-msvc").is_some()
+                find_msbuild_vs15("x86_64-pc-windows-msvc").is_some()
+                    || find_msbuild_vs15("i686-pc-windows-msvc").is_some()
             }
-            "12.0" | "14.0" => {
-                LOCAL_MACHINE.open(
-                    &OsString::from(format!("SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}",
-                                            version))).is_ok()
-            }
-            _ => false
+            "12.0" | "14.0" => LOCAL_MACHINE
+                .open(&OsString::from(format!(
+                    "SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}",
+                    version
+                )))
+                .is_ok(),
+            _ => false,
         }
     }
 
     // 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
         if let Some(r) = find_msbuild_vs15(target) {
             return Some(r);
@@ -594,34 +631,34 @@ mod impl_ {
         }
     }
 
     fn find_msbuild_vs15(target: &str) -> Option<Tool> {
         // Seems like this could also go through SetupConfiguration,
         // or that find_msvc_15 could just use this registry key
         // instead of the COM interface.
         let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7";
-        LOCAL_MACHINE.open(key.as_ref())
+        LOCAL_MACHINE
+            .open(key.as_ref())
             .ok()
-            .and_then(|key| {
-                key.query_str("15.0").ok()
-            })
+            .and_then(|key| key.query_str("15.0").ok())
             .map(|path| {
                 let path = PathBuf::from(path).join(r"MSBuild\15.0\Bin\MSBuild.exe");
                 let mut tool = Tool::new(path);
                 if target.contains("x86_64") {
                     tool.env.push(("Platform".into(), "X64".into()));
                 }
                 tool
             })
     }
 
     fn find_old_msbuild(target: &str) -> Option<Tool> {
         let key = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions";
-        LOCAL_MACHINE.open(key.as_ref())
+        LOCAL_MACHINE
+            .open(key.as_ref())
             .ok()
             .and_then(|key| {
                 max_version(&key).and_then(|(_vers, key)| key.query_str("MSBuildToolsPath").ok())
             })
             .map(|path| {
                 let mut path = PathBuf::from(path);
                 path.push("MSBuild.exe");
                 let mut tool = Tool::new(path);
--- a/third_party/rust/cc/tests/cc_env.rs
+++ b/third_party/rust/cc/tests/cc_env.rs
@@ -9,16 +9,20 @@ mod support;
 use support::Test;
 
 #[test]
 fn main() {
     ccache();
     distcc();
     ccache_spaces();
     ccache_env_flags();
+    leading_spaces();
+    extra_flags();
+    path_to_ccache();
+    more_spaces();
 }
 
 fn ccache() {
     let test = Test::gnu();
 
     env::set_var("CC", "ccache cc");
     let compiler = test.gcc().file("foo.c").get_compiler();
 
@@ -66,8 +70,50 @@ fn ccache_env_flags() {
             .cflags_env()
             .into_string()
             .unwrap()
             .contains(" lol-this-is-not-a-compiler") == false
     );
 
     env::set_var("CC", "");
 }
+
+fn leading_spaces() {
+    let test = Test::gnu();
+    test.shim("ccache");
+
+    env::set_var("CC", " test ");
+    let compiler = test.gcc().file("foo.c").get_compiler();
+    assert_eq!(compiler.path(), Path::new("test"));
+
+    env::set_var("CC", "");
+}
+
+fn extra_flags() {
+    let test = Test::gnu();
+    test.shim("ccache");
+
+    env::set_var("CC", "ccache cc -m32");
+    let compiler = test.gcc().file("foo.c").get_compiler();
+    assert_eq!(compiler.path(), Path::new("cc"));
+}
+
+fn path_to_ccache() {
+    let test = Test::gnu();
+    test.shim("ccache");
+
+    env::set_var("CC", "/path/to/ccache.exe cc -m32");
+    let compiler = test.gcc().file("foo.c").get_compiler();
+    assert_eq!(compiler.path(), Path::new("cc"));
+    assert_eq!(
+        compiler.cc_env(),
+        OsString::from("/path/to/ccache.exe cc -m32"),
+    );
+}
+
+fn more_spaces() {
+    let test = Test::gnu();
+    test.shim("ccache");
+
+    env::set_var("CC", "cc -m32");
+    let compiler = test.gcc().file("foo.c").get_compiler();
+    assert_eq!(compiler.path(), Path::new("cc"));
+}
--- a/third_party/rust/cc/tests/support/mod.rs
+++ b/third_party/rust/cc/tests/support/mod.rs
@@ -80,17 +80,19 @@ impl Test {
     }
 
     pub fn cmd(&self, i: u32) -> Execution {
         let mut s = String::new();
         File::open(self.td.path().join(format!("out{}", i)))
             .unwrap()
             .read_to_string(&mut s)
             .unwrap();
-        Execution { args: s.lines().map(|s| s.to_string()).collect() }
+        Execution {
+            args: s.lines().map(|s| s.to_string()).collect(),
+        }
     }
 }
 
 impl Execution {
     pub fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
         if !self.has(p.as_ref()) {
             panic!("didn't find {:?} in {:?}", p.as_ref(), self.args);
         } else {
@@ -106,17 +108,24 @@ impl Execution {
         }
     }
 
     pub fn has(&self, p: &OsStr) -> bool {
         self.args.iter().any(|arg| OsStr::new(arg) == p)
     }
 
     pub fn must_have_in_order(&self, before: &str, after: &str) -> &Execution {
-        let before_position = self.args.iter().rposition(|x| OsStr::new(x) == OsStr::new(before));
-        let after_position = self.args.iter().rposition(|x| OsStr::new(x) == OsStr::new(after));
+        let before_position = self.args
+            .iter()
+            .rposition(|x| OsStr::new(x) == OsStr::new(before));
+        let after_position = self.args
+            .iter()
+            .rposition(|x| OsStr::new(x) == OsStr::new(after));
         match (before_position, after_position) {
-            (Some(b), Some(a)) if b < a => {},
-            (b, a) => { panic!("{:?} (last position: {:?}) did not appear before {:?} (last position: {:?})", before, b, after, a) },
+            (Some(b), Some(a)) if b < a => {}
+            (b, a) => panic!(
+                "{:?} (last position: {:?}) did not appear before {:?} (last position: {:?})",
+                before, b, after, a
+            ),
         };
         self
     }
 }
--- a/third_party/rust/cc/tests/test.rs
+++ b/third_party/rust/cc/tests/test.rs
@@ -3,66 +3,53 @@ extern crate tempdir;
 
 use support::Test;
 
 mod support;
 
 #[test]
 fn gnu_smoke() {
     let test = Test::gnu();
-    test.gcc()
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().file("foo.c").compile("foo");
 
     test.cmd(0)
         .must_have("-O2")
         .must_have("foo.c")
         .must_not_have("-g")
         .must_have("-c")
         .must_have("-ffunction-sections")
         .must_have("-fdata-sections");
     test.cmd(1).must_have(test.td.path().join("foo.o"));
 }
 
 #[test]
 fn gnu_opt_level_1() {
     let test = Test::gnu();
-    test.gcc()
-        .opt_level(1)
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().opt_level(1).file("foo.c").compile("foo");
 
-    test.cmd(0)
-        .must_have("-O1")
-        .must_not_have("-O2");
+    test.cmd(0).must_have("-O1").must_not_have("-O2");
 }
 
 #[test]
 fn gnu_opt_level_s() {
     let test = Test::gnu();
-    test.gcc()
-        .opt_level_str("s")
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().opt_level_str("s").file("foo.c").compile("foo");
 
     test.cmd(0)
         .must_have("-Os")
         .must_not_have("-O1")
         .must_not_have("-O2")
         .must_not_have("-O3")
         .must_not_have("-Oz");
 }
 
 #[test]
 fn gnu_debug() {
     let test = Test::gnu();
-    test.gcc()
-        .debug(true)
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().debug(true).file("foo.c").compile("foo");
     test.cmd(0).must_have("-g");
 }
 
 #[test]
 fn gnu_warnings_into_errors() {
     let test = Test::gnu();
     test.gcc()
         .warnings_into_errors(true)
@@ -76,46 +63,44 @@ fn gnu_warnings_into_errors() {
 fn gnu_warnings() {
     let test = Test::gnu();
     test.gcc()
         .warnings(true)
         .flag("-Wno-missing-field-initializers")
         .file("foo.c")
         .compile("foo");
 
-    test.cmd(0).must_have("-Wall")
-               .must_have("-Wextra");
+    test.cmd(0).must_have("-Wall").must_have("-Wextra");
 }
 
 #[test]
 fn gnu_warnings_overridable() {
     let test = Test::gnu();
     test.gcc()
         .warnings(true)
         .flag("-Wno-missing-field-initializers")
         .file("foo.c")
         .compile("foo");
 
-    test.cmd(0).must_have_in_order("-Wall", "-Wno-missing-field-initializers");
+    test.cmd(0)
+        .must_have_in_order("-Wall", "-Wno-missing-field-initializers");
 }
 
 #[test]
 fn gnu_x86_64() {
     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
         let target = format!("x86_64-{}", vendor);
         let test = Test::gnu();
         test.gcc()
             .target(&target)
             .host(&target)
             .file("foo.c")
             .compile("foo");
 
-        test.cmd(0)
-            .must_have("-fPIC")
-            .must_have("-m64");
+        test.cmd(0).must_have("-fPIC").must_have("-m64");
     }
 }
 
 #[test]
 fn gnu_x86_64_no_pic() {
     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
         let target = format!("x86_64-{}", vendor);
         let test = Test::gnu();
@@ -136,18 +121,17 @@ fn gnu_i686() {
         let target = format!("i686-{}", vendor);
         let test = Test::gnu();
         test.gcc()
             .target(&target)
             .host(&target)
             .file("foo.c")
             .compile("foo");
 
-        test.cmd(0)
-            .must_have("-m32");
+        test.cmd(0).must_have("-m32");
     }
 }
 
 #[test]
 fn gnu_i686_pic() {
     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
         let target = format!("i686-{}", vendor);
         let test = Test::gnu();
@@ -171,20 +155,17 @@ fn gnu_set_stdlib() {
         .compile("foo");
 
     test.cmd(0).must_not_have("-stdlib=foo");
 }
 
 #[test]
 fn gnu_include() {
     let test = Test::gnu();
-    test.gcc()
-        .include("foo/bar")
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().include("foo/bar").file("foo.c").compile("foo");
 
     test.cmd(0).must_have("-I").must_have("foo/bar");
 }
 
 #[test]
 fn gnu_define() {
     let test = Test::gnu();
     test.gcc()
@@ -194,40 +175,36 @@ fn gnu_define() {
         .compile("foo");
 
     test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
 }
 
 #[test]
 fn gnu_compile_assembly() {
     let test = Test::gnu();
-    test.gcc()
-        .file("foo.S")
-        .compile("foo");
+    test.gcc().file("foo.S").compile("foo");
     test.cmd(0).must_have("foo.S");
 }
 
 #[test]
 fn gnu_shared() {
     let test = Test::gnu();
     test.gcc()
         .file("foo.c")
         .shared_flag(true)
         .static_flag(false)
         .compile("foo");
 
-    test.cmd(0)
-        .must_have("-shared")
-        .must_not_have("-static");
+    test.cmd(0).must_have("-shared").must_not_have("-static");
 }
 
 #[test]
 fn gnu_flag_if_supported() {
     if cfg!(windows) {
-        return
+        return;
     }
     let test = Test::gnu();
     test.gcc()
         .file("foo.c")
         .flag_if_supported("-Wall")
         .flag_if_supported("-Wflag-does-not-exist")
         .flag_if_supported("-std=c++11")
         .compile("foo");
@@ -236,87 +213,73 @@ fn gnu_flag_if_supported() {
         .must_have("-Wall")
         .must_not_have("-Wflag-does-not-exist")
         .must_not_have("-std=c++11");
 }
 
 #[test]
 fn gnu_flag_if_supported_cpp() {
     if cfg!(windows) {
-        return
+        return;
     }
     let test = Test::gnu();
     test.gcc()
         .cpp(true)
         .file("foo.cpp")
         .flag_if_supported("-std=c++11")
         .compile("foo");
 
-    test.cmd(0)
-        .must_have("-std=c++11");
+    test.cmd(0).must_have("-std=c++11");
 }
 
 #[test]
 fn gnu_static() {
     let test = Test::gnu();
     test.gcc()
         .file("foo.c")
         .shared_flag(false)
         .static_flag(true)
         .compile("foo");
 
-    test.cmd(0)
-        .must_have("-static")
-        .must_not_have("-shared");
+    test.cmd(0).must_have("-static").must_not_have("-shared");
 }
 
 #[test]
 fn msvc_smoke() {
     let test = Test::msvc();
-    test.gcc()
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().file("foo.c").compile("foo");
 
     test.cmd(0)
         .must_have("/O2")
         .must_have("foo.c")
         .must_not_have("/Z7")
         .must_have("/c")
         .must_have("/MD");
     test.cmd(1).must_have(test.td.path().join("foo.o"));
 }
 
 #[test]
 fn msvc_opt_level_0() {
     let test = Test::msvc();
-    test.gcc()
-        .opt_level(0)
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().opt_level(0).file("foo.c").compile("foo");
 
     test.cmd(0).must_not_have("/O2");
 }
 
 #[test]
 fn msvc_debug() {
     let test = Test::msvc();
-    test.gcc()
-        .debug(true)
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().debug(true).file("foo.c").compile("foo");
     test.cmd(0).must_have("/Z7");
 }
 
 #[test]
 fn msvc_include() {
     let test = Test::msvc();
-    test.gcc()
-        .include("foo/bar")
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().include("foo/bar").file("foo.c").compile("foo");
 
     test.cmd(0).must_have("/I").must_have("foo/bar");
 }
 
 #[test]
 fn msvc_define() {
     let test = Test::msvc();
     test.gcc()
@@ -326,26 +289,20 @@ fn msvc_define() {
         .compile("foo");
 
     test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
 }
 
 #[test]
 fn msvc_static_crt() {
     let test = Test::msvc();
-    test.gcc()
-        .static_crt(true)
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().static_crt(true).file("foo.c").compile("foo");
 
     test.cmd(0).must_have("/MT");
 }
 
 #[test]
 fn msvc_no_static_crt() {
     let test = Test::msvc();
-    test.gcc()
-        .static_crt(false)
-        .file("foo.c")
-        .compile("foo");
+    test.gcc().static_crt(false).file("foo.c").compile("foo");
 
     test.cmd(0).must_have("/MD");
 }