1 # -*- coding: utf-8 -*-
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
7 # Copyright 2015 The Android Open Source Project
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
13 # http://www.apache.org/licenses/LICENSE-2.0
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.
21 #-------------------------------------------------------------------------
26 import multiprocessing
28 from . common import which, HostInfo, DEQP_DIR
31 if sys.version_info < (3, 0):
40 def __init__ (self, buildDir, buildType, args, srcPath = DEQP_DIR):
41 self.srcPath = srcPath
42 self.buildDir = buildDir
43 self.buildType = buildType
44 self.args = copy.copy(args)
45 self.cmakePath = BuildConfig.findCMake()
47 def getSrcPath (self):
50 def getBuildDir (self):
53 def getBuildType (self):
59 def getCMakePath (self):
64 if which("cmake") == None:
66 "/Applications/CMake.app/Contents/bin/cmake"
68 for path in possiblePaths:
69 if os.path.exists(path):
71 raise FileNotFoundError("cmake executable file is not avaliable on the platform. It may not have been installed or added to PATH environment variable")
75 def __init__ (self, name, isMultiConfig = False, extraBuildArgs = [], platform = None):
77 self.isMultiConfig = isMultiConfig
78 self.extraBuildArgs = copy.copy(extraBuildArgs)
79 self.platform = platform
84 def getGenerateArgs (self, buildType):
85 args = ['-G', self.name]
86 if not self.isMultiConfig:
87 args.append('-DCMAKE_BUILD_TYPE=%s' % buildType)
89 # this is supported since CMake 3.1, needed for VS2019+
91 args.append(self.platform)
94 def getBuildArgs (self, buildType):
96 if self.isMultiConfig:
97 args += ['--config', buildType]
98 if len(self.extraBuildArgs) > 0:
99 args += ['--'] + self.extraBuildArgs
102 def getBinaryPath (self, buildType, basePath):
105 class UnixMakefileGenerator(CMakeGenerator):
107 CMakeGenerator.__init__(self, "Unix Makefiles", extraBuildArgs = ["-j%d" % multiprocessing.cpu_count()])
109 def isAvailable (self):
110 return which('make') != None
112 class NMakeGenerator(CMakeGenerator):
114 CMakeGenerator.__init__(self, "NMake Makefiles")
116 def isAvailable (self):
117 return which('nmake') != None
119 class NinjaGenerator(CMakeGenerator):
121 CMakeGenerator.__init__(self, "Ninja")
123 def isAvailable (self):
124 return which('ninja') != None
126 class VSProjectGenerator(CMakeGenerator):
130 def __init__(self, version, arch):
131 name = "Visual Studio %d" % version
136 # From VS2019 onwards, the architecture is given by -A <platform-name> switch
137 if arch == self.ARCH_64BIT:
139 elif arch == self.ARCH_32BIT:
142 if arch == self.ARCH_64BIT:
145 CMakeGenerator.__init__(self, name, isMultiConfig = True, extraBuildArgs = ['/m'], platform = platform)
146 self.version = version
149 def getBinaryPath (self, buildType, basePath):
150 return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe")
153 def getNativeArch ():
154 bits = HostInfo.getArchBits()
157 return VSProjectGenerator.ARCH_32BIT
159 return VSProjectGenerator.ARCH_64BIT
161 raise Exception("Unhandled bits '%s'" % bits)
164 def registryKeyAvailable (root, arch, name):
166 key = _winreg.OpenKey(root, name, 0, _winreg.KEY_READ | arch)
167 _winreg.CloseKey(key)
172 def isAvailable (self):
173 if sys.platform == 'win32' and _winreg != None:
174 nativeArch = VSProjectGenerator.getNativeArch()
175 if nativeArch == self.ARCH_32BIT and self.arch == self.ARCH_64BIT:
178 arch = _winreg.KEY_WOW64_32KEY if nativeArch == self.ARCH_64BIT else 0
180 10: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.10.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\10.0")],
181 11: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.11.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\11.0")],
182 12: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.12.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\12.0")],
183 14: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.14.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\14.0")],
184 15: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.15.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\15.0")],
185 16: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.16.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\16.0")],
186 17: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.17.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\17.0")]
189 if not self.version in keyMap:
190 raise Exception("Unsupported VS version %d" % self.version)
192 keys = keyMap[self.version]
193 for root, name in keys:
194 if VSProjectGenerator.registryKeyAvailable(root, arch, name):
200 # Pre-defined generators
202 MAKEFILE_GENERATOR = UnixMakefileGenerator()
203 NMAKE_GENERATOR = NMakeGenerator()
204 NINJA_GENERATOR = NinjaGenerator()
205 VS2010_X32_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT)
206 VS2010_X64_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT)
207 VS2012_X32_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_32BIT)
208 VS2012_X64_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_64BIT)
209 VS2013_X32_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT)
210 VS2013_X64_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_64BIT)
211 VS2015_X32_GENERATOR = VSProjectGenerator(14, VSProjectGenerator.ARCH_32BIT)
212 VS2015_X64_GENERATOR = VSProjectGenerator(14, VSProjectGenerator.ARCH_64BIT)
213 VS2017_X32_GENERATOR = VSProjectGenerator(15, VSProjectGenerator.ARCH_32BIT)
214 VS2017_X64_GENERATOR = VSProjectGenerator(15, VSProjectGenerator.ARCH_64BIT)
215 VS2019_X32_GENERATOR = VSProjectGenerator(16, VSProjectGenerator.ARCH_32BIT)
216 VS2019_X64_GENERATOR = VSProjectGenerator(16, VSProjectGenerator.ARCH_64BIT)
217 VS2022_X32_GENERATOR = VSProjectGenerator(17, VSProjectGenerator.ARCH_32BIT)
218 VS2022_X64_GENERATOR = VSProjectGenerator(17, VSProjectGenerator.ARCH_64BIT)
220 def selectFirstAvailableGenerator (generators):
221 for generator in generators:
222 if generator.isAvailable():
226 ANY_VS_X32_GENERATOR = selectFirstAvailableGenerator([
227 VS2022_X32_GENERATOR,
228 VS2019_X32_GENERATOR,
229 VS2017_X32_GENERATOR,
230 VS2015_X32_GENERATOR,
231 VS2013_X32_GENERATOR,
232 VS2012_X32_GENERATOR,
233 VS2010_X32_GENERATOR,
235 ANY_VS_X64_GENERATOR = selectFirstAvailableGenerator([
236 VS2022_X64_GENERATOR,
237 VS2019_X64_GENERATOR,
238 VS2017_X64_GENERATOR,
239 VS2015_X64_GENERATOR,
240 VS2013_X64_GENERATOR,
241 VS2012_X64_GENERATOR,
242 VS2010_X64_GENERATOR,
244 ANY_UNIX_GENERATOR = selectFirstAvailableGenerator([
249 ANY_GENERATOR = selectFirstAvailableGenerator([
250 VS2022_X64_GENERATOR,
251 VS2022_X32_GENERATOR,
252 VS2019_X64_GENERATOR,
253 VS2019_X32_GENERATOR,
254 VS2017_X64_GENERATOR,
255 VS2017_X32_GENERATOR,
256 VS2015_X64_GENERATOR,
257 VS2015_X32_GENERATOR,
258 VS2013_X64_GENERATOR,
259 VS2012_X64_GENERATOR,
260 VS2010_X64_GENERATOR,
261 VS2013_X32_GENERATOR,
262 VS2012_X32_GENERATOR,
263 VS2010_X32_GENERATOR,