Skip to content

Commit 98c5bc1

Browse files
committed
fix find_tool and find_vs_version might returrs incompatible values
On my PC, I have both MSVC 15 and 16 and found out that find_vs_version returns MSVC 16 while find_tool return MSVC 15 linker
1 parent 383f2df commit 98c5bc1

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/windows_registry.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
8080
// environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that
8181
// the tool is actually usable.
8282

83-
return impl_::find_msvc_15(tool, target)
83+
return impl_::find_msvc_15plus(tool, target)
8484
.or_else(|| impl_::find_msvc_14(tool, target))
8585
.or_else(|| impl_::find_msvc_12(tool, target))
8686
.or_else(|| impl_::find_msvc_11(tool, target));
@@ -210,7 +210,7 @@ mod impl_ {
210210

211211
#[allow(bare_trait_objects)]
212212
fn vs16_instances() -> Box<Iterator<Item = PathBuf>> {
213-
let instances = if let Some(instances) = vs15_instances() {
213+
let instances = if let Some(instances) = vs15plus_instances() {
214214
instances
215215
} else {
216216
return Box::new(iter::empty());
@@ -253,24 +253,36 @@ mod impl_ {
253253
// Note that much of this logic can be found [online] wrt paths, COM, etc.
254254
//
255255
// [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/
256-
fn vs15_instances() -> Option<EnumSetupInstances> {
256+
//
257+
// Returns MSVC 15+ instances (15, 16 right now), the order should be consider undefined.
258+
fn vs15plus_instances() -> Option<EnumSetupInstances> {
257259
com::initialize().ok()?;
258260

259261
let config = SetupConfiguration::new().ok()?;
260262
config.enum_all_instances().ok()
261263
}
262264

263-
pub fn find_msvc_15(tool: &str, target: &str) -> Option<Tool> {
264-
let iter = vs15_instances()?;
265+
pub fn find_msvc_15plus(tool: &str, target: &str) -> Option<Tool> {
266+
let iter = vs15plus_instances()?;
267+
let mut best = None;
265268
for instance in iter {
266269
let instance = instance.ok()?;
270+
let installation_name = instance.installation_name().ok()?;
267271
let tool = tool_from_vs15_instance(tool, target, &instance);
268-
if tool.is_some() {
269-
return tool;
270-
}
272+
best = match (tool, best) {
273+
(Some(tool), None) => Some((installation_name, tool)),
274+
(Some(tool), Some((best_installation_name, _))) => {
275+
if best_installation_name < installation_name {
276+
Some((installation_name, tool))
277+
} else {
278+
None
279+
}
280+
}
281+
_ => None,
282+
};
271283
}
272284

273-
None
285+
best.map(|(_installation_name, tool)| tool)
274286
}
275287

276288
// While the paths to Visual Studio 2017's devenv and MSBuild could
@@ -281,7 +293,7 @@ mod impl_ {
281293
//
282294
// [more reliable]: https://github.com/alexcrichton/cc-rs/pull/331
283295
fn find_tool_in_vs15_path(tool: &str, target: &str) -> Option<Tool> {
284-
let mut path = match vs15_instances() {
296+
let mut path = match vs15plus_instances() {
285297
Some(instances) => instances
286298
.filter_map(|instance| {
287299
instance

0 commit comments

Comments
 (0)