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