--- a/Cargo.lock
+++ b/Cargo.lock
@@ -256,23 +256,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.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.18 (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.9"
+version = "1.0.18"
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)",
@@ -317,17 +317,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.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.18 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1068,17 +1068,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.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.18 (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 = [
@@ -1204,17 +1204,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.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.18 (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"
@@ -2545,17 +2545,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.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
+"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275"
"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.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2"
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
"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.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7caa6cb9e76ddddbea09a03266d6b3bc98cd41e9fb9b017c473e7cca593ec25"
--- a/third_party/rust/cc/.cargo-checksum.json
+++ b/third_party/rust/cc/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".travis.yml":"04e69a35c252b62a8b2a47c5bd2b8dcdfbfb97e9457fe78b2f310eb710a2a781","Cargo.toml":"8829f9474c56e0deb7279d19a303243130a46e2f0b46731c5fa68eddfa5824b1","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"186c5c8a62520cb7a3d90d77161c954b52ae8456fca0e0669bc3a5b889592a43","appveyor.yml":"ab45bfdcf2596f357225a54e730c34d518a8f3ad56c2ed33af682cfd45bddc02","src/bin/gcc-shim.rs":"d6be9137cb48b86891e7b263adbf492e1193ffe682db9ba4a88eb1079b874b58","src/com.rs":"8b9a54af5400c259f877126cc68ea63ada4fe66e84c9b840711c95e570b15774","src/lib.rs":"6e8cea99f5fc8e5982b1ea9a336ee2f9a6158a9498c8f0c36f1e8cee8c99716e","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"f5c45afc99ad3b7c1311242bc4baf37e861d740ab81bf6ca90e2aa283672e65a","src/winapi.rs":"d7929b36130e33f1caa6bd444b378b83023b2b82d589c6e0ab38c4ff6c950da8","src/windows_registry.rs":"5caea0d9ff6513a1fa2908cf8f72906da981af8de8756bae3ca182d755bdf552","tests/cc_env.rs":"bf7b14aa52af04294f648b2934f0f1830c5a0bdac1676310b8aa1f61458e7782","tests/support/mod.rs":"80dc87e54025197104cfb62d1af7a3400a3a0ddf0f2d98ea4ef4111cb1f0c890","tests/test.rs":"42a771b1b6e1ed83b31204439b8ba5190b151ae93d5fa402a18851273df39cc0"},"package":"2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"}
\ No newline at end of file
+{"files":{".travis.yml":"26bcb4e14726789c4bdf8783f445820c012d82d623ea51beb985d4d4ec870733","Cargo.toml":"b921b2f55193e3c4b09fa93329734c5811fb1e5a08c5fb6f10b960147403564d","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":"f0b231d2e1923d43cd987278ccf4f20d55a6da4e2959061f57434d87428f003d","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"f5c45afc99ad3b7c1311242bc4baf37e861d740ab81bf6ca90e2aa283672e65a","src/winapi.rs":"d7929b36130e33f1caa6bd444b378b83023b2b82d589c6e0ab38c4ff6c950da8","src/windows_registry.rs":"e31ce7a3273d67f99387edf28c5a9b4d6efab8f03fe446079c2b1ede6a21ffdb","tests/cc_env.rs":"bf7b14aa52af04294f648b2934f0f1830c5a0bdac1676310b8aa1f61458e7782","tests/support/mod.rs":"80dc87e54025197104cfb62d1af7a3400a3a0ddf0f2d98ea4ef4111cb1f0c890","tests/test.rs":"a6f4fde55631b0a8726cfb026791759c92720a5ba890e6989e9405d5acf461db"},"package":"2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275"}
\ No newline at end of file
--- a/third_party/rust/cc/src/lib.rs
+++ b/third_party/rust/cc/src/lib.rs
@@ -112,16 +112,17 @@ pub struct Build {
archiver: Option<PathBuf>,
cargo_metadata: bool,
pic: Option<bool>,
static_crt: Option<bool>,
shared_flag: Option<bool>,
static_flag: Option<bool>,
warnings_into_errors: bool,
warnings: bool,
+ extra_warnings: bool,
}
/// Represents the types of errors that may occur while using cc-rs.
#[derive(Clone, Debug)]
enum ErrorKind {
/// Error occurred while performing I/O.
IOError,
/// Invalid architecture supplied.
@@ -184,77 +185,82 @@ pub struct Tool {
#[derive(Copy, Clone, Debug, PartialEq)]
enum ToolFamily {
/// Tool is GNU Compiler Collection-like.
Gnu,
/// Tool is Clang-like. It differs from the GCC in a sense that it accepts superset of flags
/// and its cross-compilation approach is different.
Clang,
/// Tool is the MSVC cl.exe.
- Msvc,
+ Msvc { clang_cl: bool },
}
impl ToolFamily {
/// What the flag to request debug info for this family of tools look like
fn debug_flag(&self) -> &'static str {
match *self {
- ToolFamily::Msvc => "/Z7",
+ ToolFamily::Msvc { .. } => "/Z7",
ToolFamily::Gnu | ToolFamily::Clang => "-g",
}
}
/// What the flag to include directories into header search path looks like
fn include_flag(&self) -> &'static str {
match *self {
- ToolFamily::Msvc => "/I",
+ ToolFamily::Msvc { .. } => "/I",
ToolFamily::Gnu | ToolFamily::Clang => "-I",
}
}
/// What the flag to request macro-expanded source output looks like
fn expand_flag(&self) -> &'static str {
match *self {
- ToolFamily::Msvc => "/E",
+ ToolFamily::Msvc { .. } => "/E",
ToolFamily::Gnu | ToolFamily::Clang => "-E",
}
}
/// What the flags to enable all warnings
- fn warnings_flags(&self) -> &'static [&'static str] {
- static MSVC_FLAGS: &'static [&'static str] = &["/W4"];
- static GNU_CLANG_FLAGS: &'static [&'static str] = &["-Wall", "-Wextra"];
+ fn warnings_flags(&self) -> &'static str {
+ match *self {
+ ToolFamily::Msvc { .. } => "/W4",
+ ToolFamily::Gnu | ToolFamily::Clang => "-Wall",
+ }
+ }
+ /// What the flags to enable extra warnings
+ fn extra_warnings_flags(&self) -> Option<&'static str> {
match *self {
- ToolFamily::Msvc => &MSVC_FLAGS,
- ToolFamily::Gnu | ToolFamily::Clang => &GNU_CLANG_FLAGS,
+ ToolFamily::Msvc { .. } => None,
+ ToolFamily::Gnu | ToolFamily::Clang => Some("-Wextra"),
}
}
/// What the flag to turn warning into errors
fn warnings_to_errors_flag(&self) -> &'static str {
match *self {
- ToolFamily::Msvc => "/WX",
+ ToolFamily::Msvc { .. } => "/WX",
ToolFamily::Gnu | ToolFamily::Clang => "-Werror",
}
}
/// 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::Msvc { .. } => unimplemented!(),
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::Msvc { .. } => unimplemented!(),
ToolFamily::Gnu | ToolFamily::Clang => "-Xcompiler",
}
}
}
/// Represents an object.
///
/// This is a source file -> object file pair.
@@ -299,16 +305,17 @@ impl Build {
debug: None,
env: Vec::new(),
compiler: None,
archiver: None,
cargo_metadata: true,
pic: None,
static_crt: None,
warnings: true,
+ extra_warnings: true,
warnings_into_errors: false,
}
}
/// Add a directory to the `-I` or include path for headers
///
/// # Example
///
@@ -401,21 +408,22 @@ impl Build {
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 host = self.get_host()?;
let mut cfg = Build::new();
cfg.flag(flag)
.target(&target)
.opt_level(0)
- .host(&target)
+ .host(&host)
.debug(false)
.cpp(self.cpp)
.cuda(self.cuda);
let compiler = cfg.try_get_compiler()?;
let mut cmd = compiler.to_command();
let is_arm = target.contains("aarch64") || target.contains("arm");
command_add_output_file(&mut cmd, &obj, target.contains("msvc"), false, is_arm);
@@ -568,25 +576,50 @@ impl Build {
/// ```no_run
/// cc::Build::new()
/// .file("src/foo.c")
/// .warnings(false)
/// .compile("libfoo.a");
/// ```
pub fn warnings(&mut self, warnings: bool) -> &mut Build {
self.warnings = warnings;
+ self.extra_warnings = warnings;
+ self
+ }
+
+ /// Set extra warnings flags.
+ ///
+ /// Adds some flags:
+ /// - nothing for MSVC.
+ /// - "-Wextra" for GNU and Clang.
+ ///
+ /// Enabled by default.
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// // Disables -Wextra, -Wall remains enabled:
+ /// cc::Build::new()
+ /// .file("src/foo.c")
+ /// .extra_warnings(false)
+ /// .compile("libfoo.a");
+ /// ```
+ pub fn extra_warnings(&mut self, warnings: bool) -> &mut Build {
+ self.extra_warnings = warnings;
self
}
/// Set the standard library to link against when compiling with C++
/// support.
///
/// The default value of this property depends on the current target: On
/// OS X `Some("c++")` is used, when compiling for a Visual Studio based
/// target `None` is used and for other targets `Some("stdc++")` is used.
+ /// If the `CXXSTDLIB` environment variable is set, its value will
+ /// override the default value.
///
/// A value of `None` indicates that no automatic linking should happen,
/// otherwise cargo will link against the specified library.
///
/// The given library name must not contain the `lib` prefix.
///
/// Common values:
/// - `stdc++` for GNU
@@ -1022,17 +1055,17 @@ impl Build {
let opt_level = self.get_opt_level()?;
let target = self.get_target()?;
let mut cmd = self.get_base_compiler()?;
// Non-target flags
// If the flag is not conditioned on target variable, it belongs here :)
match cmd.family {
- ToolFamily::Msvc => {
+ ToolFamily::Msvc { .. } => {
assert!(!self.cuda,
"CUDA C++ compilation not supported for MSVC, yet... but you are welcome to implement it :)");
cmd.args.push("/nologo".into());
let crt_flag = match self.static_crt {
Some(true) => "/MT",
Some(false) => "/MD",
@@ -1087,48 +1120,70 @@ impl Build {
cmd.push_cc_arg(debug_flag);
}
// Target flags
match cmd.family {
ToolFamily::Clang => {
cmd.args.push(format!("--target={}", target).into());
}
- ToolFamily::Msvc => {
- if target.contains("i586") {
- cmd.args.push("/ARCH:IA32".into());
+ ToolFamily::Msvc { clang_cl } => {
+ if clang_cl {
+ if target.contains("x86_64") {
+ cmd.args.push("-m64".into());
+ } else if target.contains("i586") {
+ cmd.args.push("-m32".into());
+ cmd.args.push("/arch:IA32".into());
+ } else {
+ cmd.args.push("-m32".into());
+ }
+ } else {
+ if target.contains("i586") {
+ cmd.args.push("/ARCH:IA32".into());
+ }
}
}
ToolFamily::Gnu => {
if target.contains("i686") || target.contains("i586") {
cmd.args.push("-m32".into());
} else if target == "x86_64-unknown-linux-gnux32" {
cmd.args.push("-mx32".into());
} else if target.contains("x86_64") || target.contains("powerpc64") {
cmd.args.push("-m64".into());
}
- if self.static_flag.is_none() && target.contains("musl") {
- cmd.args.push("-static".into());
+ if self.static_flag.is_none() {
+ let features = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new());
+ if features.contains("crt-static") {
+ cmd.args.push("-static".into());
+ }
}
// armv7 targets get to use armv7 instructions
- if target.starts_with("armv7-") && target.contains("-linux-") {
+ if (target.starts_with("armv7") || target.starts_with("thumbv7")) && target.contains("-linux-") {
cmd.args.push("-march=armv7-a".into());
}
- // On android we can guarantee some extra float instructions
- // (specified in the android spec online)
- if target.starts_with("armv7-linux-androideabi") {
- cmd.args.push("-march=armv7-a".into());
+ // (x86 Android doesn't say "eabi")
+ if target.contains("-androideabi") && target.contains("v7") {
+ // -march=armv7-a handled above
cmd.args.push("-mthumb".into());
- cmd.args.push("-mfpu=vfpv3-d16".into());
+ if !target.contains("neon") {
+ // On android we can guarantee some extra float instructions
+ // (specified in the android spec online)
+ // NEON guarantees even more; see below.
+ cmd.args.push("-mfpu=vfpv3-d16".into());
+ }
cmd.args.push("-mfloat-abi=softfp".into());
}
+ if target.contains("neon") {
+ cmd.args.push("-mfpu=neon-vfpv4".into());
+ }
+
if target.starts_with("armv4t-unknown-linux-") {
cmd.args.push("-march=armv4t".into());
cmd.args.push("-marm".into());
cmd.args.push("-mfloat-abi=soft".into());
}
if target.starts_with("armv5te-unknown-linux-") {
cmd.args.push("-march=armv5te".into());
@@ -1223,33 +1278,38 @@ impl Build {
}
for directory in self.include_directories.iter() {
cmd.args.push(cmd.family.include_flag().into());
cmd.args.push(directory.into());
}
if self.warnings {
- for flag in cmd.family.warnings_flags().iter() {
- cmd.push_cc_arg(flag.into());
+ let wflags = cmd.family.warnings_flags().into();
+ cmd.push_cc_arg(wflags);
+ }
+
+ if self.extra_warnings {
+ if let Some(wflags) = cmd.family.extra_warnings_flags() {
+ cmd.push_cc_arg(wflags.into());
}
}
for flag in self.flags.iter() {
cmd.args.push(flag.into());
}
for flag in self.flags_supported.iter() {
if self.is_flag_supported(flag).unwrap_or(false) {
cmd.push_cc_arg(flag.into());
}
}
for &(ref key, ref value) in self.definitions.iter() {
- let lead = if let ToolFamily::Msvc = cmd.family {
+ let lead = if let ToolFamily::Msvc { .. } = cmd.family {
"/"
} else {
"-"
};
if let Some(ref value) = *value {
cmd.args.push(format!("{}D{}={}", lead, key, value).into());
} else {
cmd.args.push(format!("{}D{}", lead, key).into());
@@ -1485,16 +1545,18 @@ impl Build {
// On Solaris, c++/cc unlikely to exist or be correct.
let default = if host.contains("solaris") {
gnu
} else {
traditional
};
+ let cl_exe = windows_registry::find_tool(&target, "cl.exe");
+
let tool_opt: Option<Tool> = self.env_tool(env)
.map(|(tool, cc, args)| {
// chop off leading/trailing whitespace to work around
// 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 {
@@ -1516,29 +1578,37 @@ impl Build {
Some(t)
} else {
Some(Tool::new(PathBuf::from(tool)))
}
} else {
None
}
})
- .or_else(|| windows_registry::find_tool(&target, "cl.exe"));
+ .or_else(|| cl_exe.clone());
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 {
format!("{}.exe", gnu)
}
} else if target.contains("android") {
- format!("{}-{}", target.replace("armv7", "arm"), gnu)
+ format!(
+ "{}-{}",
+ target
+ .replace("armv7", "arm")
+ .replace("armv7neon", "arm")
+ .replace("thumbv7", "arm")
+ .replace("thumbv7neon", "arm"),
+ gnu
+ )
} else if target.contains("cloudabi") {
format!("{}-{}", target, traditional)
} else if self.get_host()? != target {
// CROSS_COMPILE is of the form: "arm-linux-gnueabi-"
let cc_env = self.getenv("CROSS_COMPILE");
let cross_compile = cc_env.as_ref().map(|s| s.trim_right_matches('-'));
let prefix = cross_compile.or(match &target[..] {
"aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"),
@@ -1549,16 +1619,22 @@ impl Build {
"arm-frc-linux-gnueabi" => Some("arm-frc-linux-gnueabi"),
"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"),
+ "armv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
+ "armv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
+ "thumbv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
+ "thumbv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
+ "thumbv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
+ "thumbv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
"armv7-unknown-netbsd-eabihf" => Some("armv7--netbsdelf-eabihf"),
"i586-unknown-linux-musl" => Some("musl"),
"i686-pc-windows-gnu" => Some("i686-w64-mingw32"),
"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"),
@@ -1589,17 +1665,17 @@ impl Build {
}
} else {
default.to_string()
};
Tool::new(PathBuf::from(compiler))
}
};
- let tool = if self.cuda {
+ let mut tool = if self.cuda {
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,
};
@@ -1607,16 +1683,37 @@ impl Build {
nvcc_tool
.args
.push(format!("-ccbin={}", tool.path.display()).into());
nvcc_tool
} else {
tool
};
+ // If we found `cl.exe` in our environment, the tool we're returning is
+ // an MSVC-like tool, *and* no env vars were set then set env vars for
+ // the tool that we're returning.
+ //
+ // Env vars are needed for things like `link.exe` being put into PATH as
+ // well as header include paths sometimes. These paths are automatically
+ // included by default but if the `CC` or `CXX` env vars are set these
+ // won't be used. This'll ensure that when the env vars are used to
+ // configure for invocations like `clang-cl` we still get a "works out
+ // of the box" experience.
+ if let Some(cl_exe) = cl_exe {
+ if tool.family == (ToolFamily::Msvc { clang_cl: true }) &&
+ tool.env.len() == 0 &&
+ target.contains("msvc")
+ {
+ for &(ref k, ref v) in cl_exe.env.iter() {
+ tool.env.push((k.to_owned(), v.to_owned()));
+ }
+ }
+ }
+
Ok(tool)
}
fn get_var(&self, var_base: &str) -> Result<String, Error> {
let target = self.get_target()?;
let host = self.get_host()?;
let kind = if host == target { "HOST" } else { "TARGET" };
let target_u = target.replace("-", "_");
@@ -1708,27 +1805,35 @@ impl Build {
}
/// 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("apple") {
- Ok(Some("c++".to_string()))
- } else if target.contains("freebsd") {
- Ok(Some("c++".to_string()))
- } else if target.contains("openbsd") {
- Ok(Some("c++".to_string()))
+ if let Ok(stdlib) = self.get_var("CXXSTDLIB") {
+ if stdlib.is_empty() {
+ Ok(None)
+ } else {
+ Ok(Some(stdlib))
+ }
} else {
- Ok(Some("stdc++".to_string()))
+ let target = self.get_target()?;
+ if target.contains("msvc") {
+ Ok(None)
+ } else if target.contains("apple") {
+ Ok(Some("c++".to_string()))
+ } else if target.contains("freebsd") {
+ Ok(Some("c++".to_string()))
+ } else if target.contains("openbsd") {
+ Ok(Some("c++".to_string()))
+ } else {
+ Ok(Some("stdc++".to_string()))
+ }
}
}
}
}
fn get_ar(&self) -> Result<(Command, String), Error> {
if let Some(ref p) = self.archiver {
let name = p.file_name().and_then(|s| s.to_str()).unwrap_or("ar");
@@ -1826,22 +1931,25 @@ impl Default for Build {
impl Tool {
fn new(path: PathBuf) -> 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") {
+ if fname.contains("clang-cl") {
+ ToolFamily::Msvc { clang_cl: true }
+ } else if fname.contains("cl") &&
+ !fname.contains("cloudabi") &&
+ !fname.contains("uclibc") &&
+ !fname.contains("clang") {
+ ToolFamily::Msvc { clang_cl: false }
+ } else if fname.contains("clang") {
ToolFamily::Clang
- } else if fname.contains("cl") && !fname.contains("cloudabi")
- && !fname.contains("uclibc")
- {
- ToolFamily::Msvc
} else {
ToolFamily::Gnu
}
} else {
ToolFamily::Gnu
};
Tool {
path: path,
@@ -1871,21 +1979,21 @@ impl Tool {
/// This is useful for when the compiler needs to be executed and the
/// command returned will already have the initial arguments and environment
/// 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),
};
+ cmd.args(&self.cc_wrapper_args);
cmd.args(&self.args);
for &(ref k, ref v) in self.env.iter() {
cmd.env(k, v);
}
cmd
}
/// Returns the path for this compiler.
@@ -1951,17 +2059,20 @@ impl Tool {
/// Whether the tool is Clang-like.
pub fn is_like_clang(&self) -> bool {
self.family == ToolFamily::Clang
}
/// Whether the tool is MSVC-like.
pub fn is_like_msvc(&self) -> bool {
- self.family == ToolFamily::Msvc
+ match self.family {
+ ToolFamily::Msvc { .. } => true,
+ _ => false,
+ }
}
}
fn run(cmd: &mut Command, program: &str) -> Result<(), Error> {
let (mut child, print) = spawn(cmd, program)?;
let status = match child.wait() {
Ok(s) => s,
Err(_) => {