261 lines
8.1 KiB
Python
261 lines
8.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
#-------------------------------------------------------------------------
|
|
# drawElements Quality Program utilities
|
|
# --------------------------------------
|
|
#
|
|
# Copyright 2015 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
|
|
import os
|
|
import sys
|
|
import copy
|
|
import multiprocessing
|
|
|
|
from . common import which, HostInfo, DEQP_DIR
|
|
|
|
try:
|
|
if sys.version_info < (3, 0):
|
|
import _winreg
|
|
else:
|
|
import winreg
|
|
_winreg = winreg
|
|
except:
|
|
_winreg = None
|
|
|
|
class BuildConfig:
|
|
def __init__ (self, buildDir, buildType, args, srcPath = DEQP_DIR):
|
|
self.srcPath = srcPath
|
|
self.buildDir = buildDir
|
|
self.buildType = buildType
|
|
self.args = copy.copy(args)
|
|
self.cmakePath = BuildConfig.findCMake()
|
|
|
|
def getSrcPath (self):
|
|
return self.srcPath
|
|
|
|
def getBuildDir (self):
|
|
return self.buildDir
|
|
|
|
def getBuildType (self):
|
|
return self.buildType
|
|
|
|
def getArgs (self):
|
|
return self.args
|
|
|
|
def getCMakePath (self):
|
|
return self.cmakePath
|
|
|
|
@staticmethod
|
|
def findCMake ():
|
|
if which("cmake") == None:
|
|
possiblePaths = [
|
|
"/Applications/CMake.app/Contents/bin/cmake"
|
|
]
|
|
for path in possiblePaths:
|
|
if os.path.exists(path):
|
|
return path
|
|
raise FileNotFoundError("cmake executable file is not avaliable on the platform. It may not have been installed or added to PATH environment variable")
|
|
return "cmake"
|
|
|
|
class CMakeGenerator:
|
|
def __init__ (self, name, isMultiConfig = False, extraBuildArgs = [], platform = None):
|
|
self.name = name
|
|
self.isMultiConfig = isMultiConfig
|
|
self.extraBuildArgs = copy.copy(extraBuildArgs)
|
|
self.platform = platform
|
|
|
|
def getName (self):
|
|
return self.name
|
|
|
|
def getGenerateArgs (self, buildType):
|
|
args = ['-G', self.name]
|
|
if not self.isMultiConfig:
|
|
args.append('-DCMAKE_BUILD_TYPE=%s' % buildType)
|
|
if self.platform:
|
|
# this is supported since CMake 3.1, needed for VS2019+
|
|
args.append('-A')
|
|
args.append(self.platform)
|
|
return args
|
|
|
|
def getBuildArgs (self, buildType):
|
|
args = []
|
|
if self.isMultiConfig:
|
|
args += ['--config', buildType]
|
|
if len(self.extraBuildArgs) > 0:
|
|
args += ['--'] + self.extraBuildArgs
|
|
return args
|
|
|
|
def getBinaryPath (self, buildType, basePath):
|
|
return basePath
|
|
|
|
class UnixMakefileGenerator(CMakeGenerator):
|
|
def __init__(self):
|
|
CMakeGenerator.__init__(self, "Unix Makefiles", extraBuildArgs = ["-j%d" % multiprocessing.cpu_count()])
|
|
|
|
def isAvailable (self):
|
|
return which('make') != None
|
|
|
|
class NMakeGenerator(CMakeGenerator):
|
|
def __init__(self):
|
|
CMakeGenerator.__init__(self, "NMake Makefiles")
|
|
|
|
def isAvailable (self):
|
|
return which('nmake') != None
|
|
|
|
class NinjaGenerator(CMakeGenerator):
|
|
def __init__(self):
|
|
CMakeGenerator.__init__(self, "Ninja")
|
|
|
|
def isAvailable (self):
|
|
return which('ninja') != None
|
|
|
|
class VSProjectGenerator(CMakeGenerator):
|
|
ARCH_32BIT = 0
|
|
ARCH_64BIT = 1
|
|
|
|
def __init__(self, version, arch):
|
|
name = "Visual Studio %d" % version
|
|
|
|
platform = None
|
|
|
|
if version >= 16:
|
|
# From VS2019 onwards, the architecture is given by -A <platform-name> switch
|
|
if arch == self.ARCH_64BIT:
|
|
platform = "x64"
|
|
elif arch == self.ARCH_32BIT:
|
|
platform = "Win32"
|
|
else:
|
|
if arch == self.ARCH_64BIT:
|
|
name += " Win64"
|
|
|
|
CMakeGenerator.__init__(self, name, isMultiConfig = True, extraBuildArgs = ['/m'], platform = platform)
|
|
self.version = version
|
|
self.arch = arch
|
|
|
|
def getBinaryPath (self, buildType, basePath):
|
|
return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe")
|
|
|
|
@staticmethod
|
|
def getNativeArch ():
|
|
bits = HostInfo.getArchBits()
|
|
|
|
if bits == 32:
|
|
return VSProjectGenerator.ARCH_32BIT
|
|
elif bits == 64:
|
|
return VSProjectGenerator.ARCH_64BIT
|
|
else:
|
|
raise Exception("Unhandled bits '%s'" % bits)
|
|
|
|
@staticmethod
|
|
def registryKeyAvailable (root, arch, name):
|
|
try:
|
|
key = _winreg.OpenKey(root, name, 0, _winreg.KEY_READ | arch)
|
|
_winreg.CloseKey(key)
|
|
return True
|
|
except:
|
|
return False
|
|
|
|
def isAvailable (self):
|
|
if sys.platform == 'win32' and _winreg != None:
|
|
nativeArch = VSProjectGenerator.getNativeArch()
|
|
if nativeArch == self.ARCH_32BIT and self.arch == self.ARCH_64BIT:
|
|
return False
|
|
|
|
arch = _winreg.KEY_WOW64_32KEY if nativeArch == self.ARCH_64BIT else 0
|
|
keyMap = {
|
|
10: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.10.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\10.0")],
|
|
11: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.11.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\11.0")],
|
|
12: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.12.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\12.0")],
|
|
14: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.14.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\14.0")],
|
|
15: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.15.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\15.0")],
|
|
16: [(_winreg.HKEY_CLASSES_ROOT, "VisualStudio.DTE.16.0"), (_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\VCExpress\\16.0")]
|
|
}
|
|
|
|
if not self.version in keyMap:
|
|
raise Exception("Unsupported VS version %d" % self.version)
|
|
|
|
keys = keyMap[self.version]
|
|
for root, name in keys:
|
|
if VSProjectGenerator.registryKeyAvailable(root, arch, name):
|
|
return True
|
|
return False
|
|
else:
|
|
return False
|
|
|
|
# Pre-defined generators
|
|
|
|
MAKEFILE_GENERATOR = UnixMakefileGenerator()
|
|
NMAKE_GENERATOR = NMakeGenerator()
|
|
NINJA_GENERATOR = NinjaGenerator()
|
|
VS2010_X32_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT)
|
|
VS2010_X64_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT)
|
|
VS2012_X32_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_32BIT)
|
|
VS2012_X64_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_64BIT)
|
|
VS2013_X32_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT)
|
|
VS2013_X64_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_64BIT)
|
|
VS2015_X32_GENERATOR = VSProjectGenerator(14, VSProjectGenerator.ARCH_32BIT)
|
|
VS2015_X64_GENERATOR = VSProjectGenerator(14, VSProjectGenerator.ARCH_64BIT)
|
|
VS2017_X32_GENERATOR = VSProjectGenerator(15, VSProjectGenerator.ARCH_32BIT)
|
|
VS2017_X64_GENERATOR = VSProjectGenerator(15, VSProjectGenerator.ARCH_64BIT)
|
|
VS2019_X32_GENERATOR = VSProjectGenerator(16, VSProjectGenerator.ARCH_32BIT)
|
|
VS2019_X64_GENERATOR = VSProjectGenerator(16, VSProjectGenerator.ARCH_64BIT)
|
|
|
|
def selectFirstAvailableGenerator (generators):
|
|
for generator in generators:
|
|
if generator.isAvailable():
|
|
return generator
|
|
return None
|
|
|
|
ANY_VS_X32_GENERATOR = selectFirstAvailableGenerator([
|
|
VS2019_X32_GENERATOR,
|
|
VS2017_X32_GENERATOR,
|
|
VS2015_X32_GENERATOR,
|
|
VS2013_X32_GENERATOR,
|
|
VS2012_X32_GENERATOR,
|
|
VS2010_X32_GENERATOR,
|
|
])
|
|
ANY_VS_X64_GENERATOR = selectFirstAvailableGenerator([
|
|
VS2019_X64_GENERATOR,
|
|
VS2017_X64_GENERATOR,
|
|
VS2015_X64_GENERATOR,
|
|
VS2013_X64_GENERATOR,
|
|
VS2012_X64_GENERATOR,
|
|
VS2010_X64_GENERATOR,
|
|
])
|
|
ANY_UNIX_GENERATOR = selectFirstAvailableGenerator([
|
|
NINJA_GENERATOR,
|
|
MAKEFILE_GENERATOR,
|
|
NMAKE_GENERATOR,
|
|
])
|
|
ANY_GENERATOR = selectFirstAvailableGenerator([
|
|
VS2019_X64_GENERATOR,
|
|
VS2019_X32_GENERATOR,
|
|
VS2017_X64_GENERATOR,
|
|
VS2017_X32_GENERATOR,
|
|
VS2015_X64_GENERATOR,
|
|
VS2015_X32_GENERATOR,
|
|
VS2013_X64_GENERATOR,
|
|
VS2012_X64_GENERATOR,
|
|
VS2010_X64_GENERATOR,
|
|
VS2013_X32_GENERATOR,
|
|
VS2012_X32_GENERATOR,
|
|
VS2010_X32_GENERATOR,
|
|
NINJA_GENERATOR,
|
|
MAKEFILE_GENERATOR,
|
|
NMAKE_GENERATOR,
|
|
])
|