1# -*- coding: utf-8 -*- 2 3import os 4import platform 5 6try: 7 import _winreg 8except: 9 _winreg = None 10 11class BuildConfig: 12 def __init__ (self, buildDir, buildType, args): 13 self.buildDir = buildDir 14 self.buildType = buildType 15 self.args = args 16 17 def getBuildDir (self): 18 return self.buildDir 19 20 def getBuildType (self): 21 return self.buildType 22 23 def getArgs (self): 24 return self.args 25 26class CMakeGenerator: 27 def __init__ (self, name, isMultiConfig = False): 28 self.name = name 29 self.isMultiConfig = isMultiConfig 30 31 def getName (self): 32 return self.name 33 34 def getGenerateArgs (self, buildType): 35 args = ['-G', self.name] 36 if not self.isMultiConfig: 37 args.append('-DCMAKE_BUILD_TYPE=%s' % buildType) 38 return args 39 40 def getBuildArgs (self, buildType): 41 args = [] 42 if self.isMultiConfig: 43 args += ['--config', buildType] 44 return args 45 46 def getBinaryPath (self, buildType, basePath): 47 return basePath 48 49class DefaultGenerator(CMakeGenerator): 50 def __init__(self): 51 CMakeGenerator.__init__("default") 52 53 def getGenerateArgs (self, buildType): 54 args = [] 55 if not self.isMultiConfig: 56 args.append('-DCMAKE_BUILD_TYPE=%s' % buildType) 57 return args 58 59class VSProjectGenerator(CMakeGenerator): 60 ARCH_32BIT = 0 61 ARCH_64BIT = 1 62 63 def __init__(self, version, arch): 64 name = "Visual Studio %d" % version 65 if arch == self.ARCH_64BIT: 66 name += " Win64" 67 68 CMakeGenerator.__init__(self, name, isMultiConfig = True) 69 self.version = version 70 self.arch = arch 71 72 def getBuildArgs (self, buildType): 73 return CMakeGenerator.getBuildArgs(self, buildType) + ['--', '/m'] 74 75 def getBinaryPath (self, buildType, basePath): 76 return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe") 77 78 @staticmethod 79 def getNativeArch (): 80 arch = platform.machine().lower() 81 82 if arch == 'x86': 83 return VSProjectGenerator.ARCH_32BIT 84 elif arch == 'amd64': 85 return VSProjectGenerator.ARCH_64BIT 86 else: 87 raise Exception("Unhandled arch '%s'" % arch) 88 89 @staticmethod 90 def registryKeyAvailable (root, arch, name): 91 try: 92 key = _winreg.OpenKey(root, name, 0, _winreg.KEY_READ | arch) 93 _winreg.CloseKey(key) 94 return True 95 except: 96 return False 97 98 def isAvailable (self): 99 if _winreg != None: 100 nativeArch = VSProjectGenerator.getNativeArch() 101 if nativeArch == self.ARCH_32BIT and self.arch == self.ARCH_64BIT: 102 return False 103 104 arch = _winreg.KEY_WOW64_32KEY if nativeArch == self.ARCH_64BIT else 0 105 keyMap = { 106 10: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.10.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\10.0")], 107 11: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.11.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\11.0")], 108 12: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.12.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\12.0")], 109 } 110 111 if not self.version in keyMap: 112 raise Exception("Unsupported VS version %d" % self.version) 113 114 keys = keyMap[self.version] 115 for root, name in keys: 116 if VSProjectGenerator.registryKeyAvailable(root, arch, name): 117 return True 118 return False 119 else: 120 return False 121 122 @staticmethod 123 def getDefault (arch): 124 for version in reversed(range(10, 13)): 125 gen = VSProjectGenerator(version, arch) 126 if gen.isAvailable(): 127 return gen 128 return None 129 130# Pre-defined generators 131 132MAKEFILE_GENERATOR = CMakeGenerator("Unix Makefiles") 133VS2010_X32_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT) 134VS2010_X64_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT) 135VS2013_X64_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT) 136VS2013_X64_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_64BIT) 137 138ANY_VS_X32_GENERATOR = VSProjectGenerator.getDefault(VSProjectGenerator.ARCH_32BIT) 139ANY_VS_X64_GENERATOR = VSProjectGenerator.getDefault(VSProjectGenerator.ARCH_64BIT) 140