Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
msvc.py1743 linesDownload Raw Back to setuptools
1"""2Improved support for Microsoft Visual C++ compilers.3 4Known supported compilers:5--------------------------6Microsoft Visual C++ 14.X:7    Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)8    Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)9    Microsoft Visual Studio Build Tools 2019 (x86, x64, arm, arm64)10 11This may also support compilers shipped with compatible Visual Studio versions.12"""13 14import json15from os import listdir, pathsep16from os.path import join, isfile, isdir, dirname17from subprocess import CalledProcessError18import contextlib19import platform20import itertools21import subprocess22import distutils.errors23from typing import Dict, TYPE_CHECKING24from setuptools.extern.more_itertools import unique_everseen25 26# https://github.com/python/mypy/issues/816627if not TYPE_CHECKING and platform.system() == 'Windows':28    import winreg29    from os import environ30else:31    # Mock winreg and environ so the module can be imported on this platform.32 33    class winreg:34        HKEY_USERS = None35        HKEY_CURRENT_USER = None36        HKEY_LOCAL_MACHINE = None37        HKEY_CLASSES_ROOT = None38 39    environ: Dict[str, str] = dict()40 41 42def _msvc14_find_vc2015():43    """Python 3.8 "distutils/_msvccompiler.py" backport"""44    try:45        key = winreg.OpenKey(46            winreg.HKEY_LOCAL_MACHINE,47            r"Software\Microsoft\VisualStudio\SxS\VC7",48            0,49            winreg.KEY_READ | winreg.KEY_WOW64_32KEY,50        )51    except OSError:52        return None, None53 54    best_version = 055    best_dir = None56    with key:57        for i in itertools.count():58            try:59                v, vc_dir, vt = winreg.EnumValue(key, i)60            except OSError:61                break62            if v and vt == winreg.REG_SZ and isdir(vc_dir):63                try:64                    version = int(float(v))65                except (ValueError, TypeError):66                    continue67                if version >= 14 and version > best_version:68                    best_version, best_dir = version, vc_dir69    return best_version, best_dir70 71 72def _msvc14_find_vc2017():73    """Python 3.8 "distutils/_msvccompiler.py" backport74 75    Returns "15, path" based on the result of invoking vswhere.exe76    If no install is found, returns "None, None"77 78    The version is returned to avoid unnecessarily changing the function79    result. It may be ignored when the path is not None.80 81    If vswhere.exe is not available, by definition, VS 2017 is not82    installed.83    """84    root = environ.get("ProgramFiles(x86)") or environ.get("ProgramFiles")85    if not root:86        return None, None87 88    suitable_components = (89        "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",90        "Microsoft.VisualStudio.Workload.WDExpress",91    )92 93    for component in suitable_components:94        # Workaround for `-requiresAny` (only available on VS 2017 > 15.6)95        with contextlib.suppress(CalledProcessError, OSError, UnicodeDecodeError):96            path = (97                subprocess.check_output([98                    join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"),99                    "-latest",100                    "-prerelease",101                    "-requires",102                    component,103                    "-property",104                    "installationPath",105                    "-products",106                    "*",107                ])108                .decode(encoding="mbcs", errors="strict")109                .strip()110            )111 112            path = join(path, "VC", "Auxiliary", "Build")113            if isdir(path):114                return 15, path115 116    return None, None  # no suitable component found117 118 119PLAT_SPEC_TO_RUNTIME = {120    'x86': 'x86',121    'x86_amd64': 'x64',122    'x86_arm': 'arm',123    'x86_arm64': 'arm64',124}125 126 127def _msvc14_find_vcvarsall(plat_spec):128    """Python 3.8 "distutils/_msvccompiler.py" backport"""129    _, best_dir = _msvc14_find_vc2017()130    vcruntime = None131 132    if plat_spec in PLAT_SPEC_TO_RUNTIME:133        vcruntime_plat = PLAT_SPEC_TO_RUNTIME[plat_spec]134    else:135        vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86'136 137    if best_dir:138        vcredist = join(139            best_dir,140            "..",141            "..",142            "redist",143            "MSVC",144            "**",145            vcruntime_plat,146            "Microsoft.VC14*.CRT",147            "vcruntime140.dll",148        )149        try:150            import glob151 152            vcruntime = glob.glob(vcredist, recursive=True)[-1]153        except (ImportError, OSError, LookupError):154            vcruntime = None155 156    if not best_dir:157        best_version, best_dir = _msvc14_find_vc2015()158        if best_version:159            vcruntime = join(160                best_dir,161                'redist',162                vcruntime_plat,163                "Microsoft.VC140.CRT",164                "vcruntime140.dll",165            )166 167    if not best_dir:168        return None, None169 170    vcvarsall = join(best_dir, "vcvarsall.bat")171    if not isfile(vcvarsall):172        return None, None173 174    if not vcruntime or not isfile(vcruntime):175        vcruntime = None176 177    return vcvarsall, vcruntime178 179 180def _msvc14_get_vc_env(plat_spec):181    """Python 3.8 "distutils/_msvccompiler.py" backport"""182    if "DISTUTILS_USE_SDK" in environ:183        return {key.lower(): value for key, value in environ.items()}184 185    vcvarsall, vcruntime = _msvc14_find_vcvarsall(plat_spec)186    if not vcvarsall:187        raise distutils.errors.DistutilsPlatformError("Unable to find vcvarsall.bat")188 189    try:190        out = subprocess.check_output(191            'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec),192            stderr=subprocess.STDOUT,193        ).decode('utf-16le', errors='replace')194    except subprocess.CalledProcessError as exc:195        raise distutils.errors.DistutilsPlatformError(196            "Error executing {}".format(exc.cmd)197        ) from exc198 199    env = {200        key.lower(): value201        for key, _, value in (line.partition('=') for line in out.splitlines())202        if key and value203    }204 205    if vcruntime:206        env['py_vcruntime_redist'] = vcruntime207    return env208 209 210def msvc14_get_vc_env(plat_spec):211    """212    Patched "distutils._msvccompiler._get_vc_env" for support extra213    Microsoft Visual C++ 14.X compilers.214 215    Set environment without use of "vcvarsall.bat".216 217    Parameters218    ----------219    plat_spec: str220        Target architecture.221 222    Return223    ------224    dict225        environment226    """227 228    # Always use backport from CPython 3.8229    try:230        return _msvc14_get_vc_env(plat_spec)231    except distutils.errors.DistutilsPlatformError as exc:232        _augment_exception(exc, 14.0)233        raise234 235 236def _augment_exception(exc, version, arch=''):237    """238    Add details to the exception message to help guide the user239    as to what action will resolve it.240    """241    # Error if MSVC++ directory not found or environment not set242    message = exc.args[0]243 244    if "vcvarsall" in message.lower() or "visual c" in message.lower():245        # Special error message if MSVC++ not installed246        tmpl = 'Microsoft Visual C++ {version:0.1f} or greater is required.'247        message = tmpl.format(**locals())248        msdownload = 'www.microsoft.com/download/details.aspx?id=%d'249        if version == 9.0:250            if arch.lower().find('ia64') > -1:251                # For VC++ 9.0, if IA64 support is needed, redirect user252                # to Windows SDK 7.0.253                # Note: No download link available from Microsoft.254                message += ' Get it with "Microsoft Windows SDK 7.0"'255            else:256                # For VC++ 9.0 redirect user to Vc++ for Python 2.7 :257                # This redirection link is maintained by Microsoft.258                # Contact vspython@microsoft.com if it needs updating.259                message += ' Get it from http://aka.ms/vcpython27'260        elif version == 10.0:261            # For VC++ 10.0 Redirect user to Windows SDK 7.1262            message += ' Get it with "Microsoft Windows SDK 7.1": '263            message += msdownload % 8279264        elif version >= 14.0:265            # For VC++ 14.X Redirect user to latest Visual C++ Build Tools266            message += (267                ' Get it with "Microsoft C++ Build Tools": '268                r'https://visualstudio.microsoft.com'269                r'/visual-cpp-build-tools/'270            )271 272    exc.args = (message,)273 274 275class PlatformInfo:276    """277    Current and Target Architectures information.278 279    Parameters280    ----------281    arch: str282        Target architecture.283    """284 285    current_cpu = environ.get('processor_architecture', '').lower()286 287    def __init__(self, arch):288        self.arch = arch.lower().replace('x64', 'amd64')289 290    @property291    def target_cpu(self):292        """293        Return Target CPU architecture.294 295        Return296        ------297        str298            Target CPU299        """300        return self.arch[self.arch.find('_') + 1 :]301 302    def target_is_x86(self):303        """304        Return True if target CPU is x86 32 bits..305 306        Return307        ------308        bool309            CPU is x86 32 bits310        """311        return self.target_cpu == 'x86'312 313    def current_is_x86(self):314        """315        Return True if current CPU is x86 32 bits..316 317        Return318        ------319        bool320            CPU is x86 32 bits321        """322        return self.current_cpu == 'x86'323 324    def current_dir(self, hidex86=False, x64=False):325        """326        Current platform specific subfolder.327 328        Parameters329        ----------330        hidex86: bool331            return '' and not '\x86' if architecture is x86.332        x64: bool333            return '\x64' and not '\amd64' if architecture is amd64.334 335        Return336        ------337        str338            subfolder: '\target', or '' (see hidex86 parameter)339        """340        return (341            ''342            if (self.current_cpu == 'x86' and hidex86)343            else r'\x64'344            if (self.current_cpu == 'amd64' and x64)345            else r'\%s' % self.current_cpu346        )347 348    def target_dir(self, hidex86=False, x64=False):349        r"""350        Target platform specific subfolder.351 352        Parameters353        ----------354        hidex86: bool355            return '' and not '\x86' if architecture is x86.356        x64: bool357            return '\x64' and not '\amd64' if architecture is amd64.358 359        Return360        ------361        str362            subfolder: '\current', or '' (see hidex86 parameter)363        """364        return (365            ''366            if (self.target_cpu == 'x86' and hidex86)367            else r'\x64'368            if (self.target_cpu == 'amd64' and x64)369            else r'\%s' % self.target_cpu370        )371 372    def cross_dir(self, forcex86=False):373        r"""374        Cross platform specific subfolder.375 376        Parameters377        ----------378        forcex86: bool379            Use 'x86' as current architecture even if current architecture is380            not x86.381 382        Return383        ------384        str385            subfolder: '' if target architecture is current architecture,386            '\current_target' if not.387        """388        current = 'x86' if forcex86 else self.current_cpu389        return (390            ''391            if self.target_cpu == current392            else self.target_dir().replace('\\', '\\%s_' % current)393        )394 395 396class RegistryInfo:397    """398    Microsoft Visual Studio related registry information.399 400    Parameters401    ----------402    platform_info: PlatformInfo403        "PlatformInfo" instance.404    """405 406    HKEYS = (407        winreg.HKEY_USERS,408        winreg.HKEY_CURRENT_USER,409        winreg.HKEY_LOCAL_MACHINE,410        winreg.HKEY_CLASSES_ROOT,411    )412 413    def __init__(self, platform_info):414        self.pi = platform_info415 416    @property417    def visualstudio(self):418        """419        Microsoft Visual Studio root registry key.420 421        Return422        ------423        str424            Registry key425        """426        return 'VisualStudio'427 428    @property429    def sxs(self):430        """431        Microsoft Visual Studio SxS registry key.432 433        Return434        ------435        str436            Registry key437        """438        return join(self.visualstudio, 'SxS')439 440    @property441    def vc(self):442        """443        Microsoft Visual C++ VC7 registry key.444 445        Return446        ------447        str448            Registry key449        """450        return join(self.sxs, 'VC7')451 452    @property453    def vs(self):454        """455        Microsoft Visual Studio VS7 registry key.456 457        Return458        ------459        str460            Registry key461        """462        return join(self.sxs, 'VS7')463 464    @property465    def vc_for_python(self):466        """467        Microsoft Visual C++ for Python registry key.468 469        Return470        ------471        str472            Registry key473        """474        return r'DevDiv\VCForPython'475 476    @property477    def microsoft_sdk(self):478        """479        Microsoft SDK registry key.480 481        Return482        ------483        str484            Registry key485        """486        return 'Microsoft SDKs'487 488    @property489    def windows_sdk(self):490        """491        Microsoft Windows/Platform SDK registry key.492 493        Return494        ------495        str496            Registry key497        """498        return join(self.microsoft_sdk, 'Windows')499 500    @property501    def netfx_sdk(self):502        """503        Microsoft .NET Framework SDK registry key.504 505        Return506        ------507        str508            Registry key509        """510        return join(self.microsoft_sdk, 'NETFXSDK')511 512    @property513    def windows_kits_roots(self):514        """515        Microsoft Windows Kits Roots registry key.516 517        Return518        ------519        str520            Registry key521        """522        return r'Windows Kits\Installed Roots'523 524    def microsoft(self, key, x86=False):525        """526        Return key in Microsoft software registry.527 528        Parameters529        ----------530        key: str531            Registry key path where look.532        x86: str533            Force x86 software registry.534 535        Return536        ------537        str538            Registry key539        """540        node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node'541        return join('Software', node64, 'Microsoft', key)542 543    def lookup(self, key, name):544        """545        Look for values in registry in Microsoft software registry.546 547        Parameters548        ----------549        key: str550            Registry key path where look.551        name: str552            Value name to find.553 554        Return555        ------556        str557            value558        """559        key_read = winreg.KEY_READ560        openkey = winreg.OpenKey561        closekey = winreg.CloseKey562        ms = self.microsoft563        for hkey in self.HKEYS:564            bkey = None565            try:566                bkey = openkey(hkey, ms(key), 0, key_read)567            except OSError:568                if not self.pi.current_is_x86():569                    try:570                        bkey = openkey(hkey, ms(key, True), 0, key_read)571                    except OSError:572                        continue573                else:574                    continue575            try:576                return winreg.QueryValueEx(bkey, name)[0]577            except OSError:578                pass579            finally:580                if bkey:581                    closekey(bkey)582        return None583 584 585class SystemInfo:586    """587    Microsoft Windows and Visual Studio related system information.588 589    Parameters590    ----------591    registry_info: RegistryInfo592        "RegistryInfo" instance.593    vc_ver: float594        Required Microsoft Visual C++ version.595    """596 597    # Variables and properties in this class use originals CamelCase variables598    # names from Microsoft source files for more easy comparison.599    WinDir = environ.get('WinDir', '')600    ProgramFiles = environ.get('ProgramFiles', '')601    ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles)602 603    def __init__(self, registry_info, vc_ver=None):604        self.ri = registry_info605        self.pi = self.ri.pi606 607        self.known_vs_paths = self.find_programdata_vs_vers()608 609        # Except for VS15+, VC version is aligned with VS version610        self.vs_ver = self.vc_ver = vc_ver or self._find_latest_available_vs_ver()611 612    def _find_latest_available_vs_ver(self):613        """614        Find the latest VC version615 616        Return617        ------618        float619            version620        """621        reg_vc_vers = self.find_reg_vs_vers()622 623        if not (reg_vc_vers or self.known_vs_paths):624            raise distutils.errors.DistutilsPlatformError(625                'No Microsoft Visual C++ version found'626            )627 628        vc_vers = set(reg_vc_vers)629        vc_vers.update(self.known_vs_paths)630        return sorted(vc_vers)[-1]631 632    def find_reg_vs_vers(self):633        """634        Find Microsoft Visual Studio versions available in registry.635 636        Return637        ------638        list of float639            Versions640        """641        ms = self.ri.microsoft642        vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs)643        vs_vers = []644        for hkey, key in itertools.product(self.ri.HKEYS, vckeys):645            try:646                bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ)647            except OSError:648                continue649            with bkey:650                subkeys, values, _ = winreg.QueryInfoKey(bkey)651                for i in range(values):652                    with contextlib.suppress(ValueError):653                        ver = float(winreg.EnumValue(bkey, i)[0])654                        if ver not in vs_vers:655                            vs_vers.append(ver)656                for i in range(subkeys):657                    with contextlib.suppress(ValueError):658                        ver = float(winreg.EnumKey(bkey, i))659                        if ver not in vs_vers:660                            vs_vers.append(ver)661        return sorted(vs_vers)662 663    def find_programdata_vs_vers(self):664        r"""665        Find Visual studio 2017+ versions from information in666        "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances".667 668        Return669        ------670        dict671            float version as key, path as value.672        """673        vs_versions = {}674        instances_dir = r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances'675 676        try:677            hashed_names = listdir(instances_dir)678 679        except OSError:680            # Directory not exists with all Visual Studio versions681            return vs_versions682 683        for name in hashed_names:684            try:685                # Get VS installation path from "state.json" file686                state_path = join(instances_dir, name, 'state.json')687                with open(state_path, 'rt', encoding='utf-8') as state_file:688                    state = json.load(state_file)689                vs_path = state['installationPath']690 691                # Raises OSError if this VS installation does not contain VC692                listdir(join(vs_path, r'VC\Tools\MSVC'))693 694                # Store version and path695                vs_versions[self._as_float_version(state['installationVersion'])] = (696                    vs_path697                )698 699            except (OSError, KeyError):700                # Skip if "state.json" file is missing or bad format701                continue702 703        return vs_versions704 705    @staticmethod706    def _as_float_version(version):707        """708        Return a string version as a simplified float version (major.minor)709 710        Parameters711        ----------712        version: str713            Version.714 715        Return716        ------717        float718            version719        """720        return float('.'.join(version.split('.')[:2]))721 722    @property723    def VSInstallDir(self):724        """725        Microsoft Visual Studio directory.726 727        Return728        ------729        str730            path731        """732        # Default path733        default = join(734            self.ProgramFilesx86, 'Microsoft Visual Studio %0.1f' % self.vs_ver735        )736 737        # Try to get path from registry, if fail use default path738        return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default739 740    @property741    def VCInstallDir(self):742        """743        Microsoft Visual C++ directory.744 745        Return746        ------747        str748            path749        """750        path = self._guess_vc() or self._guess_vc_legacy()751 752        if not isdir(path):753            msg = 'Microsoft Visual C++ directory not found'754            raise distutils.errors.DistutilsPlatformError(msg)755 756        return path757 758    def _guess_vc(self):759        """760        Locate Visual C++ for VS2017+.761 762        Return763        ------764        str765            path766        """767        if self.vs_ver <= 14.0:768            return ''769 770        try:771            # First search in known VS paths772            vs_dir = self.known_vs_paths[self.vs_ver]773        except KeyError:774            # Else, search with path from registry775            vs_dir = self.VSInstallDir776 777        guess_vc = join(vs_dir, r'VC\Tools\MSVC')778 779        # Subdir with VC exact version as name780        try:781            # Update the VC version with real one instead of VS version782            vc_ver = listdir(guess_vc)[-1]783            self.vc_ver = self._as_float_version(vc_ver)784            return join(guess_vc, vc_ver)785        except (OSError, IndexError):786            return ''787 788    def _guess_vc_legacy(self):789        """790        Locate Visual C++ for versions prior to 2017.791 792        Return793        ------794        str795            path796        """797        default = join(798            self.ProgramFilesx86, r'Microsoft Visual Studio %0.1f\VC' % self.vs_ver799        )800 801        # Try to get "VC++ for Python" path from registry as default path802        reg_path = join(self.ri.vc_for_python, '%0.1f' % self.vs_ver)803        python_vc = self.ri.lookup(reg_path, 'installdir')804        default_vc = join(python_vc, 'VC') if python_vc else default805 806        # Try to get path from registry, if fail use default path807        return self.ri.lookup(self.ri.vc, '%0.1f' % self.vs_ver) or default_vc808 809    @property810    def WindowsSdkVersion(self):811        """812        Microsoft Windows SDK versions for specified MSVC++ version.813 814        Return815        ------816        tuple of str817            versions818        """819        if self.vs_ver <= 9.0:820            return '7.0', '6.1', '6.0a'821        elif self.vs_ver == 10.0:822            return '7.1', '7.0a'823        elif self.vs_ver == 11.0:824            return '8.0', '8.0a'825        elif self.vs_ver == 12.0:826            return '8.1', '8.1a'827        elif self.vs_ver >= 14.0:828            return '10.0', '8.1'829        return None830 831    @property832    def WindowsSdkLastVersion(self):833        """834        Microsoft Windows SDK last version.835 836        Return837        ------838        str839            version840        """841        return self._use_last_dir_name(join(self.WindowsSdkDir, 'lib'))842 843    @property  # noqa: C901844    def WindowsSdkDir(self):  # noqa: C901  # is too complex (12)  # FIXME845        """846        Microsoft Windows SDK directory.847 848        Return849        ------850        str851            path852        """853        sdkdir = ''854        for ver in self.WindowsSdkVersion:855            # Try to get it from registry856            loc = join(self.ri.windows_sdk, 'v%s' % ver)857            sdkdir = self.ri.lookup(loc, 'installationfolder')858            if sdkdir:859                break860        if not sdkdir or not isdir(sdkdir):861            # Try to get "VC++ for Python" version from registry862            path = join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)863            install_base = self.ri.lookup(path, 'installdir')864            if install_base:865                sdkdir = join(install_base, 'WinSDK')866        if not sdkdir or not isdir(sdkdir):867            # If fail, use default new path868            for ver in self.WindowsSdkVersion:869                intver = ver[: ver.rfind('.')]870                path = r'Microsoft SDKs\Windows Kits\%s' % intver871                d = join(self.ProgramFiles, path)872                if isdir(d):873                    sdkdir = d874        if not sdkdir or not isdir(sdkdir):875            # If fail, use default old path876            for ver in self.WindowsSdkVersion:877                path = r'Microsoft SDKs\Windows\v%s' % ver878                d = join(self.ProgramFiles, path)879                if isdir(d):880                    sdkdir = d881        if not sdkdir:882            # If fail, use Platform SDK883            sdkdir = join(self.VCInstallDir, 'PlatformSDK')884        return sdkdir885 886    @property887    def WindowsSDKExecutablePath(self):888        """889        Microsoft Windows SDK executable directory.890 891        Return892        ------893        str894            path895        """896        # Find WinSDK NetFx Tools registry dir name897        if self.vs_ver <= 11.0:898            netfxver = 35899            arch = ''900        else:901            netfxver = 40902            hidex86 = True if self.vs_ver <= 12.0 else False903            arch = self.pi.current_dir(x64=True, hidex86=hidex86)904        fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-'))905 906        # list all possibles registry paths907        regpaths = []908        if self.vs_ver >= 14.0:909            for ver in self.NetFxSdkVersion:910                regpaths += [join(self.ri.netfx_sdk, ver, fx)]911 912        for ver in self.WindowsSdkVersion:913            regpaths += [join(self.ri.windows_sdk, 'v%sA' % ver, fx)]914 915        # Return installation folder from the more recent path916        for path in regpaths:917            execpath = self.ri.lookup(path, 'installationfolder')918            if execpath:919                return execpath920 921        return None922 923    @property924    def FSharpInstallDir(self):925        """926        Microsoft Visual F# directory.927 928        Return929        ------930        str931            path932        """933        path = join(self.ri.visualstudio, r'%0.1f\Setup\F#' % self.vs_ver)934        return self.ri.lookup(path, 'productdir') or ''935 936    @property937    def UniversalCRTSdkDir(self):938        """939        Microsoft Universal CRT SDK directory.940 941        Return942        ------943        str944            path945        """946        # Set Kit Roots versions for specified MSVC++ version947        vers = ('10', '81') if self.vs_ver >= 14.0 else ()948 949        # Find path of the more recent Kit950        for ver in vers:951            sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot%s' % ver)952            if sdkdir:953                return sdkdir or ''954 955        return None956 957    @property958    def UniversalCRTSdkLastVersion(self):959        """960        Microsoft Universal C Runtime SDK last version.961 962        Return963        ------964        str965            version966        """967        return self._use_last_dir_name(join(self.UniversalCRTSdkDir, 'lib'))968 969    @property970    def NetFxSdkVersion(self):971        """972        Microsoft .NET Framework SDK versions.973 974        Return975        ------976        tuple of str977            versions978        """979        # Set FxSdk versions for specified VS version980        return (981            ('4.7.2', '4.7.1', '4.7', '4.6.2', '4.6.1', '4.6', '4.5.2', '4.5.1', '4.5')982            if self.vs_ver >= 14.0983            else ()984        )985 986    @property987    def NetFxSdkDir(self):988        """989        Microsoft .NET Framework SDK directory.990 991        Return992        ------993        str994            path995        """996        sdkdir = ''997        for ver in self.NetFxSdkVersion:998            loc = join(self.ri.netfx_sdk, ver)999            sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder')1000            if sdkdir:1001                break1002        return sdkdir1003 1004    @property1005    def FrameworkDir32(self):1006        """1007        Microsoft .NET Framework 32bit directory.1008 1009        Return1010        ------1011        str1012            path1013        """1014        # Default path1015        guess_fw = join(self.WinDir, r'Microsoft.NET\Framework')1016 1017        # Try to get path from registry, if fail use default path1018        return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw1019 1020    @property1021    def FrameworkDir64(self):1022        """1023        Microsoft .NET Framework 64bit directory.1024 1025        Return1026        ------1027        str1028            path1029        """1030        # Default path1031        guess_fw = join(self.WinDir, r'Microsoft.NET\Framework64')1032 1033        # Try to get path from registry, if fail use default path1034        return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw1035 1036    @property1037    def FrameworkVersion32(self):1038        """1039        Microsoft .NET Framework 32bit versions.1040 1041        Return1042        ------1043        tuple of str1044            versions1045        """1046        return self._find_dot_net_versions(32)1047 1048    @property1049    def FrameworkVersion64(self):1050        """1051        Microsoft .NET Framework 64bit versions.1052 1053        Return1054        ------1055        tuple of str1056            versions1057        """1058        return self._find_dot_net_versions(64)1059 1060    def _find_dot_net_versions(self, bits):1061        """1062        Find Microsoft .NET Framework versions.1063 1064        Parameters1065        ----------1066        bits: int1067            Platform number of bits: 32 or 64.1068 1069        Return1070        ------1071        tuple of str1072            versions1073        """1074        # Find actual .NET version in registry1075        reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits)1076        dot_net_dir = getattr(self, 'FrameworkDir%d' % bits)1077        ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or ''1078 1079        # Set .NET versions for specified MSVC++ version1080        if self.vs_ver >= 12.0:1081            return ver, 'v4.0'1082        elif self.vs_ver >= 10.0:1083            return 'v4.0.30319' if ver.lower()[:2] != 'v4' else ver, 'v3.5'1084        elif self.vs_ver == 9.0:1085            return 'v3.5', 'v2.0.50727'1086        elif self.vs_ver == 8.0:1087            return 'v3.0', 'v2.0.50727'1088 1089    @staticmethod1090    def _use_last_dir_name(path, prefix=''):1091        """1092        Return name of the last dir in path or '' if no dir found.1093 1094        Parameters1095        ----------1096        path: str1097            Use dirs in this path1098        prefix: str1099            Use only dirs starting by this prefix1100 1101        Return1102        ------1103        str1104            name1105        """1106        matching_dirs = (1107            dir_name1108            for dir_name in reversed(listdir(path))1109            if isdir(join(path, dir_name)) and dir_name.startswith(prefix)1110        )1111        return next(matching_dirs, None) or ''1112 1113 1114class EnvironmentInfo:1115    """1116    Return environment variables for specified Microsoft Visual C++ version1117    and platform : Lib, Include, Path and libpath.1118 1119    This function is compatible with Microsoft Visual C++ 9.0 to 14.X.1120 1121    Script created by analysing Microsoft environment configuration files like1122    "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ...1123 1124    Parameters1125    ----------1126    arch: str1127        Target architecture.1128    vc_ver: float1129        Required Microsoft Visual C++ version. If not set, autodetect the last1130        version.1131    vc_min_ver: float1132        Minimum Microsoft Visual C++ version.1133    """1134 1135    # Variables and properties in this class use originals CamelCase variables1136    # names from Microsoft source files for more easy comparison.1137 1138    def __init__(self, arch, vc_ver=None, vc_min_ver=0):1139        self.pi = PlatformInfo(arch)1140        self.ri = RegistryInfo(self.pi)1141        self.si = SystemInfo(self.ri, vc_ver)1142 1143        if self.vc_ver < vc_min_ver:1144            err = 'No suitable Microsoft Visual C++ version found'1145            raise distutils.errors.DistutilsPlatformError(err)1146 1147    @property1148    def vs_ver(self):1149        """1150        Microsoft Visual Studio.1151 1152        Return1153        ------1154        float1155            version1156        """1157        return self.si.vs_ver1158 1159    @property1160    def vc_ver(self):1161        """1162        Microsoft Visual C++ version.1163 1164        Return1165        ------1166        float1167            version1168        """1169        return self.si.vc_ver1170 1171    @property1172    def VSTools(self):1173        """1174        Microsoft Visual Studio Tools.1175 1176        Return1177        ------1178        list of str1179            paths1180        """1181        paths = [r'Common7\IDE', r'Common7\Tools']1182 1183        if self.vs_ver >= 14.0:1184            arch_subdir = self.pi.current_dir(hidex86=True, x64=True)1185            paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow']1186            paths += [r'Team Tools\Performance Tools']1187            paths += [r'Team Tools\Performance Tools%s' % arch_subdir]1188 1189        return [join(self.si.VSInstallDir, path) for path in paths]1190 1191    @property1192    def VCIncludes(self):1193        """1194        Microsoft Visual C++ & Microsoft Foundation Class Includes.1195 1196        Return1197        ------1198        list of str1199            paths1200        """

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

codekingpro/portable-devtools · Team Ai