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