diff --git a/src/windows_registry.rs b/src/windows_registry.rs index 5af3ff73b..700100d37 100644 --- a/src/windows_registry.rs +++ b/src/windows_registry.rs @@ -80,7 +80,7 @@ pub fn find_tool(target: &str, tool: &str) -> Option { // environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that // the tool is actually usable. - return impl_::find_msvc_15(tool, target) + return impl_::find_msvc_15plus(tool, target) .or_else(|| impl_::find_msvc_14(tool, target)) .or_else(|| impl_::find_msvc_12(tool, target)) .or_else(|| impl_::find_msvc_11(tool, target)); @@ -210,7 +210,7 @@ mod impl_ { #[allow(bare_trait_objects)] fn vs16_instances() -> Box> { - let instances = if let Some(instances) = vs15_instances() { + let instances = if let Some(instances) = vs15plus_instances() { instances } else { return Box::new(iter::empty()); @@ -253,24 +253,34 @@ mod impl_ { // Note that much of this logic can be found [online] wrt paths, COM, etc. // // [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/ - fn vs15_instances() -> Option { + // + // Returns MSVC 15+ instances (15, 16 right now), the order should be consider undefined. + fn vs15plus_instances() -> Option { com::initialize().ok()?; let config = SetupConfiguration::new().ok()?; config.enum_all_instances().ok() } - pub fn find_msvc_15(tool: &str, target: &str) -> Option { - let iter = vs15_instances()?; + pub fn find_msvc_15plus(tool: &str, target: &str) -> Option { + let iter = vs15plus_instances()?; + let mut best = None; for instance in iter { let instance = instance.ok()?; + let installation_name = instance.installation_name().ok()?; let tool = tool_from_vs15_instance(tool, target, &instance); - if tool.is_some() { - return tool; - } + best = match (tool, best) { + (Some(tool), None) => Some((installation_name, tool)), + (Some(tool), Some((best_installation_name, _))) + if best_installation_name < installation_name => + { + Some((installation_name, tool)) + } + _ => None, + }; } - None + best.map(|(_installation_name, tool)| tool) } // While the paths to Visual Studio 2017's devenv and MSBuild could @@ -281,7 +291,7 @@ mod impl_ { // // [more reliable]: https://github.com/alexcrichton/cc-rs/pull/331 fn find_tool_in_vs15_path(tool: &str, target: &str) -> Option { - let mut path = match vs15_instances() { + let mut path = match vs15plus_instances() { Some(instances) => instances .filter_map(|instance| { instance