-
Notifications
You must be signed in to change notification settings - Fork 6
/
winenv.py
140 lines (112 loc) · 5.11 KB
/
winenv.py
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import json
from operator import attrgetter
import os
from pathlib import Path
import platform
import subprocess
from typing import Optional
if platform.system() == "Windows":
import winreg
from .machine_spec import MachineSpec
cached_msvs_dir = None
cached_msvc_dir = None
cached_winsdk = None
def detect_msvs_installation_dir(toolchain_prefix: Optional[Path]) -> Path:
global cached_msvs_dir
if cached_msvs_dir is None:
vswhere = Path(os.environ.get("ProgramFiles(x86)", os.environ["ProgramFiles"])) \
/ "Microsoft Visual Studio" / "Installer" / "vswhere.exe"
if not vswhere.exists():
if toolchain_prefix is None:
raise MissingDependencyError("unable to locate vswhere.exe")
vswhere = toolchain_prefix / "bin" / "vswhere.exe"
installations = json.loads(
subprocess.run([
vswhere,
"-latest",
"-format", "json",
"-property", "installationPath"
],
capture_output=True,
encoding="utf-8",
check=True).stdout
)
if len(installations) == 0:
raise MissingDependencyError("Visual Studio is not installed")
cached_msvs_dir = Path(installations[0]["installationPath"])
return cached_msvs_dir
def detect_msvc_tool_dir(toolchain_prefix: Optional[Path]) -> Path:
global cached_msvc_dir
if cached_msvc_dir is None:
msvs_dir = detect_msvs_installation_dir(toolchain_prefix)
version = sorted((msvs_dir / "VC" / "Tools" / "MSVC").glob("*.*.*"),
key=attrgetter("name"),
reverse=True)[0].name
cached_msvc_dir = msvs_dir / "VC" / "Tools" / "MSVC" / version
return cached_msvc_dir
def detect_windows_sdk() -> tuple[Path, str]:
global cached_winsdk
if cached_winsdk is None:
try:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows Kits\Installed Roots")
try:
(install_dir, _) = winreg.QueryValueEx(key, "KitsRoot10")
install_dir = Path(install_dir)
version = sorted((install_dir / "Include").glob("*.*.*"),
key=attrgetter("name"),
reverse=True)[0].name
cached_winsdk = (install_dir, version)
finally:
winreg.CloseKey(key)
except Exception as e:
raise MissingDependencyError("Windows 10 SDK is not installed")
return cached_winsdk
def detect_msvs_tool_path(machine: MachineSpec,
build_machine: MachineSpec,
tool: str,
toolchain_prefix: Optional[Path]) -> Path:
return detect_msvc_tool_dir(toolchain_prefix) / "bin" / f"Host{build_machine.msvc_platform}" \
/ machine.msvc_platform / tool
def detect_msvs_runtime_path(machine: MachineSpec,
build_machine: MachineSpec,
toolchain_prefix: Optional[Path]) -> list[Path]:
msvc_platform = machine.msvc_platform
native_msvc_platform = build_machine.msvc_platform
msvc_dir = detect_msvc_tool_dir(toolchain_prefix)
msvc_bindir = msvc_dir / "bin" / f"Host{native_msvc_platform}" / msvc_platform
msvc_dll_dirs = []
if msvc_platform != native_msvc_platform:
msvc_dll_dirs.append(msvc_dir / "bin" / f"Host{native_msvc_platform}" / native_msvc_platform)
(winsdk_dir, winsdk_version) = detect_windows_sdk()
winsdk_bindir = winsdk_dir / "Bin" / winsdk_version / msvc_platform
return [winsdk_bindir, msvc_bindir] + msvc_dll_dirs
def detect_msvs_include_path(toolchain_prefix: Optional[Path]) -> list[Path]:
msvc_dir = detect_msvc_tool_dir(toolchain_prefix)
vc_dir = detect_msvs_installation_dir(toolchain_prefix) / "VC"
(winsdk_dir, winsdk_version) = detect_windows_sdk()
winsdk_inc_dirs = [
winsdk_dir / "Include" / winsdk_version / "um",
winsdk_dir / "Include" / winsdk_version / "shared",
]
return [
msvc_dir / "include",
msvc_dir / "atlmfc" / "include",
vc_dir / "Auxiliary" / "VS" / "include",
winsdk_dir / "Include" / winsdk_version / "ucrt",
] + winsdk_inc_dirs
def detect_msvs_library_path(machine: MachineSpec,
toolchain_prefix: Optional[Path]) -> list[Path]:
msvc_platform = machine.msvc_platform
msvc_dir = detect_msvc_tool_dir(toolchain_prefix)
vc_dir = detect_msvs_installation_dir(toolchain_prefix) / "VC"
(winsdk_dir, winsdk_version) = detect_windows_sdk()
winsdk_lib_dir = winsdk_dir / "Lib" / winsdk_version / "um" / msvc_platform
return [
msvc_dir / "lib" / msvc_platform,
msvc_dir / "atlmfc" / "lib" / msvc_platform,
vc_dir / "Auxiliary" / "VS" / "lib" / msvc_platform,
winsdk_dir / "Lib" / winsdk_version / "ucrt" / msvc_platform,
winsdk_lib_dir,
]
class MissingDependencyError(Exception):
pass