Home | History | Annotate | Download | only in build
      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