diff --git a/.travis.yml b/.travis.yml index 6f3c53d..492f2f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,10 @@ matrix: 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: diff --git a/cc-test/build.rs b/cc-test/build.rs index 5a7b178..677161e 100644 --- a/cc-test/build.rs +++ b/cc-test/build.rs @@ -25,12 +25,12 @@ fn main() { let target = std::env::var("TARGET").unwrap(); let file = target.split("-").next().unwrap(); - let file = format!("src/{}.{}", - file, - if target.contains("msvc") { "asm" } else { "S" }); - cc::Build::new() - .file(file) - .compile("asm"); + let file = format!( + "src/{}.{}", + file, + if target.contains("msvc") { "asm" } else { "S" } + ); + cc::Build::new().file(file).compile("asm"); cc::Build::new() .file("src/baz.cpp") @@ -38,9 +38,7 @@ fn main() { .compile("baz"); if target.contains("windows") { - cc::Build::new() - .file("src/windows.c") - .compile("windows"); + cc::Build::new().file("src/windows.c").compile("windows"); } // Test that the `windows_registry` module will set PATH by looking for @@ -86,9 +84,7 @@ fn main() { .file("src/opt_linkage.c") .compile("OptLinkage"); - let out = cc::Build::new() - .file("src/expand.c") - .expand(); + let out = cc::Build::new().file("src/expand.c").expand(); let out = String::from_utf8(out).unwrap(); assert!(out.contains("hello world")); } diff --git a/src/com.rs b/src/com.rs index bd8cce7..2b16475 100644 --- a/src/com.rs +++ b/src/com.rs @@ -19,7 +19,7 @@ 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) }; @@ -30,8 +30,13 @@ pub fn initialize() -> Result<(), HRESULT> { Ok(()) } -pub struct ComPtr(*mut T) where T: Interface; -impl ComPtr where T: Interface { +pub struct ComPtr(*mut T) +where + T: Interface; +impl ComPtr +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`. @@ -40,7 +45,11 @@ impl ComPtr where T: Interface { ComPtr(ptr) } /// Casts up the inheritance chain - pub fn up(self) -> ComPtr where T: Deref, U: Interface { + pub fn up(self) -> ComPtr + where + T: Deref, + U: Interface, + { ComPtr(self.into_raw() as *mut U) } /// Extracts the raw pointer. @@ -55,20 +64,31 @@ impl ComPtr where T: Interface { unsafe { &*(self.0 as *mut IUnknown) } } /// Performs QueryInterface fun. - pub fn cast(&self) -> Result, i32> where U: Interface { + pub fn cast(&self) -> Result, 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 Deref for ComPtr where T: Interface { +impl Deref for ComPtr +where + T: Interface, +{ type Target = T; fn deref(&self) -> &T { unsafe { &*self.0 } } } -impl Clone for ComPtr where T: Interface { +impl Clone for ComPtr +where + T: Interface, +{ fn clone(&self) -> Self { unsafe { self.as_unknown().AddRef(); @@ -76,9 +96,14 @@ impl Clone for ComPtr where T: Interface { } } } -impl Drop for ComPtr where T: Interface { +impl Drop for ComPtr +where + T: Interface, +{ fn drop(&mut self) { - unsafe { self.as_unknown().Release(); } + unsafe { + self.as_unknown().Release(); + } } } pub struct BStr(BSTR); @@ -102,7 +127,10 @@ pub trait ToWide { fn to_wide(&self) -> Vec; fn to_wide_null(&self) -> Vec; } -impl ToWide for T where T: AsRef { +impl ToWide for T +where + T: AsRef, +{ fn to_wide(&self) -> Vec { self.as_ref().encode_wide().collect() } @@ -110,7 +138,10 @@ impl ToWide for T where T: AsRef { 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(); @@ -122,4 +153,3 @@ impl FromWide for OsString { OsStringExt::from_wide(wide) } } - diff --git a/src/lib.rs b/src/lib.rs index 847e319..9ec2309 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -61,16 +61,15 @@ 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}; 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)] @@ -242,8 +241,7 @@ impl ToolFamily { fn nvcc_debug_flag(&self) -> &'static str { match *self { ToolFamily::Msvc => unimplemented!(), - ToolFamily::Gnu | - ToolFamily::Clang => "-G", + ToolFamily::Gnu | ToolFamily::Clang => "-G", } } @@ -252,8 +250,7 @@ impl ToolFamily { fn nvcc_redirect_flag(&self) -> &'static str { match *self { ToolFamily::Msvc => unimplemented!(), - ToolFamily::Gnu | - ToolFamily::Clang => "-Xcompiler", + ToolFamily::Gnu | ToolFamily::Clang => "-Xcompiler", } } } @@ -270,10 +267,7 @@ struct Object { 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 } } } @@ -346,10 +340,8 @@ impl Build { /// .compile("foo"); /// ``` pub fn define<'a, V: Into>>(&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 } @@ -405,10 +397,12 @@ impl Build { /// `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 { - let known_status = self.known_flag_support_status.lock().ok() + let known_status = self.known_flag_support_status + .lock() + .ok() .and_then(|flag_status| flag_status.get(flag).cloned()); if let Some(is_supported) = known_status { - return Ok(is_supported) + return Ok(is_supported); } let out_dir = self.get_out_dir()?; @@ -426,8 +420,7 @@ impl Build { 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); + 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 @@ -796,9 +789,8 @@ impl Build { A: AsRef, B: AsRef, { - 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 } @@ -939,9 +931,7 @@ impl Build { 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(), ) @@ -979,9 +969,7 @@ impl Build { 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(); @@ -1226,14 +1214,13 @@ impl Build { 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 ); } @@ -1325,13 +1312,8 @@ impl Build { 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:"); @@ -1340,10 +1322,13 @@ impl Build { // 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::(); + let estimated_command_line_len = objects + .iter() + .chain(&self.objects) + .map(|a| a.as_os_str().len()) + .sum::(); if estimated_command_line_len > 1024 * 6 { - let mut args = String::from("\u{FEFF}"); // BOM + 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() { @@ -1364,7 +1349,10 @@ impl Build { let mut args_file = OsString::from(dst); args_file.push(".args"); - fs::File::create(&args_file).unwrap().write_all(&utf16le).unwrap(); + fs::File::create(&args_file) + .unwrap() + .write_all(&utf16le) + .unwrap(); let mut args_file_arg = OsString::from("@"); args_file_arg.push(args_file); @@ -1493,41 +1481,44 @@ impl Build { }; // On Solaris, c++/cc unlikely to exist or be correct. - let default = if host.contains("solaris") { gnu } else { traditional }; - - let tool_opt: Option = - 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))) - } + let default = if host.contains("solaris") { + gnu + } else { + traditional + }; + + let tool_opt: Option = 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 { - None + Some(Tool::new(PathBuf::from(tool))) } - }) - .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, @@ -1601,14 +1592,18 @@ impl Build { }; 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 @@ -1631,10 +1626,7 @@ impl Build { 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), )), } } @@ -1648,7 +1640,6 @@ impl Build { .collect() } - /// Returns compiler path, optional modifier name from whitelist, and arguments vec fn env_tool(&self, name: &str) -> Option<(String, Option, Vec)> { let tool = match self.get_var(name) { @@ -1674,14 +1665,18 @@ impl Build { None => return None, }; - let file_stem = Path::new(maybe_wrapper).file_stem().unwrap().to_str().unwrap(); + let file_stem = Path::new(maybe_wrapper) + .file_stem() + .unwrap() + .to_str() + .unwrap(); if whitelist.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(), - )) + )); } } @@ -1786,10 +1781,7 @@ impl Build { 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()), )), } } @@ -1817,8 +1809,9 @@ impl Tool { 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 @@ -1861,8 +1854,8 @@ impl Tool { 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() { @@ -1908,10 +1901,8 @@ impl Tool { cc_env.push(arg); } cc_env - }, - None => { - OsString::from("") } + None => OsString::from(""), } } @@ -1954,8 +1945,7 @@ fn run(cmd: &mut Command, program: &str) -> Result<(), Error> { ErrorKind::ToolExecError, &format!( "Failed to wait on spawned child process, command {:?} with args {:?}.", - cmd, - program + cmd, program ), )) } @@ -1970,9 +1960,7 @@ fn run(cmd: &mut Command, program: &str) -> Result<(), Error> { ErrorKind::ToolExecError, &format!( "Command {:?} with args {:?} did not execute successfully (status code {}).", - cmd, - program, - status + cmd, program, status ), )) } @@ -1995,8 +1983,7 @@ fn run_output(cmd: &mut Command, program: &str) -> Result, Error> { ErrorKind::ToolExecError, &format!( "Failed to wait on spawned child process, command {:?} with args {:?}.", - cmd, - program + cmd, program ), )) } @@ -2011,9 +1998,7 @@ fn run_output(cmd: &mut Command, program: &str) -> Result, Error> { ErrorKind::ToolExecError, &format!( "Command {:?} with args {:?} did not execute successfully (status code {}).", - cmd, - program, - status + cmd, program, status ), )) } @@ -2029,39 +2014,30 @@ fn spawn(cmd: &mut Command, program: &str) -> Result<(Child, JoinHandle<()>), Er 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), )), } } @@ -2070,7 +2046,6 @@ 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, is_arm: bool) { if msvc && is_asm && is_arm { cmd.arg("-o").arg(&dst); diff --git a/src/registry.rs b/src/registry.rs index a452723..2ac2fa6 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -8,7 +8,7 @@ // 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; @@ -36,28 +36,31 @@ 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; } @@ -90,11 +93,13 @@ impl RegistryKey { let key = key.encode_wide().chain(Some(0)).collect::>(); 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)))) @@ -116,29 +121,36 @@ impl RegistryKey { 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)); } @@ -169,14 +181,16 @@ impl<'a> Iterator for Iter<'a> { 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 { diff --git a/src/setup_config.rs b/src/setup_config.rs index 175b7f1..7c03d38 100644 --- a/src/setup_config.rs +++ b/src/setup_config.rs @@ -15,7 +15,7 @@ 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}; @@ -155,7 +155,7 @@ interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) { }} 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); @@ -163,31 +163,44 @@ pub struct SetupConfiguration(ComPtr); impl SetupConfiguration { pub fn new() -> Result { 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 { 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 { 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 { let mut obj = null_mut(); let this = try!(self.0.cast::()); 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) }) } } @@ -202,28 +215,36 @@ impl SetupInstance { 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 { 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 { 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 { 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 { @@ -231,7 +252,9 @@ impl SetupInstance { let this = try!(self.0.cast::()); 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()) } } @@ -249,9 +272,12 @@ impl Iterator for EnumSetupInstances { fn next(&mut self) -> Option> { 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) })) } } - diff --git a/src/winapi.rs b/src/winapi.rs index 3fb0408..cc83963 100644 --- a/src/winapi.rs +++ b/src/winapi.rs @@ -44,8 +44,8 @@ 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)] @@ -69,13 +69,17 @@ pub trait Interface { #[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; } diff --git a/src/windows_registry.rs b/src/windows_registry.rs index f2b6593..cbd0f96 100644 --- a/src/windows_registry.rs +++ b/src/windows_registry.rs @@ -69,7 +69,11 @@ pub fn find_tool(target: &str, tool: &str) -> Option { // 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())); } @@ -119,19 +123,20 @@ pub fn find_vs_version() -> Result { 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. @@ -142,12 +147,14 @@ pub fn find_vs_version() -> Result { } 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\ + " + )) } } } @@ -185,7 +192,12 @@ mod impl_ { } 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); @@ -217,11 +229,13 @@ mod impl_ { None } - fn tool_from_vs15_instance(tool: &str, target: &str, - instance: &SetupInstance) -> Option { - 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 { + 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); @@ -238,9 +252,13 @@ mod impl_ { 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()); @@ -255,11 +273,15 @@ mod impl_ { 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)) @@ -288,7 +310,8 @@ mod impl_ { 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")); @@ -353,7 +376,8 @@ mod impl_ { 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 @@ -361,7 +385,12 @@ mod impl_ { fn get_tool(tool: &str, path: &Path, target: &str) -> Option { 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); @@ -402,16 +431,17 @@ mod impl_ { 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)) @@ -430,14 +460,17 @@ mod impl_ { 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::>(); 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)) @@ -555,7 +588,8 @@ mod impl_ { 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, @@ -574,15 +608,16 @@ mod impl_ { 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() - } - "12.0" | "14.0" => { - LOCAL_MACHINE.open( - &OsString::from(format!("SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}", - version))).is_ok() + find_msbuild_vs15("x86_64-pc-windows-msvc").is_some() + || find_msbuild_vs15("i686-pc-windows-msvc").is_some() } - _ => false + "12.0" | "14.0" => LOCAL_MACHINE + .open(&OsString::from(format!( + "SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}", + version + ))) + .is_ok(), + _ => false, } } @@ -601,11 +636,10 @@ mod impl_ { // 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); @@ -618,7 +652,8 @@ mod impl_ { fn find_old_msbuild(target: &str) -> Option { 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()) diff --git a/tests/support/mod.rs b/tests/support/mod.rs index bb56bf3..cae8151 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -85,7 +85,9 @@ impl Test { .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(), + } } } @@ -111,11 +113,18 @@ impl Execution { } 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 } diff --git a/tests/test.rs b/tests/test.rs index 7e5a28d..223bc6e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -8,9 +8,7 @@ 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") @@ -25,23 +23,15 @@ fn gnu_smoke() { #[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") @@ -54,10 +44,7 @@ fn gnu_opt_level_s() { #[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"); } @@ -81,8 +68,7 @@ fn gnu_warnings() { .file("foo.c") .compile("foo"); - test.cmd(0).must_have("-Wall") - .must_have("-Wextra"); + test.cmd(0).must_have("-Wall").must_have("-Wextra"); } #[test] @@ -94,7 +80,8 @@ fn gnu_warnings_overridable() { .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] @@ -108,9 +95,7 @@ fn gnu_x86_64() { .file("foo.c") .compile("foo"); - test.cmd(0) - .must_have("-fPIC") - .must_have("-m64"); + test.cmd(0).must_have("-fPIC").must_have("-m64"); } } @@ -141,8 +126,7 @@ fn gnu_i686() { .file("foo.c") .compile("foo"); - test.cmd(0) - .must_have("-m32"); + test.cmd(0).must_have("-m32"); } } @@ -176,10 +160,7 @@ fn gnu_set_stdlib() { #[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"); } @@ -199,9 +180,7 @@ fn gnu_define() { #[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"); } @@ -214,15 +193,13 @@ fn gnu_shared() { .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() @@ -241,7 +218,7 @@ fn gnu_flag_if_supported() { #[test] fn gnu_flag_if_supported_cpp() { if cfg!(windows) { - return + return; } let test = Test::gnu(); test.gcc() @@ -250,8 +227,7 @@ fn gnu_flag_if_supported_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] @@ -263,17 +239,13 @@ fn gnu_static() { .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") @@ -287,10 +259,7 @@ fn msvc_smoke() { #[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"); } @@ -298,20 +267,14 @@ fn msvc_opt_level_0() { #[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"); } @@ -331,10 +294,7 @@ fn msvc_define() { #[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"); } @@ -342,10 +302,7 @@ fn msvc_static_crt() { #[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"); }