Merge "Add script for build- and sanity-checking source code"
authorTreehugger Robot <treehugger-gerrit@google.com>
Fri, 12 Aug 2016 21:19:40 +0000 (21:19 +0000)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Fri, 12 Aug 2016 21:19:40 +0000 (21:19 +0000)
scripts/check_build_sanity.py [new file with mode: 0644]

diff --git a/scripts/check_build_sanity.py b/scripts/check_build_sanity.py
new file mode 100644 (file)
index 0000000..f161b2e
--- /dev/null
@@ -0,0 +1,192 @@
+# -*- coding: utf-8 -*-
+
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2016 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 argparse
+import tempfile
+
+from build.common import *
+from build.build import *
+
+class Environment:
+       def __init__ (self, srcDir, tmpDir):
+               self.srcDir     = srcDir
+               self.tmpDir     = tmpDir
+
+class BuildTestStep:
+       def getName (self):
+               return "<unknown>"
+
+       def isAvailable (self, env):
+               return True
+
+       def run (self, env):
+               raise Exception("Not implemented")
+
+class RunScript(BuildTestStep):
+       def __init__ (self, scriptPath):
+               self.scriptPath = scriptPath
+
+       def getName (self):
+               return self.scriptPath
+
+       def run (self, env):
+               execute(["python", os.path.join(env.srcDir, self.scriptPath)])
+
+def makeCflagsArgs (cflags):
+       cflagsStr = " ".join(cflags)
+       return ["-DCMAKE_C_FLAGS=%s" % cflagsStr, "-DCMAKE_CXX_FLAGS=%s" % cflagsStr]
+
+def makeBuildArgs (target, cc, cpp, cflags):
+       return ["-DDEQP_TARGET=%s" % target, "-DCMAKE_C_COMPILER=%s" % cc, "-DCMAKE_CXX_COMPILER=%s" % cpp] + makeCflagsArgs(cflags)
+
+class BuildConfigGen:
+       def isAvailable (self, env):
+               return True
+
+class UnixConfig(BuildConfigGen):
+       def __init__ (self, target, buildType, cc, cpp, cflags):
+               self.target             = target
+               self.buildType  = buildType
+               self.cc                 = cc
+               self.cpp                = cpp
+               self.cflags             = cflags
+
+       def isAvailable (self, env):
+               return which(self.cc) != None and which(self.cpp) != None
+
+       def getBuildConfig (self, env, buildDir):
+               args = makeBuildArgs(self.target, self.cc, self.cpp, self.cflags)
+               return BuildConfig(buildDir, self.buildType, args, env.srcDir)
+
+class VSConfig(BuildConfigGen):
+       def __init__ (self, buildType):
+               self.buildType = buildType
+
+       def getBuildConfig (self, env, buildDir):
+               args = ["-DCMAKE_C_FLAGS=/WX -DCMAKE_CXX_FLAGS=/WX"]
+               return BuildConfig(buildDir, self.buildType, args, env.srcDir)
+
+class Build(BuildTestStep):
+       def __init__ (self, buildDir, configGen, generator):
+               self.buildDir   = buildDir
+               self.configGen  = configGen
+               self.generator  = generator
+
+       def getName (self):
+               return self.buildDir
+
+       def isAvailable (self, env):
+               return self.configGen.isAvailable(env) and self.generator != None and self.generator.isAvailable()
+
+       def run (self, env):
+               # specialize config for env
+               buildDir        = os.path.join(env.tmpDir, self.buildDir)
+               curConfig       = self.configGen.getBuildConfig(env, buildDir)
+
+               build(curConfig, self.generator)
+
+class CheckSrcChanges(BuildTestStep):
+       def getName (self):
+               return "check for changes"
+
+       def run (self, env):
+               pushWorkingDir(env.srcDir)
+               execute(["git", "diff", "--exit-code"])
+               popWorkingDir()
+
+def getClangVersion ():
+       knownVersions = ["4.0", "3.9", "3.8", "3.7", "3.6", "3.5"]
+       for version in knownVersions:
+               if which("clang-" + version) != None:
+                       return "-" + version
+       return ""
+
+COMMON_GCC_CFLAGS      = ["-Werror"]
+COMMON_CLANG_CFLAGS    = COMMON_GCC_CFLAGS + ["-Wno-error=unused-command-line-argument"]
+GCC_32BIT_CFLAGS       = COMMON_GCC_CFLAGS + ["-m32"]
+CLANG_32BIT_CFLAGS     = COMMON_CLANG_CFLAGS + ["-m32"]
+GCC_64BIT_CFLAGS       = COMMON_GCC_CFLAGS + ["-m64"]
+CLANG_64BIT_CFLAGS     = COMMON_CLANG_CFLAGS + ["-m64"]
+CLANG_VERSION          = getClangVersion()
+
+STEPS = [
+       RunScript(os.path.join("external", "fetch_sources.py")),
+       Build("clang-64-debug",
+                 UnixConfig("null",
+                                        "Debug",
+                                        "clang" + CLANG_VERSION,
+                                        "clang++" + CLANG_VERSION,
+                                        CLANG_64BIT_CFLAGS),
+                 ANY_UNIX_GENERATOR),
+       Build("gcc-32-debug",
+                 UnixConfig("null",
+                                        "Debug",
+                                        "gcc",
+                                        "g++",
+                                        GCC_32BIT_CFLAGS),
+                 ANY_UNIX_GENERATOR),
+       Build("gcc-64-release",
+                 UnixConfig("null",
+                                        "Release",
+                                        "gcc",
+                                        "g++",
+                                        GCC_32BIT_CFLAGS),
+                 ANY_UNIX_GENERATOR),
+       Build("vs-64-debug",
+                 VSConfig("Debug"),
+                 ANY_VS_X64_GENERATOR),
+       RunScript(os.path.join("scripts", "build_android_mustpass.py")),
+       RunScript(os.path.join("external", "vulkancts", "build_mustpass.py")),
+       RunScript(os.path.join("scripts", "gen_egl.py")),
+       RunScript(os.path.join("scripts", "opengl", "gen_all.py")),
+       CheckSrcChanges(),
+]
+
+def parseArgs ():
+       parser = argparse.ArgumentParser(description = "Build and test source",
+                                                                        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+
+       parser.add_argument("-s",
+                                               "--src-dir",
+                                               dest="srcDir",
+                                               default=DEQP_DIR,
+                                               help="Source directory")
+       parser.add_argument("-t",
+                                               "--tmp-dir",
+                                               dest="tmpDir",
+                                               default=os.path.join(tempfile.gettempdir(), "deqp-build-test"),
+                                               help="Temporary directory")
+       return parser.parse_args()
+
+if __name__ == "__main__":
+       args    = parseArgs()
+       env             = Environment(args.srcDir, args.tmpDir)
+
+       for step in STEPS:
+               if step.isAvailable(env):
+                       print "Run: %s" % step.getName()
+                       step.run(env)
+               else:
+                       print "Skip: %s" % step.getName()
+
+       print "All steps completed successfully"