First iteration of new release script
authorPyry Haulos <phaulos@google.com>
Wed, 29 Oct 2014 20:01:55 +0000 (13:01 -0700)
committerPyry Haulos <phaulos@google.com>
Tue, 11 Nov 2014 16:55:21 +0000 (16:55 +0000)
This change restores release script from the grave and adapts it to the
new environment. Releases are now defined by a simple configuration
(source-only, bin-only, or both) and unique name. Android APK and linux64
utility binaries are currently built but not tested.

Additionally, deprecated license checks have been removed from qpInfo and
tcuApp.

Bug: 18329517
Change-Id: If5073f65e7a91ec60fa7d903c9e9cfd196075944
(cherry picked from commit 290f32ab4cdac8866be121c3da33bb187333f4ab)

framework/common/tcuApp.cpp
framework/qphelper/qpInfo.c
framework/qphelper/qpInfo.h
scripts/build/build.py
scripts/build/common.py
scripts/build/config.py
scripts/make_release.py [new file with mode: 0644]
targets/android/install.bat
targets/android/install.sh [new file with mode: 0755]
targets/android/launch.bat

index eebeab0..a0d733b 100644 (file)
@@ -66,9 +66,6 @@ App::App (Platform& platform, Archive& archive, TestLog& log, const CommandLine&
        print("dEQP Core %s (0x%08x) starting..\n", qpGetReleaseName(), qpGetReleaseId());
        print("  target implementation = '%s'\n", qpGetTargetName());
 
-       if (!qpIsLicenseValid())
-               qpPrintf("WARNING: License has expired!\n");
-
        if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST))
                qpPrintf("WARNING: Failed to set floating-point rounding mode!\n");
 
index 6589b82..49cc3d0 100644 (file)
 
 #include "qpInfo.h"
 
-#include <time.h>
-
 DE_BEGIN_EXTERN_C
 
 #define DEQP_RELEASE_NAME      "2014.x"
 #define DEQP_RELEASE_ID                0xcafebabe
-#define DEQP_LICENSE_BEGIN     0
-#define DEQP_LICENSE_END       0xffffffffu
 
 const char* qpGetTargetName (void)
 {
@@ -51,13 +47,4 @@ deUint32 qpGetReleaseId (void)
        return DEQP_RELEASE_ID;
 }
 
-deBool qpIsLicenseValid (void)
-{
-       deUint64        begin   = (deUint64)DEQP_LICENSE_BEGIN;
-       deUint64        end             = (deUint64)DEQP_LICENSE_END;
-       deUint64        curTime = (deUint64)time(DE_NULL);
-
-       return begin <= curTime && curTime <= end;
-}
-
 DE_END_EXTERN_C
index 96aaacc..58830cd 100644 (file)
@@ -31,8 +31,6 @@ const char*                   qpGetTargetName                 (void);
 const char*                    qpGetReleaseName                (void);
 deUint32                       qpGetReleaseId                  (void);
 
-deBool                         qpIsLicenseValid                (void);
-
 DE_END_EXTERN_C
 
 #endif /* _QPINFO_H */
index 2ed6187..222c3bb 100644 (file)
@@ -7,7 +7,6 @@ from common import *
 from config import *
 
 def initBuildDir (config, generator):
-       srcPath = DEQP_DIR
        cfgArgs = []
 
        # Build base configuration args
@@ -20,7 +19,7 @@ def initBuildDir (config, generator):
                os.makedirs(config.buildDir)
 
        pushWorkingDir(config.getBuildDir())
-       execute(["cmake", srcPath] + cfgArgs)
+       execute(["cmake", config.getSrcPath()] + cfgArgs)
        popWorkingDir()
 
 def build (config, generator, targets = None):
index f31a20a..8b39268 100644 (file)
@@ -42,3 +42,12 @@ def writeFile (filename, data):
        f = open(filename, 'wb')
        f.write(data)
        f.close()
+
+def which (binName):
+       for path in os.environ['PATH'].split(os.pathsep):
+               path = path.strip('"')
+               fullPath = os.path.join(path, binName)
+               if os.path.isfile(fullPath) and os.access(fullPath, os.X_OK):
+                       return fullPath
+
+       return None
index e4121aa..e94de67 100644 (file)
@@ -1,7 +1,11 @@
 # -*- coding: utf-8 -*-
 
 import os
+import copy
 import platform
+import multiprocessing
+
+from common import which, DEQP_DIR
 
 try:
        import _winreg
@@ -9,10 +13,14 @@ except:
        _winreg = None
 
 class BuildConfig:
-       def __init__ (self, buildDir, buildType, args):
+       def __init__ (self, buildDir, buildType, args, srcPath = DEQP_DIR):
+               self.srcPath            = srcPath
                self.buildDir           = buildDir
                self.buildType          = buildType
-               self.args                       = args
+               self.args                       = copy.copy(args)
+
+       def getSrcPath (self):
+               return self.srcPath
 
        def getBuildDir (self):
                return self.buildDir
@@ -24,9 +32,10 @@ class BuildConfig:
                return self.args
 
 class CMakeGenerator:
-       def __init__ (self, name, isMultiConfig = False):
+       def __init__ (self, name, isMultiConfig = False, extraBuildArgs = []):
                self.name                       = name
                self.isMultiConfig      = isMultiConfig
+               self.extraBuildArgs     = copy.copy(extraBuildArgs)
 
        def getName (self):
                return self.name
@@ -41,20 +50,26 @@ class CMakeGenerator:
                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 DefaultGenerator(CMakeGenerator):
+class UnixMakefileGenerator(CMakeGenerator):
        def __init__(self):
-               CMakeGenerator.__init__("default")
+               CMakeGenerator.__init__(self, "Unix Makefiles", extraBuildArgs = ["-j%d" % multiprocessing.cpu_count()])
 
-       def getGenerateArgs (self, buildType):
-               args = []
-               if not self.isMultiConfig:
-                       args.append('-DCMAKE_BUILD_TYPE=%s' % buildType)
-               return args
+       def isAvailable (self):
+               return which('make') != None
+
+class NinjaGenerator(CMakeGenerator):
+       def __init__(self):
+               CMakeGenerator.__init__(self, "Ninja")
+
+       def isAvailable (self):
+               return which('ninja') != None
 
 class VSProjectGenerator(CMakeGenerator):
        ARCH_32BIT      = 0
@@ -65,13 +80,10 @@ class VSProjectGenerator(CMakeGenerator):
                if arch == self.ARCH_64BIT:
                        name += " Win64"
 
-               CMakeGenerator.__init__(self, name, isMultiConfig = True)
+               CMakeGenerator.__init__(self, name, isMultiConfig = True, extraBuildArgs = ['/m'])
                self.version            = version
                self.arch                       = arch
 
-       def getBuildArgs (self, buildType):
-               return CMakeGenerator.getBuildArgs(self, buildType) + ['--', '/m']
-
        def getBinaryPath (self, buildType, basePath):
                return os.path.join(os.path.dirname(basePath), buildType, os.path.basename(basePath) + ".exe")
 
@@ -119,21 +131,34 @@ class VSProjectGenerator(CMakeGenerator):
                else:
                        return False
 
-       @staticmethod
-       def getDefault (arch):
-               for version in reversed(range(10, 13)):
-                       gen = VSProjectGenerator(version, arch)
-                       if gen.isAvailable():
-                               return gen
-               return None
-
 # Pre-defined generators
 
-MAKEFILE_GENERATOR             = CMakeGenerator("Unix Makefiles")
+MAKEFILE_GENERATOR             = UnixMakefileGenerator()
+NINJA_GENERATOR                        = NinjaGenerator()
 VS2010_X32_GENERATOR   = VSProjectGenerator(10, VSProjectGenerator.ARCH_32BIT)
 VS2010_X64_GENERATOR   = VSProjectGenerator(10, VSProjectGenerator.ARCH_64BIT)
-VS2013_X64_GENERATOR   = VSProjectGenerator(12, VSProjectGenerator.ARCH_32BIT)
+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)
 
-ANY_VS_X32_GENERATOR   = VSProjectGenerator.getDefault(VSProjectGenerator.ARCH_32BIT)
-ANY_VS_X64_GENERATOR   = VSProjectGenerator.getDefault(VSProjectGenerator.ARCH_64BIT)
+def selectFirstAvailableGenerator (generators):
+       for generator in generators:
+               if generator.isAvailable():
+                       return generator
+       return None
+
+ANY_VS_X32_GENERATOR   = selectFirstAvailableGenerator([
+                                                               VS2013_X32_GENERATOR,
+                                                               VS2012_X32_GENERATOR,
+                                                               VS2010_X32_GENERATOR,
+                                                       ])
+ANY_VS_X64_GENERATOR   = selectFirstAvailableGenerator([
+                                                               VS2013_X64_GENERATOR,
+                                                               VS2012_X64_GENERATOR,
+                                                               VS2010_X64_GENERATOR,
+                                                       ])
+ANY_UNIX_GENERATOR             = selectFirstAvailableGenerator([
+                                                               NINJA_GENERATOR,
+                                                               MAKEFILE_GENERATOR,
+                                                       ])
diff --git a/scripts/make_release.py b/scripts/make_release.py
new file mode 100644 (file)
index 0000000..d996b40
--- /dev/null
@@ -0,0 +1,512 @@
+# -*- coding: utf-8 -*-
+
+import os
+import re
+import sys
+import copy
+import zlib
+import time
+import shlex
+import shutil
+import fnmatch
+import tarfile
+import argparse
+import platform
+import datetime
+import tempfile
+import posixpath
+import subprocess
+
+from build.common import *
+from build.config import *
+from build.build import *
+
+def die (msg):
+       print msg
+       sys.exit(-1)
+
+def removeLeadingPath (path, basePath):
+       # Both inputs must be normalized already
+       assert os.path.normpath(path) == path
+       assert os.path.normpath(basePath) == basePath
+       return path[len(basePath) + 1:]
+
+def findFile (candidates):
+       for file in candidates:
+               if os.path.exists(file):
+                       return file
+       return None
+
+def getFileList (basePath):
+       allFiles        = []
+       basePath        = os.path.normpath(basePath)
+       for root, dirs, files in os.walk(basePath):
+               for file in files:
+                       relPath = removeLeadingPath(os.path.normpath(os.path.join(root, file)), basePath)
+                       allFiles.append(relPath)
+       return allFiles
+
+def toDatetime (dateTuple):
+       Y, M, D = dateTuple
+       return datetime.datetime(Y, M, D)
+
+class PackageBuildInfo:
+       def __init__ (self, releaseConfig, srcBasePath, dstBasePath, tmpBasePath):
+               self.releaseConfig      = releaseConfig
+               self.srcBasePath        = srcBasePath
+               self.dstBasePath        = dstBasePath
+               self.tmpBasePath        = tmpBasePath
+
+       def getReleaseConfig (self):
+               return self.releaseConfig
+
+       def getReleaseVersion (self):
+               return self.releaseConfig.getVersion()
+
+       def getReleaseId (self):
+               # Release id is crc32(releaseConfig + release)
+               return zlib.crc32(self.releaseConfig.getName() + self.releaseConfig.getVersion()) & 0xffffffff
+
+       def getSrcBasePath (self):
+               return self.srcBasePath
+
+       def getTmpBasePath (self):
+               return self.tmpBasePath
+
+class DstFile (object):
+       def __init__ (self, dstFile):
+               self.dstFile = dstFile
+
+       def makeDir (self):
+               dirName = os.path.dirname(self.dstFile)
+               if not os.path.exists(dirName):
+                       os.makedirs(dirName)
+
+       def make (self, packageBuildInfo):
+               assert False # Should not be called
+
+class CopyFile (DstFile):
+       def __init__ (self, srcFile, dstFile):
+               super(CopyFile, self).__init__(dstFile)
+               self.srcFile = srcFile
+
+       def make (self, packageBuildInfo):
+               self.makeDir()
+               if os.path.exists(self.dstFile):
+                       die("%s already exists" % self.dstFile)
+               shutil.copyfile(self.srcFile, self.dstFile)
+
+class GenInfoFile (DstFile):
+       def __init__ (self, srcFile, dstFile):
+               super(GenInfoFile, self).__init__(dstFile)
+               self.srcFile = srcFile
+
+       def make (self, packageBuildInfo):
+               self.makeDir()
+               print "    GenInfoFile: %s" % removeLeadingPath(self.dstFile, packageBuildInfo.dstBasePath)
+               src                     = readFile(self.srcFile)
+
+               for define, value in [("DEQP_RELEASE_NAME",     "\"%s\""        % packageBuildInfo.getReleaseVersion()),
+                                                         ("DEQP_RELEASE_ID",           "0x%08x"        % packageBuildInfo.getReleaseId())]:
+                       src = re.sub('(#\s*define\s+%s\s+)[^\n\r]+' % re.escape(define), r'\1 %s' % value, src)
+
+               writeFile(self.dstFile, src)
+
+class GenCMake (DstFile):
+       def __init__ (self, srcFile, dstFile, replaceVars):
+               super(GenCMake, self).__init__(dstFile)
+               self.srcFile            = srcFile
+               self.replaceVars        = replaceVars
+
+       def make (self, packageBuildInfo):
+               self.makeDir()
+               print "    GenCMake: %s" % removeLeadingPath(self.dstFile, packageBuildInfo.dstBasePath)
+               src = readFile(self.srcFile)
+               for var, value in self.replaceVars:
+                       src = re.sub('set\(%s\s+"[^"]*"' % re.escape(var),
+                                                'set(%s "%s"' % (var, value), src)
+               writeFile(self.dstFile, src)
+
+def createFileTargets (srcBasePath, dstBasePath, files, filters):
+       usedFiles       = set() # Files that are already included by other filters
+       targets         = []
+
+       for isMatch, createFileObj in filters:
+               # Build list of files that match filter
+               matchingFiles = []
+               for file in files:
+                       if not file in usedFiles and isMatch(file):
+                               matchingFiles.append(file)
+
+               # Build file objects, add to used set
+               for file in matchingFiles:
+                       usedFiles.add(file)
+                       targets.append(createFileObj(os.path.join(srcBasePath, file), os.path.join(dstBasePath, file)))
+
+       return targets
+
+# Generates multiple file targets based on filters
+class FileTargetGroup:
+       def __init__ (self, srcBasePath, dstBasePath, filters, srcBasePathFunc=PackageBuildInfo.getSrcBasePath):
+               self.srcBasePath        = srcBasePath
+               self.dstBasePath        = dstBasePath
+               self.filters            = filters
+               self.getSrcBasePath     = srcBasePathFunc
+
+       def make (self, packageBuildInfo):
+               fullSrcPath             = os.path.normpath(os.path.join(self.getSrcBasePath(packageBuildInfo), self.srcBasePath))
+               fullDstPath             = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, self.dstBasePath))
+
+               allFiles                = getFileList(fullSrcPath)
+               targets                 = createFileTargets(fullSrcPath, fullDstPath, allFiles, self.filters)
+
+               # Make all file targets
+               for file in targets:
+                       file.make(packageBuildInfo)
+
+# Single file target
+class SingleFileTarget:
+       def __init__ (self, srcFile, dstFile, makeTarget):
+               self.srcFile    = srcFile
+               self.dstFile    = dstFile
+               self.makeTarget = makeTarget
+
+       def make (self, packageBuildInfo):
+               fullSrcPath             = os.path.normpath(os.path.join(packageBuildInfo.srcBasePath, self.srcFile))
+               fullDstPath             = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, self.dstFile))
+
+               target = self.makeTarget(fullSrcPath, fullDstPath)
+               target.make(packageBuildInfo)
+
+class BuildTarget:
+       def __init__ (self, baseConfig, generator, targets = None):
+               self.baseConfig = baseConfig
+               self.generator  = generator
+               self.targets    = targets
+
+       def make (self, packageBuildInfo):
+               print "    Building %s" % self.baseConfig.getBuildDir()
+
+               # Create config with full build dir path
+               config = BuildConfig(os.path.join(packageBuildInfo.getTmpBasePath(), self.baseConfig.getBuildDir()),
+                                                        self.baseConfig.getBuildType(),
+                                                        self.baseConfig.getArgs(),
+                                                        srcPath = os.path.join(packageBuildInfo.dstBasePath, "src"))
+
+               assert not os.path.exists(config.getBuildDir())
+               build(config, self.generator, self.targets)
+
+class BuildAndroidTarget:
+       def __init__ (self, dstFile):
+               self.dstFile = dstFile
+
+       def make (self, packageBuildInfo):
+               print "    Building Android binary"
+
+               buildRoot = os.path.join(packageBuildInfo.tmpBasePath, "android-build")
+
+               assert not os.path.exists(buildRoot)
+               os.makedirs(buildRoot)
+
+               # Execute build script
+               scriptPath = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, "src", "android", "scripts", "build.py"))
+               execute([
+                               "python",
+                               "-B", # no .py[co]
+                               scriptPath,
+                               "--build-root=%s" % buildRoot,
+                       ])
+
+               srcFile         = os.path.normpath(os.path.join(buildRoot, "package", "bin", "dEQP-debug.apk"))
+               dstFile         = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, self.dstFile))
+
+               CopyFile(srcFile, dstFile).make(packageBuildInfo)
+
+class FetchExternalSourcesTarget:
+       def __init__ (self):
+               pass
+
+       def make (self, packageBuildInfo):
+               scriptPath = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, "src", "external", "fetch_sources.py"))
+               execute([
+                               "python",
+                               "-B", # no .py[co]
+                               scriptPath,
+                       ])
+
+class RemoveSourcesTarget:
+       def __init__ (self):
+               pass
+
+       def make (self, packageBuildInfo):
+               shutil.rmtree(os.path.join(packageBuildInfo.dstBasePath, "src"), ignore_errors=False)
+
+class Module:
+       def __init__ (self, name, targets):
+               self.name               = name
+               self.targets    = targets
+
+       def make (self, packageBuildInfo):
+               for target in self.targets:
+                       target.make(packageBuildInfo)
+
+class ReleaseConfig:
+       def __init__ (self, name, version, modules, sources = True):
+               self.name                       = name
+               self.version            = version
+               self.modules            = modules
+               self.sources            = sources
+
+       def getName (self):
+               return self.name
+
+       def getVersion (self):
+               return self.version
+
+       def getModules (self):
+               return self.modules
+
+       def packageWithSources (self):
+               return self.sources
+
+def matchIncludeExclude (includePatterns, excludePatterns, filename):
+       components = os.path.normpath(filename).split(os.sep)
+       for pattern in excludePatterns:
+               for component in components:
+                       if fnmatch.fnmatch(component, pattern):
+                               return False
+
+       for pattern in includePatterns:
+               for component in components:
+                       if fnmatch.fnmatch(component, pattern):
+                               return True
+
+       return False
+
+def copyFileFilter (includePatterns, excludePatterns=[]):
+       return (lambda f: matchIncludeExclude(includePatterns, excludePatterns, f),
+                       lambda s, d: CopyFile(s, d))
+
+def makeFileCopyGroup (srcDir, dstDir, includePatterns, excludePatterns=[]):
+       return FileTargetGroup(srcDir, dstDir, [copyFileFilter(includePatterns, excludePatterns)])
+
+def makeTmpFileCopyGroup (srcDir, dstDir, includePatterns, excludePatterns=[]):
+       return FileTargetGroup(srcDir, dstDir, [copyFileFilter(includePatterns, excludePatterns)], PackageBuildInfo.getTmpBasePath)
+
+def makeFileCopy (srcFile, dstFile):
+       return SingleFileTarget(srcFile, dstFile, lambda s, d: CopyFile(s, d))
+
+def getReleaseFileName (configName, releaseName):
+       today = datetime.date.today()
+       return "dEQP-%s-%04d-%02d-%02d-%s" % (releaseName, today.year, today.month, today.day, configName)
+
+def getTempDir ():
+       dirName = os.path.join(tempfile.gettempdir(), "dEQP-Releases")
+       if not os.path.exists(dirName):
+               os.makedirs(dirName)
+       return dirName
+
+def makeRelease (releaseConfig):
+       releaseName                     = getReleaseFileName(releaseConfig.getName(), releaseConfig.getVersion())
+       tmpPath                         = getTempDir()
+       srcBasePath                     = DEQP_DIR
+       dstBasePath                     = os.path.join(tmpPath, releaseName)
+       tmpBasePath                     = os.path.join(tmpPath, releaseName + "-tmp")
+       packageBuildInfo        = PackageBuildInfo(releaseConfig, srcBasePath, dstBasePath, tmpBasePath)
+       dstArchiveName          = releaseName + ".tar.bz2"
+
+       print "Creating release %s to %s" % (releaseName, tmpPath)
+
+       # Remove old temporary dirs
+       for path in [dstBasePath, tmpBasePath]:
+               if os.path.exists(path):
+                       shutil.rmtree(path, ignore_errors=False)
+
+       # Make all modules
+       for module in releaseConfig.getModules():
+               print "  Processing module %s" % module.name
+               module.make(packageBuildInfo)
+
+       # Remove sources?
+       if not releaseConfig.packageWithSources():
+               shutil.rmtree(os.path.join(dstBasePath, "src"), ignore_errors=False)
+
+       # Create archive
+       print "Creating %s" % dstArchiveName
+       archive = tarfile.open(dstArchiveName, 'w:bz2')
+       archive.add(dstBasePath, arcname=releaseName)
+       archive.close()
+
+       # Remove tmp dirs
+       for path in [dstBasePath, tmpBasePath]:
+               if os.path.exists(path):
+                       shutil.rmtree(path, ignore_errors=False)
+
+       print "Done!"
+
+# Module declarations
+
+SRC_FILE_PATTERNS      = ["*.h", "*.hpp", "*.c", "*.cpp", "*.m", "*.mm", "*.inl", "*.java", "*.aidl", "CMakeLists.txt", "LICENSE.txt", "*.cmake"]
+TARGET_PATTERNS                = ["*.cmake", "*.h", "*.lib", "*.dll", "*.so", "*.txt"]
+
+BASE = Module("Base", [
+       makeFileCopy            ("LICENSE",                                                                     "src/LICENSE"),
+       makeFileCopy            ("CMakeLists.txt",                                                      "src/CMakeLists.txt"),
+       makeFileCopyGroup       ("targets",                                                                     "src/targets",                                                  TARGET_PATTERNS),
+       makeFileCopyGroup       ("execserver",                                                          "src/execserver",                                               SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("executor",                                                            "src/executor",                                                 SRC_FILE_PATTERNS),
+       makeFileCopy            ("modules/CMakeLists.txt",                                      "src/modules/CMakeLists.txt"),
+       makeFileCopyGroup       ("external",                                                            "src/external",                                                 ["CMakeLists.txt", "*.py"]),
+
+       # Stylesheet for displaying test logs on browser
+       makeFileCopyGroup       ("doc/testlog-stylesheet",                                      "doc/testlog-stylesheet",                               ["*"]),
+
+       # Non-optional parts of framework
+       # \note qpInfo.c must be processed!
+       FileTargetGroup         ("framework", "src/framework", [
+                       # If file is qpInfo.c use GenInfoFile
+                       (lambda f: f[-8:] == "qpInfo.c", lambda s, d: GenInfoFile(s, d)),
+                       # Otherwise just CopyFile targets
+                       copyFileFilter(SRC_FILE_PATTERNS, ["imagedifftester", "randomshaders", "simplereference", "referencerenderer"])
+               ]),
+
+       # Main modules CMakeLists.txt
+
+       # android sources
+       makeFileCopyGroup       ("android/package/src",                                         "src/android/package/src",                              SRC_FILE_PATTERNS),
+       makeFileCopy            ("android/package/AndroidManifest.xml",         "src/android/package/AndroidManifest.xml"),
+       makeFileCopyGroup       ("android/package/res",                                         "src/android/package/res",                              ["*.png", "*.xml"]),
+       makeFileCopyGroup       ("android/scripts",                                                     "src/android/scripts", [
+               "common.py",
+               "build.py",
+               "resources.py",
+               "install.py",
+               "launch.py",
+               "debug.py"
+               ]),
+])
+
+DOCUMENTATION = Module("Documentation", [
+       makeFileCopyGroup       ("doc/pdf",                                                                     "doc",                                                                  ["*.pdf"]),
+       makeFileCopyGroup       ("doc",                                                                         "doc",                                                                  ["porting_layer_changes_*.txt"]),
+])
+
+GLSHARED = Module("Shared GL Tests", [
+       # Optional framework components
+       makeFileCopyGroup       ("framework/randomshaders",                                     "src/framework/randomshaders",                  SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("framework/opengl/simplereference",            "src/framework/opengl/simplereference", SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("framework/referencerenderer",                         "src/framework/referencerenderer",              SRC_FILE_PATTERNS),
+
+       makeFileCopyGroup       ("modules/glshared",                                            "src/modules/glshared",                                 SRC_FILE_PATTERNS),
+])
+
+GLES2 = Module("GLES2", [
+       makeFileCopyGroup       ("modules/gles2",                                                       "src/modules/gles2",                                    SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("data/gles2",                                                          "src/data/gles2",                                               ["*.*"]),
+       makeFileCopyGroup       ("doc/testspecs/GLES2",                                         "doc/testspecs/GLES2",                                  ["*.txt"])
+])
+
+GLES3 = Module("GLES3", [
+       makeFileCopyGroup       ("modules/gles3",                                                       "src/modules/gles3",                                    SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("data/gles3",                                                          "src/data/gles3",                                               ["*.*"]),
+       makeFileCopyGroup       ("doc/testspecs/GLES3",                                         "doc/testspecs/GLES3",                                  ["*.txt"])
+])
+
+GLES31 = Module("GLES31", [
+       makeFileCopyGroup       ("modules/gles31",                                                      "src/modules/gles31",                                   SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("data/gles31",                                                         "src/data/gles31",                                              ["*.*"]),
+       makeFileCopyGroup       ("doc/testspecs/GLES31",                                        "doc/testspecs/GLES31",                                 ["*.txt"])
+])
+
+EGL = Module("EGL", [
+       makeFileCopyGroup       ("modules/egl",                                                         "src/modules/egl",                                              SRC_FILE_PATTERNS)
+])
+
+INTERNAL = Module("Internal", [
+       makeFileCopyGroup       ("modules/internal",                                            "src/modules/internal",                                 SRC_FILE_PATTERNS),
+       makeFileCopyGroup       ("data/internal",                                                       "src/data/internal",                                    ["*.*"]),
+])
+
+EXTERNAL_SRCS = Module("External sources", [
+       FetchExternalSourcesTarget()
+])
+
+ANDROID_BINARIES = Module("Android Binaries", [
+       BuildAndroidTarget      ("bin/android/dEQP.apk"),
+       makeFileCopyGroup       ("targets/android",                                                     "bin/android",                                                  ["*.bat", "*.sh"]),
+])
+
+COMMON_BUILD_ARGS      = ['-DPNG_SRC_PATH=%s' % os.path.realpath(os.path.join(DEQP_DIR, '..', 'libpng'))]
+NULL_X32_CONFIG                = BuildConfig('null-x32',       'Release', ['-DDEQP_TARGET=null', '-DCMAKE_C_FLAGS=-m32', '-DCMAKE_CXX_FLAGS=-m32'] + COMMON_BUILD_ARGS)
+NULL_X64_CONFIG                = BuildConfig('null-x64',       'Release', ['-DDEQP_TARGET=null', '-DCMAKE_C_FLAGS=-m64', '-DCMAKE_CXX_FLAGS=-m64'] + COMMON_BUILD_ARGS)
+GLX_X32_CONFIG         = BuildConfig('glx-x32',        'Release', ['-DDEQP_TARGET=x11_glx', '-DCMAKE_C_FLAGS=-m32', '-DCMAKE_CXX_FLAGS=-m32'] + COMMON_BUILD_ARGS)
+GLX_X64_CONFIG         = BuildConfig('glx-x64',        'Release', ['-DDEQP_TARGET=x11_glx', '-DCMAKE_C_FLAGS=-m64', '-DCMAKE_CXX_FLAGS=-m64'] + COMMON_BUILD_ARGS)
+
+EXCLUDE_BUILD_FILES = ["CMakeFiles", "*.a", "*.cmake"]
+
+LINUX_X32_COMMON_BINARIES = Module("Linux x32 Common Binaries", [
+       BuildTarget                     (NULL_X32_CONFIG, ANY_UNIX_GENERATOR),
+       makeTmpFileCopyGroup(NULL_X32_CONFIG.getBuildDir() + "/execserver",             "bin/linux32",                                  ["*"],  EXCLUDE_BUILD_FILES),
+       makeTmpFileCopyGroup(NULL_X32_CONFIG.getBuildDir() + "/executor",               "bin/linux32",                                  ["*"],  EXCLUDE_BUILD_FILES),
+])
+
+LINUX_X64_COMMON_BINARIES = Module("Linux x64 Common Binaries", [
+       BuildTarget                     (NULL_X64_CONFIG, ANY_UNIX_GENERATOR),
+       makeTmpFileCopyGroup(NULL_X64_CONFIG.getBuildDir() + "/execserver",             "bin/linux64",                                  ["*"],  EXCLUDE_BUILD_FILES),
+       makeTmpFileCopyGroup(NULL_X64_CONFIG.getBuildDir() + "/executor",               "bin/linux64",                                  ["*"],  EXCLUDE_BUILD_FILES),
+])
+
+# Special module to remove src dir, for example after binary build
+REMOVE_SOURCES = Module("Remove sources from package", [
+       RemoveSourcesTarget()
+])
+
+# Release configuration
+
+ALL_MODULES            = [
+       BASE,
+       DOCUMENTATION,
+       GLSHARED,
+       GLES2,
+       GLES3,
+       GLES31,
+       EGL,
+       INTERNAL,
+       EXTERNAL_SRCS,
+]
+
+ALL_BINARIES   = [
+       LINUX_X64_COMMON_BINARIES,
+       ANDROID_BINARIES,
+]
+
+RELEASE_CONFIGS        = {
+       "src":          ALL_MODULES,
+       "src-bin":      ALL_MODULES + ALL_BINARIES,
+       "bin":          ALL_MODULES + ALL_BINARIES + [REMOVE_SOURCES],
+}
+
+def parseArgs ():
+       parser = argparse.ArgumentParser(description = "Build release package")
+       parser.add_argument("-c",
+                                               "--config",
+                                               dest="config",
+                                               choices=RELEASE_CONFIGS.keys(),
+                                               required=True,
+                                               help="Release configuration")
+       parser.add_argument("-n",
+                                               "--name",
+                                               dest="name",
+                                               required=True,
+                                               help="Package-specific name")
+       parser.add_argument("-v",
+                                               "--version",
+                                               dest="version",
+                                               required=True,
+                                               help="Version code")
+       return parser.parse_args()
+
+if __name__ == "__main__":
+       args    = parseArgs()
+       config  = ReleaseConfig(args.name, args.version, RELEASE_CONFIGS[args.config])
+       makeRelease(config)
index a7be860..42534b1 100644 (file)
@@ -1,6 +1,6 @@
 @echo off
 echo Removing old dEQP Ondevice Package...
-adb %* uninstall com.drawelements.deqp.execserver
+adb %* uninstall com.drawelements.deqp
 
 echo Installing dEQP Ondevice Package...
-adb %* install -r dEQP-ondevice.apk
+adb %* install -r dEQP.apk
diff --git a/targets/android/install.sh b/targets/android/install.sh
new file mode 100755 (executable)
index 0000000..1ac9130
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+echo "Removing old dEQP Ondevice Package..."
+adb $* uninstall com.drawelements.deqp
+
+echo "Installing dEQP Ondevice Package..."
+adb $* install -r dEQP.apk
index 05e6d77..2f89947 100644 (file)
@@ -1,4 +1,4 @@
 @echo off
 adb %* forward tcp:50016 tcp:50016
 adb %* shell setprop log.tag.dEQP DEBUG
-adb %* shell am start -n com.drawelements.deqp.execserver/.ServiceStarter
+adb %* shell am start -n com.drawelements.deqp/.execserver.ServiceStarter