aboutsummaryrefslogtreecommitdiff
path: root/cc/src/windows_registry.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cc/src/windows_registry.rs')
-rw-r--r--cc/src/windows_registry.rs186
1 files changed, 124 insertions, 62 deletions
diff --git a/cc/src/windows_registry.rs b/cc/src/windows_registry.rs
index 9099e0f..bbcbb09 100644
--- a/cc/src/windows_registry.rs
+++ b/cc/src/windows_registry.rs
@@ -65,11 +65,19 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
return impl_::find_msbuild(target);
}
+ if tool.contains("devenv") {
+ return impl_::find_devenv(target);
+ }
+
// If VCINSTALLDIR is set, then someone's probably already run vcvars and we
// should just find whatever that indicates.
if env::var_os("VCINSTALLDIR").is_some() {
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 +127,20 @@ 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.
@@ -142,12 +151,14 @@ pub fn find_vs_version() -> Result<VsVers, String> {
} 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 +196,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 +233,13 @@ mod impl_ {
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);
@@ -238,9 +256,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 +277,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 +314,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"));
@@ -302,6 +329,7 @@ mod impl_ {
tool.libs.push(sdk_lib.join("um").join(sub));
let sdk_include = sdk.join("include").join(&version);
tool.include.push(sdk_include.join("um"));
+ tool.include.push(sdk_include.join("cppwinrt"));
tool.include.push(sdk_include.join("winrt"));
tool.include.push(sdk_include.join("shared"));
} else if let Some(sdk) = get_sdk81_dir() {
@@ -353,7 +381,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 +390,12 @@ mod impl_ {
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);
@@ -402,16 +436,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 +465,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::<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))
@@ -485,8 +523,8 @@ mod impl_ {
("i586", X86_64) | ("i686", X86_64) => vec![("amd64_x86", "amd64"), ("", "")],
("x86_64", X86) => vec![("x86_amd64", "")],
("x86_64", X86_64) => vec![("amd64", "amd64"), ("x86_amd64", "")],
- ("arm", X86) => vec![("x86_arm", "")],
- ("arm", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
+ ("arm", X86) | ("thumbv7a", X86) => vec![("x86_arm", "")],
+ ("arm", X86_64) | ("thumbv7a", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
_ => vec![],
}
}
@@ -496,7 +534,8 @@ mod impl_ {
match arch {
"i586" | "i686" => Some("x86"),
"x86_64" => Some("x64"),
- "arm" => Some("arm"),
+ "arm" | "thumbv7a" => Some("arm"),
+ "aarch64" => Some("arm64"),
_ => None,
}
}
@@ -507,7 +546,8 @@ mod impl_ {
match arch {
"i586" | "i686" => Some(""),
"x86_64" => Some("amd64"),
- "arm" => Some("arm"),
+ "arm" | "thumbv7a" => Some("arm"),
+ "aarch64" => Some("arm64"),
_ => None,
}
}
@@ -553,7 +593,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,
@@ -572,18 +613,39 @@ 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,
}
}
+ pub fn find_devenv(target: &str) -> Option<Tool> {
+ find_devenv_vs15(&target)
+ }
+
+ fn find_devenv_vs15(target: &str) -> Option<Tool> {
+ let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7";
+ LOCAL_MACHINE
+ .open(key.as_ref())
+ .ok()
+ .and_then(|key| key.query_str("15.0").ok())
+ .map(|path| {
+ let path = PathBuf::from(path).join(r"Common7\IDE\devenv.exe");
+ let mut tool = Tool::new(path);
+ if target.contains("x86_64") {
+ tool.env.push(("Platform".into(), "X64".into()));
+ }
+ tool
+ })
+ }
+
// see http://stackoverflow.com/questions/328017/path-to-msbuild
pub fn find_msbuild(target: &str) -> Option<Tool> {
// VS 15 (2017) changed how to locate msbuild
@@ -599,11 +661,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);
@@ -616,7 +677,8 @@ mod impl_ {
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())