|
|
@ -114,7 +114,7 @@ pub fn compile_library(output: &str, files: &[&str]) { |
|
|
|
for f in files.iter() { |
|
|
|
c.file(*f); |
|
|
|
} |
|
|
|
c.compile(output) |
|
|
|
c.compile(output); |
|
|
|
} |
|
|
|
|
|
|
|
impl Config { |
|
|
@ -194,8 +194,7 @@ impl Config { |
|
|
|
/// otherwise cargo will link against the specified library.
|
|
|
|
///
|
|
|
|
/// The given library name must not contain the `lib` prefix.
|
|
|
|
pub fn cpp_link_stdlib(&mut self, cpp_link_stdlib: Option<&str>) |
|
|
|
-> &mut Config { |
|
|
|
pub fn cpp_link_stdlib(&mut self, cpp_link_stdlib: Option<&str>) -> &mut Config { |
|
|
|
self.cpp_link_stdlib = Some(cpp_link_stdlib.map(|s| s.into())); |
|
|
|
self |
|
|
|
} |
|
|
@ -220,8 +219,7 @@ impl Config { |
|
|
|
/// be used, otherwise `-stdlib` is added to the compile invocation.
|
|
|
|
///
|
|
|
|
/// The given library name must not contain the `lib` prefix.
|
|
|
|
pub fn cpp_set_stdlib(&mut self, cpp_set_stdlib: Option<&str>) |
|
|
|
-> &mut Config { |
|
|
|
pub fn cpp_set_stdlib(&mut self, cpp_set_stdlib: Option<&str>) -> &mut Config { |
|
|
|
self.cpp_set_stdlib = cpp_set_stdlib.map(|s| s.into()); |
|
|
|
self.cpp_link_stdlib(cpp_set_stdlib); |
|
|
|
self |
|
|
@ -322,7 +320,8 @@ impl Config { |
|
|
|
|
|
|
|
#[doc(hidden)] |
|
|
|
pub fn __set_env<A, B>(&mut self, a: A, b: B) -> &mut Config |
|
|
|
where A: AsRef<OsStr>, B: AsRef<OsStr> |
|
|
|
where A: AsRef<OsStr>, |
|
|
|
B: AsRef<OsStr> |
|
|
|
{ |
|
|
|
self.env.push((a.as_ref().to_owned(), b.as_ref().to_owned())); |
|
|
|
self |
|
|
@ -355,9 +354,10 @@ impl Config { |
|
|
|
|
|
|
|
if self.get_target().contains("msvc") { |
|
|
|
let compiler = self.get_base_compiler(); |
|
|
|
let atlmfc_lib = compiler.env().iter().find(|&&(ref var, _)| { |
|
|
|
var.as_os_str() == OsStr::new("LIB") |
|
|
|
}).and_then(|&(_, ref lib_paths)| { |
|
|
|
let atlmfc_lib = compiler.env() |
|
|
|
.iter() |
|
|
|
.find(|&&(ref var, _)| var.as_os_str() == OsStr::new("LIB")) |
|
|
|
.and_then(|&(_, ref lib_paths)| { |
|
|
|
env::split_paths(lib_paths).find(|path| { |
|
|
|
let sub = Path::new("atlmfc/lib"); |
|
|
|
path.ends_with(sub) || path.parent().map_or(false, |p| p.ends_with(sub)) |
|
|
@ -365,8 +365,7 @@ impl Config { |
|
|
|
}); |
|
|
|
|
|
|
|
if let Some(atlmfc_lib) = atlmfc_lib { |
|
|
|
self.print(&format!("cargo:rustc-link-search=native={}", |
|
|
|
atlmfc_lib.display())); |
|
|
|
self.print(&format!("cargo:rustc-link-search=native={}", atlmfc_lib.display())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -394,9 +393,7 @@ impl Config { |
|
|
|
} |
|
|
|
drop(rayon::initialize(cfg)); |
|
|
|
|
|
|
|
objs.par_iter().weight_max().for_each(|&(ref src, ref dst)| { |
|
|
|
self.compile_object(src, dst) |
|
|
|
}) |
|
|
|
objs.par_iter().weight_max().for_each(|&(ref src, ref dst)| self.compile_object(src, dst)); |
|
|
|
} |
|
|
|
|
|
|
|
#[cfg(not(feature = "parallel"))] |
|
|
@ -417,8 +414,12 @@ impl Config { |
|
|
|
for &(ref a, ref b) in self.env.iter() { |
|
|
|
cmd.env(a, b); |
|
|
|
} |
|
|
|
(cmd, compiler.path.file_name().unwrap() |
|
|
|
.to_string_lossy().into_owned()) |
|
|
|
(cmd, |
|
|
|
compiler.path |
|
|
|
.file_name() |
|
|
|
.unwrap() |
|
|
|
.to_string_lossy() |
|
|
|
.into_owned()) |
|
|
|
}; |
|
|
|
if msvc && is_asm { |
|
|
|
cmd.arg("/Fo").arg(dst); |
|
|
@ -457,14 +458,14 @@ impl Config { |
|
|
|
self.print(&format!("debug={} opt-level={}", debug, opt_level)); |
|
|
|
|
|
|
|
let mut cmd = self.get_base_compiler(); |
|
|
|
let nvcc = cmd.path.to_str() |
|
|
|
let nvcc = cmd.path |
|
|
|
.to_str() |
|
|
|
.map(|path| path.contains("nvcc")) |
|
|
|
.unwrap_or(false); |
|
|
|
|
|
|
|
if msvc { |
|
|
|
cmd.args.push("/nologo".into()); |
|
|
|
let features = env::var("CARGO_CFG_TARGET_FEATURE") |
|
|
|
.unwrap_or(String::new()); |
|
|
|
let features = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new()); |
|
|
|
if features.contains("crt-static") { |
|
|
|
cmd.args.push("/MT".into()); |
|
|
|
} else { |
|
|
@ -503,7 +504,8 @@ impl Config { |
|
|
|
cmd.args.push("-m64".into()); |
|
|
|
} |
|
|
|
|
|
|
|
if !nvcc && self.pic.unwrap_or(!target.contains("i686") && !target.contains("windows-gnu")) { |
|
|
|
if !nvcc && |
|
|
|
self.pic.unwrap_or(!target.contains("i686") && !target.contains("windows-gnu")) { |
|
|
|
cmd.args.push("-fPIC".into()); |
|
|
|
} else if nvcc && self.pic.unwrap_or(false) { |
|
|
|
cmd.args.push("-Xcompiler".into()); |
|
|
@ -601,10 +603,12 @@ impl Config { |
|
|
|
|
|
|
|
fn msvc_macro_assembler(&self) -> (Command, String) { |
|
|
|
let target = self.get_target(); |
|
|
|
let tool = if target.contains("x86_64") {"ml64.exe"} else {"ml.exe"}; |
|
|
|
let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| { |
|
|
|
self.cmd(tool) |
|
|
|
}); |
|
|
|
let tool = if target.contains("x86_64") { |
|
|
|
"ml64.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); |
|
|
|
} |
|
|
@ -635,31 +639,37 @@ impl Config { |
|
|
|
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(self.cmd("lib.exe")), |
|
|
|
None => windows_registry::find(&target, "lib.exe").unwrap_or(self.cmd("lib.exe")), |
|
|
|
}; |
|
|
|
let mut out = OsString::from("/OUT:"); |
|
|
|
out.push(dst); |
|
|
|
run(cmd.arg(out).arg("/nologo") |
|
|
|
run(cmd.arg(out) |
|
|
|
.arg("/nologo") |
|
|
|
.args(objects) |
|
|
|
.args(&self.objects), "lib.exe"); |
|
|
|
.args(&self.objects), |
|
|
|
"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); |
|
|
|
fs::hard_link(&dst, &lib_dst).or_else(|_| { |
|
|
|
fs::hard_link(&dst, &lib_dst) |
|
|
|
.or_else(|_| { |
|
|
|
// if hard-link fails, just copy (ignoring the number of bytes written)
|
|
|
|
fs::copy(&dst, &lib_dst).map(|_| ()) |
|
|
|
}).ok().expect("Copying from {:?} to {:?} failed.");; |
|
|
|
}) |
|
|
|
.ok() |
|
|
|
.expect("Copying from {:?} to {:?} failed.");; |
|
|
|
} else { |
|
|
|
let ar = self.get_ar(); |
|
|
|
let cmd = ar.file_name().unwrap().to_string_lossy(); |
|
|
|
run(self.cmd(&ar).arg("crs") |
|
|
|
run(self.cmd(&ar) |
|
|
|
.arg("crs") |
|
|
|
.arg(dst) |
|
|
|
.args(objects) |
|
|
|
.args(&self.objects), &cmd); |
|
|
|
.args(&self.objects), |
|
|
|
&cmd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -677,7 +687,7 @@ impl Config { |
|
|
|
"arm64" | "aarch64" => ArchSpec::Device("arm64"), |
|
|
|
"i386" | "i686" => ArchSpec::Simulator("-m32"), |
|
|
|
"x86_64" => ArchSpec::Simulator("-m64"), |
|
|
|
_ => fail("Unknown arch for iOS target") |
|
|
|
_ => fail("Unknown arch for iOS target"), |
|
|
|
}; |
|
|
|
|
|
|
|
let sdk = match arch { |
|
|
@ -686,7 +696,7 @@ impl Config { |
|
|
|
cmd.args.push(arch.into()); |
|
|
|
cmd.args.push("-miphoneos-version-min=7.0".into()); |
|
|
|
"iphoneos" |
|
|
|
}, |
|
|
|
} |
|
|
|
ArchSpec::Simulator(arch) => { |
|
|
|
cmd.args.push(arch.into()); |
|
|
|
cmd.args.push("-mios-simulator-version-min=7.0".into()); |
|
|
@ -715,12 +725,12 @@ impl Config { |
|
|
|
for &(ref a, ref b) in self.env.iter() { |
|
|
|
cmd.env(a, b); |
|
|
|
} |
|
|
|
return cmd |
|
|
|
return cmd; |
|
|
|
} |
|
|
|
|
|
|
|
fn get_base_compiler(&self) -> Tool { |
|
|
|
if let Some(ref c) = self.compiler { |
|
|
|
return Tool::new(c.clone()) |
|
|
|
return Tool::new(c.clone()); |
|
|
|
} |
|
|
|
let host = self.get_host(); |
|
|
|
let target = self.get_target(); |
|
|
@ -729,13 +739,15 @@ impl Config { |
|
|
|
} else { |
|
|
|
("CC", "cl.exe", "gcc", "cc") |
|
|
|
}; |
|
|
|
self.env_tool(env).map(|(tool, args)| { |
|
|
|
self.env_tool(env) |
|
|
|
.map(|(tool, args)| { |
|
|
|
let mut t = Tool::new(PathBuf::from(tool)); |
|
|
|
for arg in args { |
|
|
|
t.args.push(arg.into()); |
|
|
|
} |
|
|
|
return t |
|
|
|
}).or_else(|| { |
|
|
|
return t; |
|
|
|
}) |
|
|
|
.or_else(|| { |
|
|
|
if target.contains("emscripten") { |
|
|
|
if self.cpp { |
|
|
|
Some(Tool::new(PathBuf::from("em++"))) |
|
|
@ -745,11 +757,10 @@ impl Config { |
|
|
|
} else { |
|
|
|
None |
|
|
|
} |
|
|
|
}).or_else(|| { |
|
|
|
windows_registry::find_tool(&target, "cl.exe") |
|
|
|
}).unwrap_or_else(|| { |
|
|
|
let compiler = if host.contains("windows") && |
|
|
|
target.contains("windows") { |
|
|
|
}) |
|
|
|
.or_else(|| windows_registry::find_tool(&target, "cl.exe")) |
|
|
|
.unwrap_or_else(|| { |
|
|
|
let compiler = if host.contains("windows") && target.contains("windows") { |
|
|
|
if target.contains("msvc") { |
|
|
|
msvc.to_string() |
|
|
|
} else { |
|
|
@ -823,8 +834,10 @@ impl Config { |
|
|
|
} |
|
|
|
|
|
|
|
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()) |
|
|
|
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() |
|
|
|
} |
|
|
@ -834,8 +847,7 @@ impl Config { |
|
|
|
let whitelist = ["ccache", "distcc"]; |
|
|
|
for t in whitelist.iter() { |
|
|
|
if tool.starts_with(t) && tool[t.len()..].starts_with(" ") { |
|
|
|
return (t.to_string(), |
|
|
|
vec![tool[t.len()..].trim_left().to_string()]) |
|
|
|
return (t.to_string(), vec![tool[t.len()..].trim_left().to_string()]); |
|
|
|
} |
|
|
|
} |
|
|
|
(tool, Vec::new()) |
|
|
@ -860,9 +872,10 @@ impl Config { |
|
|
|
} |
|
|
|
|
|
|
|
fn get_ar(&self) -> PathBuf { |
|
|
|
self.archiver.clone().or_else(|| { |
|
|
|
self.get_var("AR").map(PathBuf::from).ok() |
|
|
|
}).unwrap_or_else(|| { |
|
|
|
self.archiver |
|
|
|
.clone() |
|
|
|
.or_else(|| self.get_var("AR").map(PathBuf::from).ok()) |
|
|
|
.unwrap_or_else(|| { |
|
|
|
if self.get_target().contains("android") { |
|
|
|
PathBuf::from(format!("{}-ar", self.get_target())) |
|
|
|
} else if self.get_target().contains("emscripten") { |
|
|
@ -882,9 +895,7 @@ impl Config { |
|
|
|
} |
|
|
|
|
|
|
|
fn get_opt_level(&self) -> String { |
|
|
|
self.opt_level.as_ref().cloned().unwrap_or_else(|| { |
|
|
|
self.getenv_unwrap("OPT_LEVEL") |
|
|
|
}) |
|
|
|
self.opt_level.as_ref().cloned().unwrap_or_else(|| self.getenv_unwrap("OPT_LEVEL")) |
|
|
|
} |
|
|
|
|
|
|
|
fn get_debug(&self) -> bool { |
|
|
@ -892,9 +903,7 @@ impl Config { |
|
|
|
} |
|
|
|
|
|
|
|
fn get_out_dir(&self) -> PathBuf { |
|
|
|
self.out_dir.clone().unwrap_or_else(|| { |
|
|
|
env::var_os("OUT_DIR").map(PathBuf::from).unwrap() |
|
|
|
}) |
|
|
|
self.out_dir.clone().unwrap_or_else(|| env::var_os("OUT_DIR").map(PathBuf::from).unwrap()) |
|
|
|
} |
|
|
|
|
|
|
|
fn getenv(&self, v: &str) -> Option<String> { |
|
|
@ -937,7 +946,7 @@ impl Tool { |
|
|
|
for &(ref k, ref v) in self.env.iter() { |
|
|
|
cmd.env(k, v); |
|
|
|
} |
|
|
|
return cmd |
|
|
|
cmd |
|
|
|
} |
|
|
|
|
|
|
|
/// Returns the path for this compiler.
|
|
|
@ -991,7 +1000,10 @@ fn run(cmd: &mut Command, program: &str) { |
|
|
|
"" |
|
|
|
}; |
|
|
|
fail(&format!("failed to execute command: {}\nIs `{}` \ |
|
|
|
not installed?{}", e, program, extra)); |
|
|
|
not installed?{}", |
|
|
|
e, |
|
|
|
program, |
|
|
|
extra)); |
|
|
|
} |
|
|
|
Err(e) => fail(&format!("failed to execute command: {}", e)), |
|
|
|
}; |
|
|
|