Source

pypy / pypy / translator / cli / sdk.py

Full commit
Antonio Cuni 52bbfe7 



































Amaury Forgeot d… 0bf8e32 










Antonio Cuni 52bbfe7 





Amaury Forgeot d… 0bf8e32 











Antonio Cuni 52bbfe7 







































Christian Tismer 1f574b5 




Antonio Cuni 52bbfe7 



import os.path
import platform
import py

class AbstractSDK(object):
    def _check_helper(cls, helper):
        if py.path.local.sysfind(helper) is None:
            py.test.skip("%s is not on your path." % helper)
        else:
            return helper
    _check_helper = classmethod(_check_helper)

    def runtime(cls):
        for item in cls.RUNTIME:
            cls._check_helper(item)
        return cls.RUNTIME
    runtime = classmethod(runtime)

    def ilasm(cls):
        return cls._check_helper(cls.ILASM)
    ilasm = classmethod(ilasm)

    def csc(cls):
        return cls._check_helper(cls.CSC)
    csc = classmethod(csc)

    def peverify(cls):
        return cls._check_helper(cls.PEVERIFY)
    peverify = classmethod(peverify)

class MicrosoftSDK(AbstractSDK):
    RUNTIME = []
    ILASM = 'ilasm'    
    CSC = 'csc'
    PEVERIFY = 'peverify'

def get_mono_version():
    from commands import getoutput
    lines = getoutput('mono -V').splitlines()
    parts = lines[0].split()
    # something like ['Mono', 'JIT', 'compiler', 'version', '2.4.2.3', ...]
    iversion = parts.index('version')
    ver = parts[iversion+1]     # '2.4.2.3'
    ver = ver.split('.')        # ['2', '4', '2', '3']
    return tuple(map(int, ver)) # (2, 4, 2, 3)


class MonoSDK(AbstractSDK):
    RUNTIME = ['mono']
    ILASM = 'ilasm2'
    CSC = 'gmcs'
    PEVERIFY = 'peverify' # it's not part of mono, but we get a meaningful skip message

    # this is a workaround for this bug:
    # https://bugzilla.novell.com/show_bug.cgi?id=474718 they promised that it
    # should be fixed in versions after 2.4.3.x, in the meanwhile pass
    # -O=-branch
    @classmethod
    def runtime(cls):
        cls._check_helper('mono')
        ver = get_mono_version()
        if (2, 1) < ver < (2, 4, 3):
            return ['mono', '-O=-branch']
        return ['mono']

def key_as_dict(handle):
    import _winreg
    i = 0
    res = {}
    while True:
        try:
            name, value, type_ = _winreg.EnumValue(handle, i)
            res[name] = value
            i += 1
        except WindowsError:
            break
    return res

def find_mono_on_windows():
    if platform.system() != 'Windows':
        return None
    import _winreg
    try:
        hMono = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Novell\\Mono")
    except WindowsError: # mono seems not installed
        return None

    mono = key_as_dict(hMono)
    mono_version = mono.get('DefaultCLR', None)
    if mono_version is None:
        return None
    hMono.Close()

    hMono_data = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Novell\\Mono\\%s" % mono_version)
    mono_data = key_as_dict(hMono_data)
    mono_dir = str(mono_data['SdkInstallRoot'])
    return os.path.join(mono_dir, 'bin')

def get_default_SDK():
    if platform.system() == 'Windows':
        SDK = MicrosoftSDK
        # if present, use mono ilasm2 instead of MS ilasm
        mono_bin = find_mono_on_windows()
        if mono_bin is not None:
            SDK.ILASM = os.path.join(mono_bin, 'ilasm2.bat')
        # XXX the failing tests are boring, and the SDK is usually installed
        # on windows. I do not care right now, because the Linux buildbots
        # don't test this at all...
        if platform.architecture()[0] == '64bit':
            py.test.skip('mono on 64bit is not well enough supported')
    else:
        SDK = MonoSDK
    return SDK

SDK = get_default_SDK()