xref: /aosp_15_r20/external/deqp/scripts/ctsbuild/config.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
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    if sys.version_info < (3, 0):
32        import _winreg
33    else:
34        import winreg
35        _winreg = winreg
36except:
37    _winreg = None
38
39class BuildConfig:
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()
46
47    def getSrcPath (self):
48        return self.srcPath
49
50    def getBuildDir (self):
51        return self.buildDir
52
53    def getBuildType (self):
54        return self.buildType
55
56    def getArgs (self):
57        return self.args
58
59    def getCMakePath (self):
60        return self.cmakePath
61
62    @staticmethod
63    def findCMake ():
64        if which("cmake") == None:
65            possiblePaths = [
66                "/Applications/CMake.app/Contents/bin/cmake"
67            ]
68            for path in possiblePaths:
69                if os.path.exists(path):
70                    return 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")
72        return "cmake"
73
74class CMakeGenerator:
75    def __init__ (self, name, isMultiConfig = False, extraBuildArgs = [], platform = None):
76        self.name = name
77        self.isMultiConfig = isMultiConfig
78        self.extraBuildArgs = copy.copy(extraBuildArgs)
79        self.platform = platform
80
81    def getName (self):
82        return self.name
83
84    def getGenerateArgs (self, buildType):
85        args = ['-G', self.name]
86        if not self.isMultiConfig:
87            args.append('-DCMAKE_BUILD_TYPE=%s' % buildType)
88        if self.platform:
89            # this is supported since CMake 3.1, needed for VS2019+
90            args.append('-A')
91            args.append(self.platform)
92        return args
93
94    def getBuildArgs (self, buildType):
95        args = []
96        if self.isMultiConfig:
97            args += ['--config', buildType]
98        if len(self.extraBuildArgs) > 0:
99            args += ['--'] + self.extraBuildArgs
100        return args
101
102    def getBinaryPath (self, buildType, basePath):
103        return basePath
104
105class UnixMakefileGenerator(CMakeGenerator):
106    def __init__(self):
107        CMakeGenerator.__init__(self, "Unix Makefiles", extraBuildArgs = ["-j%d" % multiprocessing.cpu_count()])
108
109    def isAvailable (self):
110        return which('make') != None
111
112class NMakeGenerator(CMakeGenerator):
113    def __init__(self):
114        CMakeGenerator.__init__(self, "NMake Makefiles")
115
116    def isAvailable (self):
117        return which('nmake') != None
118
119class NinjaGenerator(CMakeGenerator):
120    def __init__(self):
121        CMakeGenerator.__init__(self, "Ninja")
122
123    def isAvailable (self):
124        return which('ninja') != None
125
126class VSProjectGenerator(CMakeGenerator):
127    ARCH_32BIT = 0
128    ARCH_64BIT = 1
129
130    def __init__(self, version, arch):
131        name = "Visual Studio %d" % version
132
133        platform = None
134
135        if version >= 16:
136            # From VS2019 onwards, the architecture is given by -A <platform-name> switch
137            if arch == self.ARCH_64BIT:
138                platform = "x64"
139            elif arch == self.ARCH_32BIT:
140                platform = "Win32"
141        else:
142            if arch == self.ARCH_64BIT:
143                name += " Win64"
144
145        CMakeGenerator.__init__(self, name, isMultiConfig = True, extraBuildArgs = ['/m'], platform = platform)
146        self.version = version
147        self.arch = arch
148
149    def getBinaryPath (self, buildType, basePath):
150        return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe")
151
152    @staticmethod
153    def getNativeArch ():
154        bits = HostInfo.getArchBits()
155
156        if bits == 32:
157            return VSProjectGenerator.ARCH_32BIT
158        elif bits == 64:
159            return VSProjectGenerator.ARCH_64BIT
160        else:
161            raise Exception("Unhandled bits '%s'" % bits)
162
163    @staticmethod
164    def registryKeyAvailable (root, arch, name):
165        try:
166            key = _winreg.OpenKey(root, name, 0, _winreg.KEY_READ | arch)
167            _winreg.CloseKey(key)
168            return True
169        except:
170            return False
171
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:
176                return False
177
178            arch = _winreg.KEY_WOW64_32KEY if nativeArch == self.ARCH_64BIT else 0
179            keyMap = {
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")]
187            }
188
189            if not self.version in keyMap:
190                raise Exception("Unsupported VS version %d" % self.version)
191
192            keys = keyMap[self.version]
193            for root, name in keys:
194                if VSProjectGenerator.registryKeyAvailable(root, arch, name):
195                    return True
196            return False
197        else:
198            return False
199
200# Pre-defined generators
201
202MAKEFILE_GENERATOR = UnixMakefileGenerator()
203NMAKE_GENERATOR = NMakeGenerator()
204NINJA_GENERATOR = NinjaGenerator()
205VS2010_X32_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT)
206VS2010_X64_GENERATOR = VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT)
207VS2012_X32_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_32BIT)
208VS2012_X64_GENERATOR = VSProjectGenerator(11, VSProjectGenerator.ARCH_64BIT)
209VS2013_X32_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT)
210VS2013_X64_GENERATOR = VSProjectGenerator(12, VSProjectGenerator.ARCH_64BIT)
211VS2015_X32_GENERATOR = VSProjectGenerator(14, VSProjectGenerator.ARCH_32BIT)
212VS2015_X64_GENERATOR = VSProjectGenerator(14, VSProjectGenerator.ARCH_64BIT)
213VS2017_X32_GENERATOR = VSProjectGenerator(15, VSProjectGenerator.ARCH_32BIT)
214VS2017_X64_GENERATOR = VSProjectGenerator(15, VSProjectGenerator.ARCH_64BIT)
215VS2019_X32_GENERATOR = VSProjectGenerator(16, VSProjectGenerator.ARCH_32BIT)
216VS2019_X64_GENERATOR = VSProjectGenerator(16, VSProjectGenerator.ARCH_64BIT)
217VS2022_X32_GENERATOR = VSProjectGenerator(17, VSProjectGenerator.ARCH_32BIT)
218VS2022_X64_GENERATOR = VSProjectGenerator(17, VSProjectGenerator.ARCH_64BIT)
219
220def selectFirstAvailableGenerator (generators):
221    for generator in generators:
222        if generator.isAvailable():
223            return generator
224    return None
225
226ANY_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,
234                            ])
235ANY_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,
243                            ])
244ANY_UNIX_GENERATOR = selectFirstAvailableGenerator([
245                                NINJA_GENERATOR,
246                                MAKEFILE_GENERATOR,
247                                NMAKE_GENERATOR,
248                            ])
249ANY_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,
264                                NINJA_GENERATOR,
265                                MAKEFILE_GENERATOR,
266                                NMAKE_GENERATOR,
267                            ])
268