1 # -*- coding: utf-8 -*-
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
7 # Copyright 2016 The Android Open Source Project
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
13 # http://www.apache.org/licenses/LICENSE-2.0
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.
21 #-------------------------------------------------------------------------
27 from build.common import *
28 from build.build import *
31 def __init__ (self, srcDir, tmpDir):
39 def isAvailable (self, env):
43 raise Exception("Not implemented")
45 class RunScript(BuildTestStep):
46 def __init__ (self, scriptPath, getExtraArgs = None):
47 self.scriptPath = scriptPath
48 self.getExtraArgs = getExtraArgs
51 return self.scriptPath
54 args = ["python", os.path.join(env.srcDir, self.scriptPath)]
56 if self.getExtraArgs != None:
57 args += self.getExtraArgs(env)
61 def makeCflagsArgs (cflags):
62 cflagsStr = " ".join(cflags)
63 return ["-DCMAKE_C_FLAGS=%s" % cflagsStr, "-DCMAKE_CXX_FLAGS=%s" % cflagsStr]
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)
69 def isAvailable (self, env):
72 class UnixConfig(BuildConfigGen):
73 def __init__ (self, target, buildType, cc, cpp, cflags):
75 self.buildType = buildType
80 def isAvailable (self, env):
81 return which(self.cc) != None and which(self.cpp) != None
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)
87 class VSConfig(BuildConfigGen):
88 def __init__ (self, buildType):
89 self.buildType = buildType
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)
95 class Build(BuildTestStep):
96 def __init__ (self, buildDir, configGen, generator):
97 self.buildDir = buildDir
98 self.configGen = configGen
99 self.generator = generator
104 def isAvailable (self, env):
105 return self.configGen.isAvailable(env) and self.generator != None and self.generator.isAvailable()
108 # specialize config for env
109 buildDir = os.path.join(env.tmpDir, self.buildDir)
110 curConfig = self.configGen.getBuildConfig(env, buildDir)
112 build(curConfig, self.generator)
114 class CheckSrcChanges(BuildTestStep):
116 return "check for changes"
119 pushWorkingDir(env.srcDir)
120 execute(["git", "diff", "--exit-code"])
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:
130 def runSteps (steps):
132 if step.isAvailable(env):
133 print "Run: %s" % step.getName()
136 print "Skip: %s" % step.getName()
138 COMMON_CFLAGS = ["-Werror", "-Wno-error=unused-function"]
139 COMMON_GCC_CFLAGS = COMMON_CFLAGS + ["-Wno-implicit-fallthrough"]
140 COMMON_CLANG_CFLAGS = COMMON_CFLAGS + ["-Wno-error=unused-command-line-argument"]
141 GCC_32BIT_CFLAGS = COMMON_GCC_CFLAGS + ["-m32"]
142 CLANG_32BIT_CFLAGS = COMMON_CLANG_CFLAGS + ["-m32"]
143 GCC_64BIT_CFLAGS = COMMON_GCC_CFLAGS + ["-m64"]
144 CLANG_64BIT_CFLAGS = COMMON_CLANG_CFLAGS + ["-m64"]
145 CLANG_VERSION = getClangVersion()
147 # Always ran before any receipe
149 RunScript(os.path.join("external", "fetch_sources.py"))
152 # Always ran after any receipe
158 Build("clang-64-debug",
161 "clang" + CLANG_VERSION,
162 "clang++" + CLANG_VERSION,
165 Build("gcc-32-debug",
172 Build("gcc-64-release",
181 ANY_VS_X64_GENERATOR),
185 ('android-mustpass', [
186 RunScript(os.path.join("scripts", "build_android_mustpass.py"),
187 lambda env: ["--build-dir", os.path.join(env.tmpDir, "android-mustpass")]),
189 ('vulkan-mustpass', [
190 RunScript(os.path.join("external", "vulkancts", "scripts", "build_mustpass.py"),
191 lambda env: ["--build-dir", os.path.join(env.tmpDir, "vulkan-mustpass")]),
194 RunScript(os.path.join("external", "vulkancts", "scripts", "build_spirv_binaries.py"),
195 lambda env: ["--build-dir", os.path.join(env.tmpDir, "spirv-binaries")]),
198 RunScript(os.path.join("scripts", "gen_egl.py")),
199 RunScript(os.path.join("scripts", "opengl", "gen_all.py")),
200 RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework.py")),
201 RunScript(os.path.join("scripts", "gen_android_mk.py")),
202 RunScript(os.path.join("scripts", "src_util", "check_all.py")),
206 def getBuildRecipes ():
207 return [(b.getName(), [b]) for b in BUILD_TARGETS]
209 def getAllRecipe (recipes):
211 for name, steps in recipes:
213 return ("all", allSteps)
216 recipes = getBuildRecipes()
217 recipes += SPECIAL_RECIPES
220 def getRecipe (recipes, recipeName):
221 for curName, steps in recipes:
222 if curName == recipeName:
223 return (curName, steps)
226 RECIPES = getRecipes()
229 parser = argparse.ArgumentParser(description = "Build and test source",
230 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
231 parser.add_argument("-s",
235 help="Source directory")
236 parser.add_argument("-t",
239 default=os.path.join(tempfile.gettempdir(), "deqp-build-test"),
240 help="Temporary directory")
241 parser.add_argument("-r",
244 choices=[n for n, s in RECIPES] + ["all"],
246 help="Build / test recipe")
247 parser.add_argument("-d",
251 help="Print out recipes that have any available actions")
252 parser.add_argument("--skip-prerequisites",
253 dest="skipPrerequisites",
255 help="Skip external dependency fetch")
257 return parser.parse_args()
259 if __name__ == "__main__":
261 env = Environment(args.srcDir, args.tmpDir)
264 for name, steps in RECIPES:
266 if step.isAvailable(env):
270 name, steps = getAllRecipe(RECIPES) if args.recipe == "all" \
271 else getRecipe(RECIPES, args.recipe)
273 print "Running %s" % name
275 allSteps = (PREREQUISITES if (args.skipPrerequisites == False) else []) + steps + POST_CHECKS
278 print "All steps completed successfully"