• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
23import os
24import sys
25import copy
26import multiprocessing
27
28from common import which, HostInfo, DEQP_DIR
29
30try:
31	import _winreg
32except:
33	_winreg = None
34
35class BuildConfig:
36	def __init__ (self, buildDir, buildType, args, srcPath = DEQP_DIR):
37		self.srcPath		= srcPath
38		self.buildDir		= buildDir
39		self.buildType		= buildType
40		self.args			= copy.copy(args)
41		self.cmakePath		= BuildConfig.findCMake()
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	def getCMakePath (self):
56		return self.cmakePath
57
58	@staticmethod
59	def findCMake ():
60		if which("cmake") == None:
61			possiblePaths = [
62				"/Applications/CMake.app/Contents/bin/cmake"
63			]
64			for path in possiblePaths:
65				if os.path.exists(path):
66					return path
67
68		# Fall back to PATH - may fail later
69		return "cmake"
70
71class CMakeGenerator:
72	def __init__ (self, name, isMultiConfig = False, extraBuildArgs = []):
73		self.name			= name
74		self.isMultiConfig	= isMultiConfig
75		self.extraBuildArgs	= copy.copy(extraBuildArgs)
76
77	def getName (self):
78		return self.name
79
80	def getGenerateArgs (self, buildType):
81		args = ['-G', self.name]
82		if not self.isMultiConfig:
83			args.append('-DCMAKE_BUILD_TYPE=%s' % buildType)
84		return args
85
86	def getBuildArgs (self, buildType):
87		args = []
88		if self.isMultiConfig:
89			args += ['--config', buildType]
90		if len(self.extraBuildArgs) > 0:
91			args += ['--'] + self.extraBuildArgs
92		return args
93
94	def getBinaryPath (self, buildType, basePath):
95		return basePath
96
97class UnixMakefileGenerator(CMakeGenerator):
98	def __init__(self):
99		CMakeGenerator.__init__(self, "Unix Makefiles", extraBuildArgs = ["-j%d" % multiprocessing.cpu_count()])
100
101	def isAvailable (self):
102		return which('make') != None
103
104class NMakeGenerator(CMakeGenerator):
105	def __init__(self):
106		CMakeGenerator.__init__(self, "NMake Makefiles")
107
108	def isAvailable (self):
109		return which('nmake') != None
110
111class NinjaGenerator(CMakeGenerator):
112	def __init__(self):
113		CMakeGenerator.__init__(self, "Ninja")
114
115	def isAvailable (self):
116		return which('ninja') != None
117
118class VSProjectGenerator(CMakeGenerator):
119	ARCH_32BIT	= 0
120	ARCH_64BIT	= 1
121
122	def __init__(self, version, arch):
123		name = "Visual Studio %d" % version
124		if arch == self.ARCH_64BIT:
125			name += " Win64"
126
127		CMakeGenerator.__init__(self, name, isMultiConfig = True, extraBuildArgs = ['/m'])
128		self.version		= version
129		self.arch			= arch
130
131	def getBinaryPath (self, buildType, basePath):
132		return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe")
133
134	@staticmethod
135	def getNativeArch ():
136		bits = HostInfo.getArchBits()
137
138		if bits == 32:
139			return VSProjectGenerator.ARCH_32BIT
140		elif bits == 64:
141			return VSProjectGenerator.ARCH_64BIT
142		else:
143			raise Exception("Unhandled bits '%s'" % bits)
144
145	@staticmethod
146	def registryKeyAvailable (root, arch, name):
147		try:
148			key = _winreg.OpenKey(root, name, 0, _winreg.KEY_READ | arch)
149			_winreg.CloseKey(key)
150			return True
151		except:
152			return False
153
154	def isAvailable (self):
155		if sys.platform == 'win32' and _winreg != None:
156			nativeArch = VSProjectGenerator.getNativeArch()
157			if nativeArch == self.ARCH_32BIT and self.arch == self.ARCH_64BIT:
158				return False
159
160			arch = _winreg.KEY_WOW64_32KEY if nativeArch == self.ARCH_64BIT else 0
161			keyMap = {
162				10:		[(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.10.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\10.0")],
163				11:		[(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.11.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\11.0")],
164				12:		[(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.12.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\12.0")],
165				14:		[(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.14.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\14.0")],
166				15:		[(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.15.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\15.0")]
167			}
168
169			if not self.version in keyMap:
170				raise Exception("Unsupported VS version %d" % self.version)
171
172			keys = keyMap[self.version]
173			for root, name in keys:
174				if VSProjectGenerator.registryKeyAvailable(root, arch, name):
175					return True
176			return False
177		else:
178			return False
179
180# Pre-defined generators
181
182MAKEFILE_GENERATOR		= UnixMakefileGenerator()
183NMAKE_GENERATOR			= NMakeGenerator()
184NINJA_GENERATOR			= NinjaGenerator()
185VS2010_X32_GENERATOR	= VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT)
186VS2010_X64_GENERATOR	= VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT)
187VS2012_X32_GENERATOR	= VSProjectGenerator(11, VSProjectGenerator.ARCH_32BIT)
188VS2012_X64_GENERATOR	= VSProjectGenerator(11, VSProjectGenerator.ARCH_64BIT)
189VS2013_X32_GENERATOR	= VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT)
190VS2013_X64_GENERATOR	= VSProjectGenerator(12, VSProjectGenerator.ARCH_64BIT)
191VS2015_X32_GENERATOR	= VSProjectGenerator(14, VSProjectGenerator.ARCH_32BIT)
192VS2015_X64_GENERATOR	= VSProjectGenerator(14, VSProjectGenerator.ARCH_64BIT)
193VS2017_X32_GENERATOR	= VSProjectGenerator(15, VSProjectGenerator.ARCH_32BIT)
194VS2017_X64_GENERATOR	= VSProjectGenerator(15, VSProjectGenerator.ARCH_64BIT)
195
196def selectFirstAvailableGenerator (generators):
197	for generator in generators:
198		if generator.isAvailable():
199			return generator
200	return None
201
202ANY_VS_X32_GENERATOR	= selectFirstAvailableGenerator([
203								VS2017_X32_GENERATOR,
204								VS2015_X32_GENERATOR,
205								VS2013_X32_GENERATOR,
206								VS2012_X32_GENERATOR,
207								VS2010_X32_GENERATOR,
208							])
209ANY_VS_X64_GENERATOR	= selectFirstAvailableGenerator([
210								VS2017_X64_GENERATOR,
211								VS2015_X64_GENERATOR,
212								VS2013_X64_GENERATOR,
213								VS2012_X64_GENERATOR,
214								VS2010_X64_GENERATOR,
215							])
216ANY_UNIX_GENERATOR		= selectFirstAvailableGenerator([
217								NINJA_GENERATOR,
218								MAKEFILE_GENERATOR,
219								NMAKE_GENERATOR,
220							])
221ANY_GENERATOR			= selectFirstAvailableGenerator([
222								VS2017_X64_GENERATOR,
223								VS2017_X32_GENERATOR,
224								VS2015_X64_GENERATOR,
225								VS2015_X32_GENERATOR,
226								VS2013_X64_GENERATOR,
227								VS2012_X64_GENERATOR,
228								VS2010_X64_GENERATOR,
229								VS2013_X32_GENERATOR,
230								VS2012_X32_GENERATOR,
231								VS2010_X32_GENERATOR,
232								NINJA_GENERATOR,
233								MAKEFILE_GENERATOR,
234								NMAKE_GENERATOR,
235							])
236