diff --git a/src/windows_registry.rs b/src/windows_registry.rs index 00040289..863d710b 100644 --- a/src/windows_registry.rs +++ b/src/windows_registry.rs @@ -454,30 +454,34 @@ mod impl_ { ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf, PathBuf)> { let version = vs15plus_vc_read_version(instance_path)?; - let host = match host_arch() { - X86 => "X86", - X86_64 => "X64", - // There is no natively hosted compiler on ARM64. - // Instead, use the x86 toolchain under emulation (there is no x64 emulation). - AARCH64 => "X86", + let hosts = match host_arch() { + X86 => vec!["X86"], + X86_64 => vec!["X64"], + // Starting with VS 17.3, there is a natively hosted compiler on ARM64. + // On older versions of VS, we use the x86 toolchain under emulation. + // We don't want to overcomplicate compatibility checks, so we ignore x64 emulation. + AARCH64 => vec!["ARM64", "X86"], _ => return None, }; let target = lib_subdir(target)?; // The directory layout here is MSVC/bin/Host$host/$target/ let path = instance_path.join(r"VC\Tools\MSVC").join(version); + // We use the first available host architecture that can build for the target + let (host_path, host) = hosts.iter().find_map(|&x| { + let candidate = path.join("bin").join(&format!("Host{}", x)); + if candidate.join(&target).exists() { + Some((candidate, x)) + } else { + None + } + })?; // 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 = host_path.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 = host_path.join(&host.to_lowercase()); let lib_path = path.join("lib").join(&target); let include_path = path.join("include"); Some((path, bin_path, host_dylib_path, lib_path, include_path))