1 # -*- coding: utf-8 -*- 2 3 #------------------------------------------------------------------------- 4 # drawElements Quality Program utilities 5 # -------------------------------------- 6 # 7 # Copyright 2015 The Android Open Source Project 8 # 9 # Licensed under the Apache License, Version 2.0 (the "License"); 10 # you may not use this file except in compliance with the License. 11 # You may obtain a copy of the License at 12 # 13 # http://www.apache.org/licenses/LICENSE-2.0 14 # 15 # Unless required by applicable law or agreed to in writing, software 16 # distributed under the License is distributed on an "AS IS" BASIS, 17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 # See the License for the specific language governing permissions and 19 # limitations under the License. 20 # 21 #------------------------------------------------------------------------- 22 23 import os 24 import sys 25 import copy 26 import platform 27 import multiprocessing 28 29 from common import which, DEQP_DIR 30 31 try: 32 import _winreg 33 except: 34 _winreg = None 35 36 class BuildConfig: 37 def __init__ (self, buildDir, buildType, args, srcPath = DEQP_DIR): 38 self.srcPath = srcPath 39 self.buildDir = buildDir 40 self.buildType = buildType 41 self.args = copy.copy(args) 42 43 def getSrcPath (self): 44 return self.srcPath 45 46 def getBuildDir (self): 47 return self.buildDir 48 49 def getBuildType (self): 50 return self.buildType 51 52 def getArgs (self): 53 return self.args 54 55 class CMakeGenerator: 56 def __init__ (self, name, isMultiConfig = False, extraBuildArgs = []): 57 self.name = name 58 self.isMultiConfig = isMultiConfig 59 self.extraBuildArgs = copy.copy(extraBuildArgs) 60 61 def getName (self): 62 return self.name 63 64 def getGenerateArgs (self, buildType): 65 args = ['-G', self.name] 66 if not self.isMultiConfig: 67 args.append('-DCMAKE_BUILD_TYPE=%s' % buildType) 68 return args 69 70 def getBuildArgs (self, buildType): 71 args = [] 72 if self.isMultiConfig: 73 args += ['--config', buildType] 74 if len(self.extraBuildArgs) > 0: 75 args += ['--'] + self.extraBuildArgs 76 return args 77 78 def getBinaryPath (self, buildType, basePath): 79 return basePath 80 81 class UnixMakefileGenerator(CMakeGenerator): 82 def __init__(self): 83 CMakeGenerator.__init__(self, "Unix Makefiles", extraBuildArgs = ["-j%d" % multiprocessing.cpu_count()]) 84 85 def isAvailable (self): 86 return which('make') != None 87 88 class NinjaGenerator(CMakeGenerator): 89 def __init__(self): 90 CMakeGenerator.__init__(self, "Ninja") 91 92 def isAvailable (self): 93 return which('ninja') != None 94 95 class VSProjectGenerator(CMakeGenerator): 96 ARCH_32BIT = 0 97 ARCH_64BIT = 1 98 99 def __init__(self, version, arch): 100 name = "Visual Studio %d" % version 101 if arch == self.ARCH_64BIT: 102 name += " Win64" 103 104 CMakeGenerator.__init__(self, name, isMultiConfig = True, extraBuildArgs = ['/m']) 105 self.version = version 106 self.arch = arch 107 108 def getBinaryPath (self, buildType, basePath): 109 return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe") 110 111 @staticmethod 112 def getNativeArch (): 113 arch = platform.machine().lower() 114 115 if arch == 'x86': 116 return VSProjectGenerator.ARCH_32BIT 117 elif arch == 'amd64': 118 return VSProjectGenerator.ARCH_64BIT 119 else: 120 raise Exception("Unhandled arch '%s'" % arch) 121 122 @staticmethod 123 def registryKeyAvailable (root, arch, name): 124 try: 125 key = _winreg.OpenKey(root, name, 0, _winreg.KEY_READ | arch) 126 _winreg.CloseKey(key) 127 return True 128 except: 129 return False 130 131 def isAvailable (self): 132 if sys.platform == 'win32' and _winreg != None: 133 nativeArch = VSProjectGenerator.getNativeArch() 134 if nativeArch == self.ARCH_32BIT and self.arch == self.ARCH_64BIT: 135 return False 136 137 arch = _winreg.KEY_WOW64_32KEY if nativeArch == self.ARCH_64BIT else 0 138 keyMap = { 139 10: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.10.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\10.0")], 140 11: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.11.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\11.0")], 141 12: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.12.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\12.0")], 142 } 143 144 if not self.version in keyMap: 145 raise Exception("Unsupported VS version %d" % self.version) 146 147 keys = keyMap[self.version] 148 for root, name in keys: 149 if VSProjectGenerator.registryKeyAvailable(root, arch, name): 150 return True 151 return False 152 else: 153 return False 154 155 # Pre-defined generators 156 157 MAKEFILE_GENERATOR = UnixMakefileGenerator() 158 NINJA_GENERATOR = NinjaGenerator() 159 VS2010_X32_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT) 160 VS2010_X64_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT) 161 VS2012_X32_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_32BIT) 162 VS2012_X64_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_64BIT) 163 VS2013_X32_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT) 164 VS2013_X64_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_64BIT) 165 166 def selectFirstAvailableGenerator (generators): 167 for generator in generators: 168 if generator.isAvailable(): 169 return generator 170 return None 171 172 ANY_VS_X32_GENERATOR = selectFirstAvailableGenerator([ 173 VS2013_X32_GENERATOR, 174 VS2012_X32_GENERATOR, 175 VS2010_X32_GENERATOR, 176 ]) 177 ANY_VS_X64_GENERATOR = selectFirstAvailableGenerator([ 178 VS2013_X64_GENERATOR, 179 VS2012_X64_GENERATOR, 180 VS2010_X64_GENERATOR, 181 ]) 182 ANY_UNIX_GENERATOR = selectFirstAvailableGenerator([ 183 NINJA_GENERATOR, 184 MAKEFILE_GENERATOR, 185 ]) 186 ANY_GENERATOR = selectFirstAvailableGenerator([ 187 VS2013_X64_GENERATOR, 188 VS2012_X64_GENERATOR, 189 VS2010_X64_GENERATOR, 190 VS2013_X32_GENERATOR, 191 VS2012_X32_GENERATOR, 192 VS2010_X32_GENERATOR, 193 NINJA_GENERATOR, 194 MAKEFILE_GENERATOR, 195 ]) 196