summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorPyry Haulos <phaulos@google.com>2014-10-29 13:01:55 -0700
committerPyry Haulos <phaulos@google.com>2014-10-29 15:45:55 -0700
commit290f32ab4cdac8866be121c3da33bb187333f4ab (patch)
tree074fd161c6ce18ab106e14f90b9b499230569f3e /scripts
parent60d68b2463d1d6e1f8d55c55a923d304adcd1bf8 (diff)
downloadVK-GL-CTS-290f32ab4cdac8866be121c3da33bb187333f4ab.tar.gz
VK-GL-CTS-290f32ab4cdac8866be121c3da33bb187333f4ab.tar.bz2
VK-GL-CTS-290f32ab4cdac8866be121c3da33bb187333f4ab.zip
First iteration of new release script
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. Change-Id: If5073f65e7a91ec60fa7d903c9e9cfd196075944
Diffstat (limited to 'scripts')
-rw-r--r--scripts/build/build.py3
-rw-r--r--scripts/build/common.py9
-rw-r--r--scripts/build/config.py77
-rw-r--r--scripts/make_release.py512
4 files changed, 573 insertions, 28 deletions
diff --git a/scripts/build/build.py b/scripts/build/build.py
index 2ed6187c5..222c3bb16 100644
--- a/scripts/build/build.py
+++ b/scripts/build/build.py
@@ -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):
diff --git a/scripts/build/common.py b/scripts/build/common.py
index f31a20a7e..8b392686e 100644
--- a/scripts/build/common.py
+++ b/scripts/build/common.py
@@ -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
diff --git a/scripts/build/config.py b/scripts/build/config.py
index e4121aaa2..e94de67c0 100644
--- a/scripts/build/config.py
+++ b/scripts/build/config.py
@@ -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
index 000000000..d996b40bd
--- /dev/null
+++ b/scripts/make_release.py
@@ -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)