Files
releng/winenv.py
T

141 lines
5.1 KiB
Python

import json
from operator import attrgetter
import os
from pathlib import Path
import platform
import subprocess
from typing import List, Optional, Tuple
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