Add packaging for TIZEN
[platform/upstream/VK-GL-CTS.git] / scripts / check_build_sanity.py
1 # -*- coding: utf-8 -*-
2
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
6 #
7 # Copyright 2016 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 argparse
25 import tempfile
26
27 from build.common import *
28 from build.build import *
29
30 class Environment:
31         def __init__ (self, srcDir, tmpDir):
32                 self.srcDir     = srcDir
33                 self.tmpDir     = tmpDir
34
35 class BuildTestStep:
36         def getName (self):
37                 return "<unknown>"
38
39         def isAvailable (self, env):
40                 return True
41
42         def run (self, env):
43                 raise Exception("Not implemented")
44
45 class RunScript(BuildTestStep):
46         def __init__ (self, scriptPath, getExtraArgs = None):
47                 self.scriptPath         = scriptPath
48                 self.getExtraArgs       = getExtraArgs
49
50         def getName (self):
51                 return self.scriptPath
52
53         def run (self, env):
54                 args = ["python", os.path.join(env.srcDir, self.scriptPath)]
55
56                 if self.getExtraArgs != None:
57                         args += self.getExtraArgs(env)
58
59                 execute(args)
60
61 def makeCflagsArgs (cflags):
62         cflagsStr = " ".join(cflags)
63         return ["-DCMAKE_C_FLAGS=%s" % cflagsStr, "-DCMAKE_CXX_FLAGS=%s" % cflagsStr]
64
65 def makeBuildArgs (target, cc, cpp, cflags):
66         return ["-DDEQP_TARGET=%s" % target, "-DCMAKE_C_COMPILER=%s" % cc, "-DCMAKE_CXX_COMPILER=%s" % cpp] + makeCflagsArgs(cflags)
67
68 class BuildConfigGen:
69         def isAvailable (self, env):
70                 return True
71
72 class UnixConfig(BuildConfigGen):
73         def __init__ (self, target, buildType, cc, cpp, cflags):
74                 self.target             = target
75                 self.buildType  = buildType
76                 self.cc                 = cc
77                 self.cpp                = cpp
78                 self.cflags             = cflags
79
80         def isAvailable (self, env):
81                 return which(self.cc) != None and which(self.cpp) != None
82
83         def getBuildConfig (self, env, buildDir):
84                 args = makeBuildArgs(self.target, self.cc, self.cpp, self.cflags)
85                 return BuildConfig(buildDir, self.buildType, args, env.srcDir)
86
87 class VSConfig(BuildConfigGen):
88         def __init__ (self, buildType):
89                 self.buildType = buildType
90
91         def getBuildConfig (self, env, buildDir):
92                 args = ["-DCMAKE_C_FLAGS=/WX -DCMAKE_CXX_FLAGS=/WX"]
93                 return BuildConfig(buildDir, self.buildType, args, env.srcDir)
94
95 class Build(BuildTestStep):
96         def __init__ (self, buildDir, configGen, generator):
97                 self.buildDir   = buildDir
98                 self.configGen  = configGen
99                 self.generator  = generator
100
101         def getName (self):
102                 return self.buildDir
103
104         def isAvailable (self, env):
105                 return self.configGen.isAvailable(env) and self.generator != None and self.generator.isAvailable()
106
107         def run (self, env):
108                 # specialize config for env
109                 buildDir        = os.path.join(env.tmpDir, self.buildDir)
110                 curConfig       = self.configGen.getBuildConfig(env, buildDir)
111
112                 build(curConfig, self.generator)
113
114 class CheckSrcChanges(BuildTestStep):
115         def getName (self):
116                 return "check for changes"
117
118         def run (self, env):
119                 pushWorkingDir(env.srcDir)
120                 execute(["git", "diff", "--exit-code"])
121                 popWorkingDir()
122
123 def getClangVersion ():
124         knownVersions = ["4.0", "3.9", "3.8", "3.7", "3.6", "3.5"]
125         for version in knownVersions:
126                 if which("clang-" + version) != None:
127                         return "-" + version
128         return ""
129
130 def runSteps (steps):
131         for step in steps:
132                 if step.isAvailable(env):
133                         print "Run: %s" % step.getName()
134                         step.run(env)
135                 else:
136                         print "Skip: %s" % step.getName()
137
138 COMMON_GCC_CFLAGS       = ["-Werror"]
139 COMMON_CLANG_CFLAGS     = COMMON_GCC_CFLAGS + ["-Wno-error=unused-command-line-argument"]
140 GCC_32BIT_CFLAGS        = COMMON_GCC_CFLAGS + ["-m32"]
141 CLANG_32BIT_CFLAGS      = COMMON_CLANG_CFLAGS + ["-m32"]
142 GCC_64BIT_CFLAGS        = COMMON_GCC_CFLAGS + ["-m64"]
143 CLANG_64BIT_CFLAGS      = COMMON_CLANG_CFLAGS + ["-m64"]
144 CLANG_VERSION           = getClangVersion()
145
146 # Always ran before any receipe
147 PREREQUISITES           = [
148         RunScript(os.path.join("external", "fetch_sources.py"))
149 ]
150
151 # Always ran after any receipe
152 POST_CHECKS                     = [
153         CheckSrcChanges()
154 ]
155
156 BUILD_TARGETS           = [
157         Build("clang-64-debug",
158                   UnixConfig("null",
159                                          "Debug",
160                                          "clang" + CLANG_VERSION,
161                                          "clang++" + CLANG_VERSION,
162                                          CLANG_64BIT_CFLAGS),
163                   ANY_UNIX_GENERATOR),
164         Build("gcc-32-debug",
165                   UnixConfig("null",
166                                          "Debug",
167                                          "gcc",
168                                          "g++",
169                                          GCC_32BIT_CFLAGS),
170                   ANY_UNIX_GENERATOR),
171         Build("gcc-64-release",
172                   UnixConfig("null",
173                                          "Release",
174                                          "gcc",
175                                          "g++",
176                                          GCC_64BIT_CFLAGS),
177                   ANY_UNIX_GENERATOR),
178         Build("vs-64-debug",
179                   VSConfig("Debug"),
180                   ANY_VS_X64_GENERATOR),
181 ]
182
183 SPECIAL_RECIPES         = [
184         ('android-mustpass', [
185                         RunScript(os.path.join("scripts", "build_android_mustpass.py"),
186                                           lambda env: ["--build-dir", os.path.join(env.tmpDir, "android-mustpass")]),
187                 ]),
188         ('vulkan-mustpass', [
189                         RunScript(os.path.join("external", "vulkancts", "scripts", "build_mustpass.py"),
190                                           lambda env: ["--build-dir", os.path.join(env.tmpDir, "vulkan-mustpass")]),
191                 ]),
192         ('spirv-binaries', [
193                         RunScript(os.path.join("external", "vulkancts", "scripts", "build_spirv_binaries.py"),
194                                           lambda env: ["--build-dir", os.path.join(env.tmpDir, "spirv-binaries")]),
195                 ]),
196         ('gen-inl-files', [
197                         RunScript(os.path.join("scripts", "gen_egl.py")),
198                         RunScript(os.path.join("scripts", "opengl", "gen_all.py")),
199                         RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework.py")),
200                         RunScript(os.path.join("scripts", "gen_android_mk.py")),
201                         RunScript(os.path.join("scripts", "src_util", "check_all.py")),
202                 ])
203 ]
204
205 def getBuildRecipes ():
206         return [(b.getName(), [b]) for b in BUILD_TARGETS]
207
208 def getAllRecipe (recipes):
209         allSteps = []
210         for name, steps in recipes:
211                 allSteps += steps
212         return ("all", allSteps)
213
214 def getRecipes ():
215         recipes = getBuildRecipes()
216         recipes += SPECIAL_RECIPES
217         return recipes
218
219 def getRecipe (recipes, recipeName):
220         for curName, steps in recipes:
221                 if curName == recipeName:
222                         return (curName, steps)
223         return None
224
225 RECIPES                 = getRecipes()
226
227 def parseArgs ():
228         parser = argparse.ArgumentParser(description = "Build and test source",
229                                                                          formatter_class=argparse.ArgumentDefaultsHelpFormatter)
230         parser.add_argument("-s",
231                                                 "--src-dir",
232                                                 dest="srcDir",
233                                                 default=DEQP_DIR,
234                                                 help="Source directory")
235         parser.add_argument("-t",
236                                                 "--tmp-dir",
237                                                 dest="tmpDir",
238                                                 default=os.path.join(tempfile.gettempdir(), "deqp-build-test"),
239                                                 help="Temporary directory")
240         parser.add_argument("-r",
241                                                 "--recipe",
242                                                 dest="recipe",
243                                                 choices=[n for n, s in RECIPES] + ["all"],
244                                                 default="all",
245                                                 help="Build / test recipe")
246         parser.add_argument("-d",
247                                                 "--dump-recipes",
248                                                 dest="dumpRecipes",
249                                                 action="store_true",
250                                                 help="Print out recipes that have any available actions")
251         parser.add_argument("--skip-prerequisites",
252                                                 dest="skipPrerequisites",
253                                                 action="store_true",
254                                                 help="Skip external dependency fetch")
255
256         return parser.parse_args()
257
258 if __name__ == "__main__":
259         args    = parseArgs()
260         env             = Environment(args.srcDir, args.tmpDir)
261
262         if args.dumpRecipes:
263                 for name, steps in RECIPES:
264                         for step in steps:
265                                 if step.isAvailable(env):
266                                         print name
267                                         break
268         else:
269                 name, steps     = getAllRecipe(RECIPES) if args.recipe == "all" \
270                                           else getRecipe(RECIPES, args.recipe)
271
272                 print "Running %s" % name
273
274                 allSteps = (PREREQUISITES if (args.skipPrerequisites == False) else []) + steps + POST_CHECKS
275                 runSteps(allSteps)
276
277                 print "All steps completed successfully"