Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
msvc.py1558 linesDownload Raw Back to setuptools
1"""2Environment info about Microsoft Compilers.3 4>>> getfixture('windows_only')5>>> ei = EnvironmentInfo('amd64')6"""7 8from __future__ import annotations9 10import contextlib11import itertools12import json13import os14import os.path15import platform16from typing import TYPE_CHECKING, TypedDict, overload17 18from more_itertools import unique_everseen19 20from ._path import StrPath21from .compat import py31022 23import distutils.errors24 25if TYPE_CHECKING:26    from typing_extensions import LiteralString, NotRequired27 28# https://github.com/python/mypy/issues/816629if not TYPE_CHECKING and platform.system() == 'Windows':30    import winreg31    from os import environ32else:33    # Mock winreg and environ so the module can be imported on this platform.34 35    class winreg:36        HKEY_USERS = None37        HKEY_CURRENT_USER = None38        HKEY_LOCAL_MACHINE = None39        HKEY_CLASSES_ROOT = None40 41    environ: dict[str, str] = dict()42 43 44class PlatformInfo:45    """46    Current and Target Architectures information.47 48    Parameters49    ----------50    arch: str51        Target architecture.52    """53 54    current_cpu = environ.get('processor_architecture', '').lower()55 56    def __init__(self, arch: str) -> None:57        self.arch = arch.lower().replace('x64', 'amd64')58 59    @property60    def target_cpu(self) -> str:61        """62        Return Target CPU architecture.63 64        Return65        ------66        str67            Target CPU68        """69        return self.arch[self.arch.find('_') + 1 :]70 71    def target_is_x86(self) -> bool:72        """73        Return True if target CPU is x86 32 bits..74 75        Return76        ------77        bool78            CPU is x86 32 bits79        """80        return self.target_cpu == 'x86'81 82    def current_is_x86(self) -> bool:83        """84        Return True if current CPU is x86 32 bits..85 86        Return87        ------88        bool89            CPU is x86 32 bits90        """91        return self.current_cpu == 'x86'92 93    def current_dir(self, hidex86=False, x64=False) -> str:94        """95        Current platform specific subfolder.96 97        Parameters98        ----------99        hidex86: bool100            return '' and not '\x86' if architecture is x86.101        x64: bool102            return '\x64' and not '\amd64' if architecture is amd64.103 104        Return105        ------106        str107            subfolder: '\target', or '' (see hidex86 parameter)108        """109        return (110            ''111            if (self.current_cpu == 'x86' and hidex86)112            else r'\x64'113            if (self.current_cpu == 'amd64' and x64)114            else rf'\{self.current_cpu}'115        )116 117    def target_dir(self, hidex86=False, x64=False) -> str:118        r"""119        Target platform specific subfolder.120 121        Parameters122        ----------123        hidex86: bool124            return '' and not '\x86' if architecture is x86.125        x64: bool126            return '\x64' and not '\amd64' if architecture is amd64.127 128        Return129        ------130        str131            subfolder: '\current', or '' (see hidex86 parameter)132        """133        return (134            ''135            if (self.target_cpu == 'x86' and hidex86)136            else r'\x64'137            if (self.target_cpu == 'amd64' and x64)138            else rf'\{self.target_cpu}'139        )140 141    def cross_dir(self, forcex86=False) -> str:142        r"""143        Cross platform specific subfolder.144 145        Parameters146        ----------147        forcex86: bool148            Use 'x86' as current architecture even if current architecture is149            not x86.150 151        Return152        ------153        str154            subfolder: '' if target architecture is current architecture,155            '\current_target' if not.156        """157        current = 'x86' if forcex86 else self.current_cpu158        return (159            ''160            if self.target_cpu == current161            else self.target_dir().replace('\\', f'\\{current}_')162        )163 164 165class RegistryInfo:166    """167    Microsoft Visual Studio related registry information.168 169    Parameters170    ----------171    platform_info: PlatformInfo172        "PlatformInfo" instance.173    """174 175    HKEYS = (176        winreg.HKEY_USERS,177        winreg.HKEY_CURRENT_USER,178        winreg.HKEY_LOCAL_MACHINE,179        winreg.HKEY_CLASSES_ROOT,180    )181 182    def __init__(self, platform_info: PlatformInfo) -> None:183        self.pi = platform_info184 185    @property186    def visualstudio(self) -> LiteralString:187        """188        Microsoft Visual Studio root registry key.189 190        Return191        ------192        str193            Registry key194        """195        return 'VisualStudio'196 197    @property198    def sxs(self) -> LiteralString:199        """200        Microsoft Visual Studio SxS registry key.201 202        Return203        ------204        str205            Registry key206        """207        return os.path.join(self.visualstudio, 'SxS')208 209    @property210    def vc(self) -> LiteralString:211        """212        Microsoft Visual C++ VC7 registry key.213 214        Return215        ------216        str217            Registry key218        """219        return os.path.join(self.sxs, 'VC7')220 221    @property222    def vs(self) -> LiteralString:223        """224        Microsoft Visual Studio VS7 registry key.225 226        Return227        ------228        str229            Registry key230        """231        return os.path.join(self.sxs, 'VS7')232 233    @property234    def vc_for_python(self) -> LiteralString:235        """236        Microsoft Visual C++ for Python registry key.237 238        Return239        ------240        str241            Registry key242        """243        return r'DevDiv\VCForPython'244 245    @property246    def microsoft_sdk(self) -> LiteralString:247        """248        Microsoft SDK registry key.249 250        Return251        ------252        str253            Registry key254        """255        return 'Microsoft SDKs'256 257    @property258    def windows_sdk(self) -> LiteralString:259        """260        Microsoft Windows/Platform SDK registry key.261 262        Return263        ------264        str265            Registry key266        """267        return os.path.join(self.microsoft_sdk, 'Windows')268 269    @property270    def netfx_sdk(self) -> LiteralString:271        """272        Microsoft .NET Framework SDK registry key.273 274        Return275        ------276        str277            Registry key278        """279        return os.path.join(self.microsoft_sdk, 'NETFXSDK')280 281    @property282    def windows_kits_roots(self) -> LiteralString:283        """284        Microsoft Windows Kits Roots registry key.285 286        Return287        ------288        str289            Registry key290        """291        return r'Windows Kits\Installed Roots'292 293    @overload294    def microsoft(self, key: LiteralString, x86: bool = False) -> LiteralString: ...295    @overload296    def microsoft(self, key: str, x86: bool = False) -> str: ...  # type: ignore[misc]297    def microsoft(self, key: str, x86: bool = False) -> str:298        """299        Return key in Microsoft software registry.300 301        Parameters302        ----------303        key: str304            Registry key path where look.305        x86: bool306            Force x86 software registry.307 308        Return309        ------310        str311            Registry key312        """313        node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node'314        return os.path.join('Software', node64, 'Microsoft', key)315 316    def lookup(self, key: str, name: str) -> str | None:317        """318        Look for values in registry in Microsoft software registry.319 320        Parameters321        ----------322        key: str323            Registry key path where look.324        name: str325            Value name to find.326 327        Return328        ------329        str | None330            value331        """332        key_read = winreg.KEY_READ333        openkey = winreg.OpenKey334        closekey = winreg.CloseKey335        ms = self.microsoft336        for hkey in self.HKEYS:337            bkey = None338            try:339                bkey = openkey(hkey, ms(key), 0, key_read)340            except OSError:341                if not self.pi.current_is_x86():342                    try:343                        bkey = openkey(hkey, ms(key, True), 0, key_read)344                    except OSError:345                        continue346                else:347                    continue348            try:349                return winreg.QueryValueEx(bkey, name)[0]350            except OSError:351                pass352            finally:353                if bkey:354                    closekey(bkey)355        return None356 357 358class SystemInfo:359    """360    Microsoft Windows and Visual Studio related system information.361 362    Parameters363    ----------364    registry_info: RegistryInfo365        "RegistryInfo" instance.366    vc_ver: float367        Required Microsoft Visual C++ version.368    """369 370    # Variables and properties in this class use originals CamelCase variables371    # names from Microsoft source files for more easy comparison.372    WinDir = environ.get('WinDir', '')373    ProgramFiles = environ.get('ProgramFiles', '')374    ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles)375 376    def __init__(377        self, registry_info: RegistryInfo, vc_ver: float | None = None378    ) -> None:379        self.ri = registry_info380        self.pi = self.ri.pi381 382        self.known_vs_paths = self.find_programdata_vs_vers()383 384        # Except for VS15+, VC version is aligned with VS version385        self.vs_ver = self.vc_ver = vc_ver or self._find_latest_available_vs_ver()386 387    def _find_latest_available_vs_ver(self):388        """389        Find the latest VC version390 391        Return392        ------393        float394            version395        """396        reg_vc_vers = self.find_reg_vs_vers()397 398        if not (reg_vc_vers or self.known_vs_paths):399            raise distutils.errors.DistutilsPlatformError(400                'No Microsoft Visual C++ version found'401            )402 403        vc_vers = set(reg_vc_vers)404        vc_vers.update(self.known_vs_paths)405        return max(vc_vers)406 407    def find_reg_vs_vers(self) -> list[float]:408        """409        Find Microsoft Visual Studio versions available in registry.410 411        Return412        ------413        list of float414            Versions415        """416        ms = self.ri.microsoft417        vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs)418        vs_vers = []419        for hkey, key in itertools.product(self.ri.HKEYS, vckeys):420            try:421                bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ)422            except OSError:423                continue424            with bkey:425                subkeys, values, _ = winreg.QueryInfoKey(bkey)426                for i in range(values):427                    with contextlib.suppress(ValueError):428                        ver = float(winreg.EnumValue(bkey, i)[0])429                        if ver not in vs_vers:430                            vs_vers.append(ver)431                for i in range(subkeys):432                    with contextlib.suppress(ValueError):433                        ver = float(winreg.EnumKey(bkey, i))434                        if ver not in vs_vers:435                            vs_vers.append(ver)436        return sorted(vs_vers)437 438    def find_programdata_vs_vers(self) -> dict[float, str]:439        r"""440        Find Visual studio 2017+ versions from information in441        "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances".442 443        Return444        ------445        dict446            float version as key, path as value.447        """448        vs_versions: dict[float, str] = {}449        instances_dir = r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances'450 451        try:452            hashed_names = os.listdir(instances_dir)453 454        except OSError:455            # Directory not exists with all Visual Studio versions456            return vs_versions457 458        for name in hashed_names:459            try:460                # Get VS installation path from "state.json" file461                state_path = os.path.join(instances_dir, name, 'state.json')462                with open(state_path, 'rt', encoding='utf-8') as state_file:463                    state = json.load(state_file)464                vs_path = state['installationPath']465 466                # Raises OSError if this VS installation does not contain VC467                os.listdir(os.path.join(vs_path, r'VC\Tools\MSVC'))468 469                # Store version and path470                vs_versions[self._as_float_version(state['installationVersion'])] = (471                    vs_path472                )473 474            except (OSError, KeyError):475                # Skip if "state.json" file is missing or bad format476                continue477 478        return vs_versions479 480    @staticmethod481    def _as_float_version(version):482        """483        Return a string version as a simplified float version (major.minor)484 485        Parameters486        ----------487        version: str488            Version.489 490        Return491        ------492        float493            version494        """495        return float('.'.join(version.split('.')[:2]))496 497    @property498    def VSInstallDir(self) -> str:499        """500        Microsoft Visual Studio directory.501 502        Return503        ------504        str505            path506        """507        # Default path508        default = os.path.join(509            self.ProgramFilesx86, f'Microsoft Visual Studio {self.vs_ver:0.1f}'510        )511 512        # Try to get path from registry, if fail use default path513        return self.ri.lookup(self.ri.vs, f'{self.vs_ver:0.1f}') or default514 515    @property516    def VCInstallDir(self) -> str:517        """518        Microsoft Visual C++ directory.519 520        Return521        ------522        str523            path524        """525        path = self._guess_vc() or self._guess_vc_legacy()526 527        if not os.path.isdir(path):528            msg = 'Microsoft Visual C++ directory not found'529            raise distutils.errors.DistutilsPlatformError(msg)530 531        return path532 533    def _guess_vc(self):534        """535        Locate Visual C++ for VS2017+.536 537        Return538        ------539        str540            path541        """542        if self.vs_ver <= 14.0:543            return ''544 545        try:546            # First search in known VS paths547            vs_dir = self.known_vs_paths[self.vs_ver]548        except KeyError:549            # Else, search with path from registry550            vs_dir = self.VSInstallDir551 552        guess_vc = os.path.join(vs_dir, r'VC\Tools\MSVC')553 554        # Subdir with VC exact version as name555        try:556            # Update the VC version with real one instead of VS version557            vc_ver = os.listdir(guess_vc)[-1]558            self.vc_ver = self._as_float_version(vc_ver)559            return os.path.join(guess_vc, vc_ver)560        except (OSError, IndexError):561            return ''562 563    def _guess_vc_legacy(self):564        """565        Locate Visual C++ for versions prior to 2017.566 567        Return568        ------569        str570            path571        """572        default = os.path.join(573            self.ProgramFilesx86,574            rf'Microsoft Visual Studio {self.vs_ver:0.1f}\VC',575        )576 577        # Try to get "VC++ for Python" path from registry as default path578        reg_path = os.path.join(self.ri.vc_for_python, f'{self.vs_ver:0.1f}')579        python_vc = self.ri.lookup(reg_path, 'installdir')580        default_vc = os.path.join(python_vc, 'VC') if python_vc else default581 582        # Try to get path from registry, if fail use default path583        return self.ri.lookup(self.ri.vc, f'{self.vs_ver:0.1f}') or default_vc584 585    @property586    def WindowsSdkVersion(self) -> tuple[LiteralString, ...]:587        """588        Microsoft Windows SDK versions for specified MSVC++ version.589 590        Return591        ------592        tuple of str593            versions594        """595        if self.vs_ver <= 9.0:596            return '7.0', '6.1', '6.0a'597        elif self.vs_ver == 10.0:598            return '7.1', '7.0a'599        elif self.vs_ver == 11.0:600            return '8.0', '8.0a'601        elif self.vs_ver == 12.0:602            return '8.1', '8.1a'603        elif self.vs_ver >= 14.0:604            return '10.0', '8.1'605        return ()606 607    @property608    def WindowsSdkLastVersion(self) -> str:609        """610        Microsoft Windows SDK last version.611 612        Return613        ------614        str615            version616        """617        return self._use_last_dir_name(os.path.join(self.WindowsSdkDir, 'lib'))618 619    @property620    def WindowsSdkDir(self) -> str:  # noqa: C901  # is too complex (12)  # FIXME621        """622        Microsoft Windows SDK directory.623 624        Return625        ------626        str627            path628        """629        sdkdir: str | None = ''630        for ver in self.WindowsSdkVersion:631            # Try to get it from registry632            loc = os.path.join(self.ri.windows_sdk, f'v{ver}')633            sdkdir = self.ri.lookup(loc, 'installationfolder')634            if sdkdir:635                break636        if not sdkdir or not os.path.isdir(sdkdir):637            # Try to get "VC++ for Python" version from registry638            path = os.path.join(self.ri.vc_for_python, f'{self.vc_ver:0.1f}')639            install_base = self.ri.lookup(path, 'installdir')640            if install_base:641                sdkdir = os.path.join(install_base, 'WinSDK')642        if not sdkdir or not os.path.isdir(sdkdir):643            # If fail, use default new path644            for ver in self.WindowsSdkVersion:645                intver = ver[: ver.rfind('.')]646                path = rf'Microsoft SDKs\Windows Kits\{intver}'647                d = os.path.join(self.ProgramFiles, path)648                if os.path.isdir(d):649                    sdkdir = d650        if not sdkdir or not os.path.isdir(sdkdir):651            # If fail, use default old path652            for ver in self.WindowsSdkVersion:653                path = rf'Microsoft SDKs\Windows\v{ver}'654                d = os.path.join(self.ProgramFiles, path)655                if os.path.isdir(d):656                    sdkdir = d657        if not sdkdir:658            # If fail, use Platform SDK659            sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK')660        return sdkdir661 662    @property663    def WindowsSDKExecutablePath(self) -> str | None:664        """665        Microsoft Windows SDK executable directory.666 667        Return668        ------669        str | None670            path671        """672        # Find WinSDK NetFx Tools registry dir name673        if self.vs_ver <= 11.0:674            netfxver = 35675            arch = ''676        else:677            netfxver = 40678            hidex86 = True if self.vs_ver <= 12.0 else False679            arch = self.pi.current_dir(x64=True, hidex86=hidex86).replace('\\', '-')680        fx = f'WinSDK-NetFx{netfxver}Tools{arch}'681 682        # list all possibles registry paths683        regpaths = []684        if self.vs_ver >= 14.0:685            for ver in self.NetFxSdkVersion:686                regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)]687 688        for ver in self.WindowsSdkVersion:689            regpaths += [os.path.join(self.ri.windows_sdk, f'v{ver}A', fx)]690 691        # Return installation folder from the more recent path692        for path in regpaths:693            execpath = self.ri.lookup(path, 'installationfolder')694            if execpath:695                return execpath696 697        return None698 699    @property700    def FSharpInstallDir(self) -> str:701        """702        Microsoft Visual F# directory.703 704        Return705        ------706        str707            path708        """709        path = os.path.join(self.ri.visualstudio, rf'{self.vs_ver:0.1f}\Setup\F#')710        return self.ri.lookup(path, 'productdir') or ''711 712    @property713    def UniversalCRTSdkDir(self) -> str | None:714        """715        Microsoft Universal CRT SDK directory.716 717        Return718        ------719        str | None720            path721        """722        # Set Kit Roots versions for specified MSVC++ version723        vers = ('10', '81') if self.vs_ver >= 14.0 else ()724 725        # Find path of the more recent Kit726        for ver in vers:727            sdkdir = self.ri.lookup(self.ri.windows_kits_roots, f'kitsroot{ver}')728            if sdkdir:729                return sdkdir730 731        return None732 733    @property734    def UniversalCRTSdkLastVersion(self) -> str:735        """736        Microsoft Universal C Runtime SDK last version.737 738        Return739        ------740        str741            version742        """743        try:744            return self._use_last_dir_name(os.path.join(self.UniversalCRTSdkDir, 'lib'))  # type: ignore[arg-type] # Expected TypeError745        except TypeError as ex:746            py310.add_note(ex, "Cannot find UniversalCRTSdkDir")747            raise748 749    @property750    def NetFxSdkVersion(self) -> tuple[LiteralString, ...]:751        """752        Microsoft .NET Framework SDK versions.753 754        Return755        ------756        tuple of str757            versions758        """759        # Set FxSdk versions for specified VS version760        return (761            ('4.7.2', '4.7.1', '4.7', '4.6.2', '4.6.1', '4.6', '4.5.2', '4.5.1', '4.5')762            if self.vs_ver >= 14.0763            else ()764        )765 766    @property767    def NetFxSdkDir(self) -> str | None:768        """769        Microsoft .NET Framework SDK directory.770 771        Return772        ------773        str | None774            path775        """776        sdkdir: str | None = ''777        for ver in self.NetFxSdkVersion:778            loc = os.path.join(self.ri.netfx_sdk, ver)779            sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder')780            if sdkdir:781                break782        return sdkdir783 784    @property785    def FrameworkDir32(self) -> str:786        """787        Microsoft .NET Framework 32bit directory.788 789        Return790        ------791        str792            path793        """794        # Default path795        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework')796 797        # Try to get path from registry, if fail use default path798        return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw799 800    @property801    def FrameworkDir64(self) -> str:802        """803        Microsoft .NET Framework 64bit directory.804 805        Return806        ------807        str808            path809        """810        # Default path811        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework64')812 813        # Try to get path from registry, if fail use default path814        return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw815 816    @property817    def FrameworkVersion32(self) -> tuple[str, ...]:818        """819        Microsoft .NET Framework 32bit versions.820 821        Return822        ------823        tuple of str824            versions825        """826        return self._find_dot_net_versions(32)827 828    @property829    def FrameworkVersion64(self) -> tuple[str, ...]:830        """831        Microsoft .NET Framework 64bit versions.832 833        Return834        ------835        tuple of str836            versions837        """838        return self._find_dot_net_versions(64)839 840    def _find_dot_net_versions(self, bits) -> tuple[str, ...]:841        """842        Find Microsoft .NET Framework versions.843 844        Parameters845        ----------846        bits: int847            Platform number of bits: 32 or 64.848 849        Return850        ------851        tuple of str852            versions853        """854        # Find actual .NET version in registry855        reg_ver = self.ri.lookup(self.ri.vc, f'frameworkver{bits}')856        dot_net_dir = getattr(self, f'FrameworkDir{bits}')857        ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or ''858 859        # Set .NET versions for specified MSVC++ version860        if self.vs_ver >= 12.0:861            return ver, 'v4.0'862        elif self.vs_ver >= 10.0:863            return 'v4.0.30319' if ver.lower()[:2] != 'v4' else ver, 'v3.5'864        elif self.vs_ver == 9.0:865            return 'v3.5', 'v2.0.50727'866        elif self.vs_ver == 8.0:867            return 'v3.0', 'v2.0.50727'868        return ()869 870    @staticmethod871    def _use_last_dir_name(path: StrPath, prefix: str = '') -> str:872        """873        Return name of the last dir in path or '' if no dir found.874 875        Parameters876        ----------877        path: StrPath878            Use dirs in this path879        prefix: str880            Use only dirs starting by this prefix881 882        Return883        ------884        str885            name886        """887        matching_dirs = (888            dir_name889            for dir_name in reversed(os.listdir(path))890            if os.path.isdir(os.path.join(path, dir_name))891            and dir_name.startswith(prefix)892        )893        return next(matching_dirs, '')894 895 896class _EnvironmentDict(TypedDict):897    include: str898    lib: str899    libpath: str900    path: str901    py_vcruntime_redist: NotRequired[str | None]902 903 904class EnvironmentInfo:905    """906    Return environment variables for specified Microsoft Visual C++ version907    and platform : Lib, Include, Path and libpath.908 909    This function is compatible with Microsoft Visual C++ 9.0 to 14.X.910 911    Script created by analysing Microsoft environment configuration files like912    "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ...913 914    Parameters915    ----------916    arch: str917        Target architecture.918    vc_ver: float919        Required Microsoft Visual C++ version. If not set, autodetect the last920        version.921    vc_min_ver: float922        Minimum Microsoft Visual C++ version.923    """924 925    # Variables and properties in this class use originals CamelCase variables926    # names from Microsoft source files for more easy comparison.927 928    def __init__(self, arch, vc_ver=None, vc_min_ver=0) -> None:929        self.pi = PlatformInfo(arch)930        self.ri = RegistryInfo(self.pi)931        self.si = SystemInfo(self.ri, vc_ver)932 933        if self.vc_ver < vc_min_ver:934            err = 'No suitable Microsoft Visual C++ version found'935            raise distutils.errors.DistutilsPlatformError(err)936 937    @property938    def vs_ver(self):939        """940        Microsoft Visual Studio.941 942        Return943        ------944        float945            version946        """947        return self.si.vs_ver948 949    @property950    def vc_ver(self):951        """952        Microsoft Visual C++ version.953 954        Return955        ------956        float957            version958        """959        return self.si.vc_ver960 961    @property962    def VSTools(self):963        """964        Microsoft Visual Studio Tools.965 966        Return967        ------968        list of str969            paths970        """971        paths = [r'Common7\IDE', r'Common7\Tools']972 973        if self.vs_ver >= 14.0:974            arch_subdir = self.pi.current_dir(hidex86=True, x64=True)975            paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow']976            paths += [r'Team Tools\Performance Tools']977            paths += [rf'Team Tools\Performance Tools{arch_subdir}']978 979        return [os.path.join(self.si.VSInstallDir, path) for path in paths]980 981    @property982    def VCIncludes(self):983        """984        Microsoft Visual C++ & Microsoft Foundation Class Includes.985 986        Return987        ------988        list of str989            paths990        """991        return [992            os.path.join(self.si.VCInstallDir, 'Include'),993            os.path.join(self.si.VCInstallDir, r'ATLMFC\Include'),994        ]995 996    @property997    def VCLibraries(self):998        """999        Microsoft Visual C++ & Microsoft Foundation Class Libraries.1000 1001        Return1002        ------1003        list of str1004            paths1005        """1006        if self.vs_ver >= 15.0:1007            arch_subdir = self.pi.target_dir(x64=True)1008        else:1009            arch_subdir = self.pi.target_dir(hidex86=True)1010        paths = [f'Lib{arch_subdir}', rf'ATLMFC\Lib{arch_subdir}']1011 1012        if self.vs_ver >= 14.0:1013            paths += [rf'Lib\store{arch_subdir}']1014 1015        return [os.path.join(self.si.VCInstallDir, path) for path in paths]1016 1017    @property1018    def VCStoreRefs(self):1019        """1020        Microsoft Visual C++ store references Libraries.1021 1022        Return1023        ------1024        list of str1025            paths1026        """1027        if self.vs_ver < 14.0:1028            return []1029        return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')]1030 1031    @property1032    def VCTools(self):1033        """1034        Microsoft Visual C++ Tools.1035 1036        Return1037        ------1038        list of str1039            paths1040 1041        When host CPU is ARM, the tools should be found for ARM.1042 1043        >>> getfixture('windows_only')1044        >>> mp = getfixture('monkeypatch')1045        >>> mp.setattr(PlatformInfo, 'current_cpu', 'arm64')1046        >>> ei = EnvironmentInfo(arch='irrelevant')1047        >>> paths = ei.VCTools1048        >>> any('HostARM64' in path for path in paths)1049        True1050        """1051        si = self.si1052        tools = [os.path.join(si.VCInstallDir, 'VCPackages')]1053 1054        forcex86 = True if self.vs_ver <= 10.0 else False1055        arch_subdir = self.pi.cross_dir(forcex86)1056        if arch_subdir:1057            tools += [os.path.join(si.VCInstallDir, f'Bin{arch_subdir}')]1058 1059        if self.vs_ver == 14.0:1060            path = f'Bin{self.pi.current_dir(hidex86=True)}'1061            tools += [os.path.join(si.VCInstallDir, path)]1062 1063        elif self.vs_ver >= 15.0:1064            host_id = self.pi.current_cpu.replace('amd64', 'x64').upper()1065            host_dir = os.path.join('bin', f'Host{host_id}%s')1066            tools += [1067                os.path.join(si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))1068            ]1069 1070            if self.pi.current_cpu != self.pi.target_cpu:1071                tools += [1072                    os.path.join(1073                        si.VCInstallDir, host_dir % self.pi.current_dir(x64=True)1074                    )1075                ]1076 1077        else:1078            tools += [os.path.join(si.VCInstallDir, 'Bin')]1079 1080        return tools1081 1082    @property1083    def OSLibraries(self):1084        """1085        Microsoft Windows SDK Libraries.1086 1087        Return1088        ------1089        list of str1090            paths1091        """1092        if self.vs_ver <= 10.0:1093            arch_subdir = self.pi.target_dir(hidex86=True, x64=True)1094            return [os.path.join(self.si.WindowsSdkDir, f'Lib{arch_subdir}')]1095 1096        else:1097            arch_subdir = self.pi.target_dir(x64=True)1098            lib = os.path.join(self.si.WindowsSdkDir, 'lib')1099            libver = self._sdk_subdir1100            return [os.path.join(lib, f'{libver}um{arch_subdir}')]1101 1102    @property1103    def OSIncludes(self):1104        """1105        Microsoft Windows SDK Include.1106 1107        Return1108        ------1109        list of str1110            paths1111        """1112        include = os.path.join(self.si.WindowsSdkDir, 'include')1113 1114        if self.vs_ver <= 10.0:1115            return [include, os.path.join(include, 'gl')]1116 1117        else:1118            if self.vs_ver >= 14.0:1119                sdkver = self._sdk_subdir1120            else:1121                sdkver = ''1122            return [1123                os.path.join(include, f'{sdkver}shared'),1124                os.path.join(include, f'{sdkver}um'),1125                os.path.join(include, f'{sdkver}winrt'),1126            ]1127 1128    @property1129    def OSLibpath(self):1130        """1131        Microsoft Windows SDK Libraries Paths.1132 1133        Return1134        ------1135        list of str1136            paths1137        """1138        ref = os.path.join(self.si.WindowsSdkDir, 'References')1139        libpath = []1140 1141        if self.vs_ver <= 9.0:1142            libpath += self.OSLibraries1143 1144        if self.vs_ver >= 11.0:1145            libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')]1146 1147        if self.vs_ver >= 14.0:1148            libpath += [1149                ref,1150                os.path.join(self.si.WindowsSdkDir, 'UnionMetadata'),1151                os.path.join(ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'),1152                os.path.join(ref, 'Windows.Foundation.FoundationContract', '1.0.0.0'),1153                os.path.join(1154                    ref, 'Windows.Networking.Connectivity.WwanContract', '1.0.0.0'1155                ),1156                os.path.join(1157                    self.si.WindowsSdkDir,1158                    'ExtensionSDKs',1159                    'Microsoft.VCLibs',1160                    f'{self.vs_ver:0.1f}',1161                    'References',1162                    'CommonConfiguration',1163                    'neutral',1164                ),1165            ]1166        return libpath1167 1168    @property1169    def SdkTools(self):1170        """1171        Microsoft Windows SDK Tools.1172 1173        Return1174        ------1175        list of str1176            paths1177        """1178        return list(self._sdk_tools())1179 1180    def _sdk_tools(self):1181        """1182        Microsoft Windows SDK Tools paths generator.1183 1184        Return1185        ------1186        generator of str1187            paths1188        """1189        if self.vs_ver < 15.0:1190            bin_dir = 'Bin' if self.vs_ver <= 11.0 else r'Bin\x86'1191            yield os.path.join(self.si.WindowsSdkDir, bin_dir)1192 1193        if not self.pi.current_is_x86():1194            arch_subdir = self.pi.current_dir(x64=True)1195            path = f'Bin{arch_subdir}'1196            yield os.path.join(self.si.WindowsSdkDir, path)1197 1198        if self.vs_ver in (10.0, 11.0):1199            if self.pi.target_is_x86():1200                arch_subdir = ''

Showing the first 1,200 of 1558 lines. Download the file for the rest.