1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use anyhow::{anyhow, Result};
#[cfg(target_family = "windows")]
use std::path::PathBuf;
pub fn target_arch_to_windows_sdk_platform_path() -> Result<&'static str> {
if cfg!(target_arch = "x86") {
Ok("x86")
} else if cfg!(target_arch = "x86_64") {
Ok("x64")
} else if cfg!(target_arch = "arm") {
Ok("arm")
} else if cfg!(target_arch = "aarch64") {
Ok("arm64")
} else {
Err(anyhow!("target architecture not supported on Windows"))
}
}
#[cfg(target_family = "windows")]
pub fn find_windows_sdk_current_arch_bin_path(
version: Option<find_winsdk::SdkVersion>,
) -> Result<PathBuf> {
let sdk_info = find_winsdk::SdkInfo::find(version.unwrap_or(find_winsdk::SdkVersion::Any))?
.ok_or_else(|| anyhow!("could not locate Windows SDK"))?;
let bin_path = sdk_info.installation_folder().join("bin");
let candidates = [
sdk_info.product_version().to_string(),
format!("{}.0", sdk_info.product_version()),
];
let version_path = candidates
.iter()
.filter_map(|p| {
let p = bin_path.join(p);
if p.exists() {
Some(p)
} else {
None
}
})
.next()
.ok_or_else(|| anyhow!("could not locate Windows SDK version path"))?;
let arch_path = version_path.join(target_arch_to_windows_sdk_platform_path()?);
if arch_path.exists() {
Ok(arch_path)
} else {
Err(anyhow!("{} does not exist", arch_path.display()))
}
}
#[cfg(test)]
mod tests {
#[cfg(target_family = "windows")]
use super::*;
#[cfg(target_family = "windows")]
#[test]
pub fn test_find_windows_sdk_current_arch_bin_path() -> Result<()> {
find_windows_sdk_current_arch_bin_path(None)?;
Ok(())
}
}