1e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*-
2e5c31af7Sopenharmony_ci
3e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci# drawElements Quality Program utilities
5e5c31af7Sopenharmony_ci# --------------------------------------
6e5c31af7Sopenharmony_ci#
7e5c31af7Sopenharmony_ci# Copyright 2015 The Android Open Source Project
8e5c31af7Sopenharmony_ci#
9e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci# You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci#
13e5c31af7Sopenharmony_ci#      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci#
15e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci# limitations under the License.
20e5c31af7Sopenharmony_ci#
21e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
22e5c31af7Sopenharmony_ci
23e5c31af7Sopenharmony_ciimport os
24e5c31af7Sopenharmony_ciimport re
25e5c31af7Sopenharmony_ciimport sys
26e5c31af7Sopenharmony_ciimport copy
27e5c31af7Sopenharmony_ciimport zlib
28e5c31af7Sopenharmony_ciimport time
29e5c31af7Sopenharmony_ciimport shlex
30e5c31af7Sopenharmony_ciimport shutil
31e5c31af7Sopenharmony_ciimport fnmatch
32e5c31af7Sopenharmony_ciimport tarfile
33e5c31af7Sopenharmony_ciimport argparse
34e5c31af7Sopenharmony_ciimport platform
35e5c31af7Sopenharmony_ciimport datetime
36e5c31af7Sopenharmony_ciimport tempfile
37e5c31af7Sopenharmony_ciimport posixpath
38e5c31af7Sopenharmony_ciimport subprocess
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_cifrom ctsbuild.common import *
41e5c31af7Sopenharmony_cifrom ctsbuild.config import *
42e5c31af7Sopenharmony_cifrom ctsbuild.build import *
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_cipythonExecutable = sys.executable or "python"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_cidef die (msg):
47e5c31af7Sopenharmony_ci	print(msg)
48e5c31af7Sopenharmony_ci	sys.exit(-1)
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_cidef removeLeadingPath (path, basePath):
51e5c31af7Sopenharmony_ci	# Both inputs must be normalized already
52e5c31af7Sopenharmony_ci	assert os.path.normpath(path) == path
53e5c31af7Sopenharmony_ci	assert os.path.normpath(basePath) == basePath
54e5c31af7Sopenharmony_ci	return path[len(basePath) + 1:]
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_cidef findFile (candidates):
57e5c31af7Sopenharmony_ci	for file in candidates:
58e5c31af7Sopenharmony_ci		if os.path.exists(file):
59e5c31af7Sopenharmony_ci			return file
60e5c31af7Sopenharmony_ci	return None
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_cidef getFileList (basePath):
63e5c31af7Sopenharmony_ci	allFiles	= []
64e5c31af7Sopenharmony_ci	basePath	= os.path.normpath(basePath)
65e5c31af7Sopenharmony_ci	for root, dirs, files in os.walk(basePath):
66e5c31af7Sopenharmony_ci		for file in files:
67e5c31af7Sopenharmony_ci			relPath = removeLeadingPath(os.path.normpath(os.path.join(root, file)), basePath)
68e5c31af7Sopenharmony_ci			allFiles.append(relPath)
69e5c31af7Sopenharmony_ci	return allFiles
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_cidef toDatetime (dateTuple):
72e5c31af7Sopenharmony_ci	Y, M, D = dateTuple
73e5c31af7Sopenharmony_ci	return datetime.datetime(Y, M, D)
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ciclass PackageBuildInfo:
76e5c31af7Sopenharmony_ci	def __init__ (self, releaseConfig, srcBasePath, dstBasePath, tmpBasePath):
77e5c31af7Sopenharmony_ci		self.releaseConfig	= releaseConfig
78e5c31af7Sopenharmony_ci		self.srcBasePath	= srcBasePath
79e5c31af7Sopenharmony_ci		self.dstBasePath	= dstBasePath
80e5c31af7Sopenharmony_ci		self.tmpBasePath	= tmpBasePath
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	def getReleaseConfig (self):
83e5c31af7Sopenharmony_ci		return self.releaseConfig
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_ci	def getReleaseVersion (self):
86e5c31af7Sopenharmony_ci		return self.releaseConfig.getVersion()
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci	def getReleaseId (self):
89e5c31af7Sopenharmony_ci		# Release id is crc32(releaseConfig + release)
90e5c31af7Sopenharmony_ci		return zlib.crc32(self.releaseConfig.getName() + self.releaseConfig.getVersion()) & 0xffffffff
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_ci	def getSrcBasePath (self):
93e5c31af7Sopenharmony_ci		return self.srcBasePath
94e5c31af7Sopenharmony_ci
95e5c31af7Sopenharmony_ci	def getTmpBasePath (self):
96e5c31af7Sopenharmony_ci		return self.tmpBasePath
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ciclass DstFile (object):
99e5c31af7Sopenharmony_ci	def __init__ (self, dstFile):
100e5c31af7Sopenharmony_ci		self.dstFile = dstFile
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_ci	def makeDir (self):
103e5c31af7Sopenharmony_ci		dirName = os.path.dirname(self.dstFile)
104e5c31af7Sopenharmony_ci		if not os.path.exists(dirName):
105e5c31af7Sopenharmony_ci			os.makedirs(dirName)
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
108e5c31af7Sopenharmony_ci		assert False # Should not be called
109e5c31af7Sopenharmony_ci
110e5c31af7Sopenharmony_ciclass CopyFile (DstFile):
111e5c31af7Sopenharmony_ci	def __init__ (self, srcFile, dstFile):
112e5c31af7Sopenharmony_ci		super(CopyFile, self).__init__(dstFile)
113e5c31af7Sopenharmony_ci		self.srcFile = srcFile
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
116e5c31af7Sopenharmony_ci		self.makeDir()
117e5c31af7Sopenharmony_ci		if os.path.exists(self.dstFile):
118e5c31af7Sopenharmony_ci			die("%s already exists" % self.dstFile)
119e5c31af7Sopenharmony_ci		shutil.copyfile(self.srcFile, self.dstFile)
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ciclass GenReleaseInfoFileTarget (DstFile):
122e5c31af7Sopenharmony_ci	def __init__ (self, dstFile):
123e5c31af7Sopenharmony_ci		super(GenReleaseInfoFileTarget, self).__init__(dstFile)
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
126e5c31af7Sopenharmony_ci		self.makeDir()
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_ci		scriptPath = os.path.normpath(os.path.join(packageBuildInfo.srcBasePath, "framework", "qphelper", "gen_release_info.py"))
129e5c31af7Sopenharmony_ci		execute([
130e5c31af7Sopenharmony_ci				pythonExecutable,
131e5c31af7Sopenharmony_ci				"-B", # no .py[co]
132e5c31af7Sopenharmony_ci				scriptPath,
133e5c31af7Sopenharmony_ci				"--name=%s" % packageBuildInfo.getReleaseVersion(),
134e5c31af7Sopenharmony_ci				"--id=0x%08x" % packageBuildInfo.getReleaseId(),
135e5c31af7Sopenharmony_ci				"--out=%s" % self.dstFile
136e5c31af7Sopenharmony_ci			])
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_ciclass GenCMake (DstFile):
139e5c31af7Sopenharmony_ci	def __init__ (self, srcFile, dstFile, replaceVars):
140e5c31af7Sopenharmony_ci		super(GenCMake, self).__init__(dstFile)
141e5c31af7Sopenharmony_ci		self.srcFile		= srcFile
142e5c31af7Sopenharmony_ci		self.replaceVars	= replaceVars
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
145e5c31af7Sopenharmony_ci		self.makeDir()
146e5c31af7Sopenharmony_ci		print("    GenCMake: %s" % removeLeadingPath(self.dstFile, packageBuildInfo.dstBasePath))
147e5c31af7Sopenharmony_ci		src = readFile(self.srcFile)
148e5c31af7Sopenharmony_ci		for var, value in self.replaceVars:
149e5c31af7Sopenharmony_ci			src = re.sub('set\(%s\s+"[^"]*"' % re.escape(var),
150e5c31af7Sopenharmony_ci						 'set(%s "%s"' % (var, value), src)
151e5c31af7Sopenharmony_ci		writeFile(self.dstFile, src)
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_cidef createFileTargets (srcBasePath, dstBasePath, files, filters):
154e5c31af7Sopenharmony_ci	usedFiles	= set() # Files that are already included by other filters
155e5c31af7Sopenharmony_ci	targets		= []
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ci	for isMatch, createFileObj in filters:
158e5c31af7Sopenharmony_ci		# Build list of files that match filter
159e5c31af7Sopenharmony_ci		matchingFiles = []
160e5c31af7Sopenharmony_ci		for file in files:
161e5c31af7Sopenharmony_ci			if not file in usedFiles and isMatch(file):
162e5c31af7Sopenharmony_ci				matchingFiles.append(file)
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci		# Build file objects, add to used set
165e5c31af7Sopenharmony_ci		for file in matchingFiles:
166e5c31af7Sopenharmony_ci			usedFiles.add(file)
167e5c31af7Sopenharmony_ci			targets.append(createFileObj(os.path.join(srcBasePath, file), os.path.join(dstBasePath, file)))
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	return targets
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_ci# Generates multiple file targets based on filters
172e5c31af7Sopenharmony_ciclass FileTargetGroup:
173e5c31af7Sopenharmony_ci	def __init__ (self, srcBasePath, dstBasePath, filters, srcBasePathFunc=PackageBuildInfo.getSrcBasePath):
174e5c31af7Sopenharmony_ci		self.srcBasePath	= srcBasePath
175e5c31af7Sopenharmony_ci		self.dstBasePath	= dstBasePath
176e5c31af7Sopenharmony_ci		self.filters		= filters
177e5c31af7Sopenharmony_ci		self.getSrcBasePath	= srcBasePathFunc
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
180e5c31af7Sopenharmony_ci		fullSrcPath		= os.path.normpath(os.path.join(self.getSrcBasePath(packageBuildInfo), self.srcBasePath))
181e5c31af7Sopenharmony_ci		fullDstPath		= os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, self.dstBasePath))
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_ci		allFiles		= getFileList(fullSrcPath)
184e5c31af7Sopenharmony_ci		targets			= createFileTargets(fullSrcPath, fullDstPath, allFiles, self.filters)
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ci		# Make all file targets
187e5c31af7Sopenharmony_ci		for file in targets:
188e5c31af7Sopenharmony_ci			file.make(packageBuildInfo)
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ci# Single file target
191e5c31af7Sopenharmony_ciclass SingleFileTarget:
192e5c31af7Sopenharmony_ci	def __init__ (self, srcFile, dstFile, makeTarget):
193e5c31af7Sopenharmony_ci		self.srcFile	= srcFile
194e5c31af7Sopenharmony_ci		self.dstFile	= dstFile
195e5c31af7Sopenharmony_ci		self.makeTarget	= makeTarget
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
198e5c31af7Sopenharmony_ci		fullSrcPath		= os.path.normpath(os.path.join(packageBuildInfo.srcBasePath, self.srcFile))
199e5c31af7Sopenharmony_ci		fullDstPath		= os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, self.dstFile))
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ci		target = self.makeTarget(fullSrcPath, fullDstPath)
202e5c31af7Sopenharmony_ci		target.make(packageBuildInfo)
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_ciclass BuildTarget:
205e5c31af7Sopenharmony_ci	def __init__ (self, baseConfig, generator, targets = None):
206e5c31af7Sopenharmony_ci		self.baseConfig	= baseConfig
207e5c31af7Sopenharmony_ci		self.generator	= generator
208e5c31af7Sopenharmony_ci		self.targets	= targets
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
211e5c31af7Sopenharmony_ci		print("    Building %s" % self.baseConfig.getBuildDir())
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci		# Create config with full build dir path
214e5c31af7Sopenharmony_ci		config = BuildConfig(os.path.join(packageBuildInfo.getTmpBasePath(), self.baseConfig.getBuildDir()),
215e5c31af7Sopenharmony_ci							 self.baseConfig.getBuildType(),
216e5c31af7Sopenharmony_ci							 self.baseConfig.getArgs(),
217e5c31af7Sopenharmony_ci							 srcPath = os.path.join(packageBuildInfo.dstBasePath, "src"))
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_ci		assert not os.path.exists(config.getBuildDir())
220e5c31af7Sopenharmony_ci		build(config, self.generator, self.targets)
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ciclass BuildAndroidTarget:
223e5c31af7Sopenharmony_ci	def __init__ (self, dstFile):
224e5c31af7Sopenharmony_ci		self.dstFile = dstFile
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
227e5c31af7Sopenharmony_ci		print("    Building Android binary")
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci		buildRoot = os.path.join(packageBuildInfo.tmpBasePath, "android-build")
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci		assert not os.path.exists(buildRoot)
232e5c31af7Sopenharmony_ci		os.makedirs(buildRoot)
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ci		# Execute build script
235e5c31af7Sopenharmony_ci		scriptPath = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, "src", "android", "scripts", "build.py"))
236e5c31af7Sopenharmony_ci		execute([
237e5c31af7Sopenharmony_ci				pythonExecutable,
238e5c31af7Sopenharmony_ci				"-B", # no .py[co]
239e5c31af7Sopenharmony_ci				scriptPath,
240e5c31af7Sopenharmony_ci				"--build-root=%s" % buildRoot,
241e5c31af7Sopenharmony_ci			])
242e5c31af7Sopenharmony_ci
243e5c31af7Sopenharmony_ci		srcFile		= os.path.normpath(os.path.join(buildRoot, "package", "bin", "dEQP-debug.apk"))
244e5c31af7Sopenharmony_ci		dstFile		= os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, self.dstFile))
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci		CopyFile(srcFile, dstFile).make(packageBuildInfo)
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_ciclass FetchExternalSourcesTarget:
249e5c31af7Sopenharmony_ci	def __init__ (self):
250e5c31af7Sopenharmony_ci		pass
251e5c31af7Sopenharmony_ci
252e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
253e5c31af7Sopenharmony_ci		scriptPath = os.path.normpath(os.path.join(packageBuildInfo.dstBasePath, "src", "external", "fetch_sources.py"))
254e5c31af7Sopenharmony_ci		execute([
255e5c31af7Sopenharmony_ci				pythonExecutable,
256e5c31af7Sopenharmony_ci				"-B", # no .py[co]
257e5c31af7Sopenharmony_ci				scriptPath,
258e5c31af7Sopenharmony_ci			])
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ciclass RemoveSourcesTarget:
261e5c31af7Sopenharmony_ci	def __init__ (self):
262e5c31af7Sopenharmony_ci		pass
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
265e5c31af7Sopenharmony_ci		shutil.rmtree(os.path.join(packageBuildInfo.dstBasePath, "src"), ignore_errors=False)
266e5c31af7Sopenharmony_ci
267e5c31af7Sopenharmony_ciclass Module:
268e5c31af7Sopenharmony_ci	def __init__ (self, name, targets):
269e5c31af7Sopenharmony_ci		self.name		= name
270e5c31af7Sopenharmony_ci		self.targets	= targets
271e5c31af7Sopenharmony_ci
272e5c31af7Sopenharmony_ci	def make (self, packageBuildInfo):
273e5c31af7Sopenharmony_ci		for target in self.targets:
274e5c31af7Sopenharmony_ci			target.make(packageBuildInfo)
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_ciclass ReleaseConfig:
277e5c31af7Sopenharmony_ci	def __init__ (self, name, version, modules, sources = True):
278e5c31af7Sopenharmony_ci		self.name			= name
279e5c31af7Sopenharmony_ci		self.version		= version
280e5c31af7Sopenharmony_ci		self.modules		= modules
281e5c31af7Sopenharmony_ci		self.sources		= sources
282e5c31af7Sopenharmony_ci
283e5c31af7Sopenharmony_ci	def getName (self):
284e5c31af7Sopenharmony_ci		return self.name
285e5c31af7Sopenharmony_ci
286e5c31af7Sopenharmony_ci	def getVersion (self):
287e5c31af7Sopenharmony_ci		return self.version
288e5c31af7Sopenharmony_ci
289e5c31af7Sopenharmony_ci	def getModules (self):
290e5c31af7Sopenharmony_ci		return self.modules
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci	def packageWithSources (self):
293e5c31af7Sopenharmony_ci		return self.sources
294e5c31af7Sopenharmony_ci
295e5c31af7Sopenharmony_cidef matchIncludeExclude (includePatterns, excludePatterns, filename):
296e5c31af7Sopenharmony_ci	components = os.path.normpath(filename).split(os.sep)
297e5c31af7Sopenharmony_ci	for pattern in excludePatterns:
298e5c31af7Sopenharmony_ci		for component in components:
299e5c31af7Sopenharmony_ci			if fnmatch.fnmatch(component, pattern):
300e5c31af7Sopenharmony_ci				return False
301e5c31af7Sopenharmony_ci
302e5c31af7Sopenharmony_ci	for pattern in includePatterns:
303e5c31af7Sopenharmony_ci		for component in components:
304e5c31af7Sopenharmony_ci			if fnmatch.fnmatch(component, pattern):
305e5c31af7Sopenharmony_ci				return True
306e5c31af7Sopenharmony_ci
307e5c31af7Sopenharmony_ci	return False
308e5c31af7Sopenharmony_ci
309e5c31af7Sopenharmony_cidef copyFileFilter (includePatterns, excludePatterns=[]):
310e5c31af7Sopenharmony_ci	return (lambda f: matchIncludeExclude(includePatterns, excludePatterns, f),
311e5c31af7Sopenharmony_ci			lambda s, d: CopyFile(s, d))
312e5c31af7Sopenharmony_ci
313e5c31af7Sopenharmony_cidef makeFileCopyGroup (srcDir, dstDir, includePatterns, excludePatterns=[]):
314e5c31af7Sopenharmony_ci	return FileTargetGroup(srcDir, dstDir, [copyFileFilter(includePatterns, excludePatterns)])
315e5c31af7Sopenharmony_ci
316e5c31af7Sopenharmony_cidef makeTmpFileCopyGroup (srcDir, dstDir, includePatterns, excludePatterns=[]):
317e5c31af7Sopenharmony_ci	return FileTargetGroup(srcDir, dstDir, [copyFileFilter(includePatterns, excludePatterns)], PackageBuildInfo.getTmpBasePath)
318e5c31af7Sopenharmony_ci
319e5c31af7Sopenharmony_cidef makeFileCopy (srcFile, dstFile):
320e5c31af7Sopenharmony_ci	return SingleFileTarget(srcFile, dstFile, lambda s, d: CopyFile(s, d))
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_cidef getReleaseFileName (configName, releaseName):
323e5c31af7Sopenharmony_ci	today = datetime.date.today()
324e5c31af7Sopenharmony_ci	return "dEQP-%s-%04d-%02d-%02d-%s" % (releaseName, today.year, today.month, today.day, configName)
325e5c31af7Sopenharmony_ci
326e5c31af7Sopenharmony_cidef getTempDir ():
327e5c31af7Sopenharmony_ci	dirName = os.path.join(tempfile.gettempdir(), "dEQP-Releases")
328e5c31af7Sopenharmony_ci	if not os.path.exists(dirName):
329e5c31af7Sopenharmony_ci		os.makedirs(dirName)
330e5c31af7Sopenharmony_ci	return dirName
331e5c31af7Sopenharmony_ci
332e5c31af7Sopenharmony_cidef makeRelease (releaseConfig):
333e5c31af7Sopenharmony_ci	releaseName			= getReleaseFileName(releaseConfig.getName(), releaseConfig.getVersion())
334e5c31af7Sopenharmony_ci	tmpPath				= getTempDir()
335e5c31af7Sopenharmony_ci	srcBasePath			= DEQP_DIR
336e5c31af7Sopenharmony_ci	dstBasePath			= os.path.join(tmpPath, releaseName)
337e5c31af7Sopenharmony_ci	tmpBasePath			= os.path.join(tmpPath, releaseName + "-tmp")
338e5c31af7Sopenharmony_ci	packageBuildInfo	= PackageBuildInfo(releaseConfig, srcBasePath, dstBasePath, tmpBasePath)
339e5c31af7Sopenharmony_ci	dstArchiveName		= releaseName + ".tar.bz2"
340e5c31af7Sopenharmony_ci
341e5c31af7Sopenharmony_ci	print("Creating release %s to %s" % (releaseName, tmpPath))
342e5c31af7Sopenharmony_ci
343e5c31af7Sopenharmony_ci	# Remove old temporary dirs
344e5c31af7Sopenharmony_ci	for path in [dstBasePath, tmpBasePath]:
345e5c31af7Sopenharmony_ci		if os.path.exists(path):
346e5c31af7Sopenharmony_ci			shutil.rmtree(path, ignore_errors=False)
347e5c31af7Sopenharmony_ci
348e5c31af7Sopenharmony_ci	# Make all modules
349e5c31af7Sopenharmony_ci	for module in releaseConfig.getModules():
350e5c31af7Sopenharmony_ci		print("  Processing module %s" % module.name)
351e5c31af7Sopenharmony_ci		module.make(packageBuildInfo)
352e5c31af7Sopenharmony_ci
353e5c31af7Sopenharmony_ci	# Remove sources?
354e5c31af7Sopenharmony_ci	if not releaseConfig.packageWithSources():
355e5c31af7Sopenharmony_ci		shutil.rmtree(os.path.join(dstBasePath, "src"), ignore_errors=False)
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ci	# Create archive
358e5c31af7Sopenharmony_ci	print("Creating %s" % dstArchiveName)
359e5c31af7Sopenharmony_ci	archive	= tarfile.open(dstArchiveName, 'w:bz2')
360e5c31af7Sopenharmony_ci	archive.add(dstBasePath, arcname=releaseName)
361e5c31af7Sopenharmony_ci	archive.close()
362e5c31af7Sopenharmony_ci
363e5c31af7Sopenharmony_ci	# Remove tmp dirs
364e5c31af7Sopenharmony_ci	for path in [dstBasePath, tmpBasePath]:
365e5c31af7Sopenharmony_ci		if os.path.exists(path):
366e5c31af7Sopenharmony_ci			shutil.rmtree(path, ignore_errors=False)
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ci	print("Done!")
369e5c31af7Sopenharmony_ci
370e5c31af7Sopenharmony_ci# Module declarations
371e5c31af7Sopenharmony_ci
372e5c31af7Sopenharmony_ciSRC_FILE_PATTERNS	= ["*.h", "*.hpp", "*.c", "*.cpp", "*.m", "*.mm", "*.inl", "*.java", "*.aidl", "CMakeLists.txt", "LICENSE.txt", "*.cmake"]
373e5c31af7Sopenharmony_ciTARGET_PATTERNS		= ["*.cmake", "*.h", "*.lib", "*.dll", "*.so", "*.txt"]
374e5c31af7Sopenharmony_ci
375e5c31af7Sopenharmony_ciBASE = Module("Base", [
376e5c31af7Sopenharmony_ci	makeFileCopy		("LICENSE",									"src/LICENSE"),
377e5c31af7Sopenharmony_ci	makeFileCopy		("CMakeLists.txt",							"src/CMakeLists.txt"),
378e5c31af7Sopenharmony_ci	makeFileCopyGroup	("targets",									"src/targets",							TARGET_PATTERNS),
379e5c31af7Sopenharmony_ci	makeFileCopyGroup	("execserver",								"src/execserver",						SRC_FILE_PATTERNS),
380e5c31af7Sopenharmony_ci	makeFileCopyGroup	("executor",								"src/executor",							SRC_FILE_PATTERNS),
381e5c31af7Sopenharmony_ci	makeFileCopy		("modules/CMakeLists.txt",					"src/modules/CMakeLists.txt"),
382e5c31af7Sopenharmony_ci	makeFileCopyGroup	("external",								"src/external",							["CMakeLists.txt", "*.py"]),
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	# Stylesheet for displaying test logs on browser
385e5c31af7Sopenharmony_ci	makeFileCopyGroup	("doc/testlog-stylesheet",					"doc/testlog-stylesheet",				["*"]),
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_ci	# Non-optional parts of framework
388e5c31af7Sopenharmony_ci	makeFileCopy		("framework/CMakeLists.txt",				"src/framework/CMakeLists.txt"),
389e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/delibs",						"src/framework/delibs",					SRC_FILE_PATTERNS),
390e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/common",						"src/framework/common",					SRC_FILE_PATTERNS),
391e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/qphelper",						"src/framework/qphelper",				SRC_FILE_PATTERNS),
392e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/platform",						"src/framework/platform",				SRC_FILE_PATTERNS),
393e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/opengl",						"src/framework/opengl",					SRC_FILE_PATTERNS, ["simplereference"]),
394e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/egl",							"src/framework/egl",					SRC_FILE_PATTERNS),
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci	# android sources
397e5c31af7Sopenharmony_ci	makeFileCopyGroup	("android/package/src",						"src/android/package/src",				SRC_FILE_PATTERNS),
398e5c31af7Sopenharmony_ci	makeFileCopy		("android/package/AndroidManifest.xml",		"src/android/package/AndroidManifest.xml"),
399e5c31af7Sopenharmony_ci	makeFileCopyGroup	("android/package/res",						"src/android/package/res",				["*.png", "*.xml"]),
400e5c31af7Sopenharmony_ci	makeFileCopyGroup	("android/scripts",							"src/android/scripts", [
401e5c31af7Sopenharmony_ci		"common.py",
402e5c31af7Sopenharmony_ci		"build.py",
403e5c31af7Sopenharmony_ci		"resources.py",
404e5c31af7Sopenharmony_ci		"install.py",
405e5c31af7Sopenharmony_ci		"launch.py",
406e5c31af7Sopenharmony_ci		"debug.py"
407e5c31af7Sopenharmony_ci		]),
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ci	# Release info
410e5c31af7Sopenharmony_ci	GenReleaseInfoFileTarget("src/framework/qphelper/qpReleaseInfo.inl")
411e5c31af7Sopenharmony_ci])
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_ciDOCUMENTATION = Module("Documentation", [
414e5c31af7Sopenharmony_ci	makeFileCopyGroup	("doc/pdf",									"doc",									["*.pdf"]),
415e5c31af7Sopenharmony_ci	makeFileCopyGroup	("doc",										"doc",									["porting_layer_changes_*.txt"]),
416e5c31af7Sopenharmony_ci])
417e5c31af7Sopenharmony_ci
418e5c31af7Sopenharmony_ciGLSHARED = Module("Shared GL Tests", [
419e5c31af7Sopenharmony_ci	# Optional framework components
420e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/randomshaders",					"src/framework/randomshaders",			SRC_FILE_PATTERNS),
421e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/opengl/simplereference",		"src/framework/opengl/simplereference",	SRC_FILE_PATTERNS),
422e5c31af7Sopenharmony_ci	makeFileCopyGroup	("framework/referencerenderer",				"src/framework/referencerenderer",		SRC_FILE_PATTERNS),
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci	makeFileCopyGroup	("modules/glshared",						"src/modules/glshared",					SRC_FILE_PATTERNS),
425e5c31af7Sopenharmony_ci])
426e5c31af7Sopenharmony_ci
427e5c31af7Sopenharmony_ciGLES2 = Module("GLES2", [
428e5c31af7Sopenharmony_ci	makeFileCopyGroup	("modules/gles2",							"src/modules/gles2",					SRC_FILE_PATTERNS),
429e5c31af7Sopenharmony_ci	makeFileCopyGroup	("data/gles2",								"src/data/gles2",						["*.*"]),
430e5c31af7Sopenharmony_ci	makeFileCopyGroup	("doc/testspecs/GLES2",						"doc/testspecs/GLES2",					["*.txt"])
431e5c31af7Sopenharmony_ci])
432e5c31af7Sopenharmony_ci
433e5c31af7Sopenharmony_ciGLES3 = Module("GLES3", [
434e5c31af7Sopenharmony_ci	makeFileCopyGroup	("modules/gles3",							"src/modules/gles3",					SRC_FILE_PATTERNS),
435e5c31af7Sopenharmony_ci	makeFileCopyGroup	("data/gles3",								"src/data/gles3",						["*.*"]),
436e5c31af7Sopenharmony_ci	makeFileCopyGroup	("doc/testspecs/GLES3",						"doc/testspecs/GLES3",					["*.txt"])
437e5c31af7Sopenharmony_ci])
438e5c31af7Sopenharmony_ci
439e5c31af7Sopenharmony_ciGLES31 = Module("GLES31", [
440e5c31af7Sopenharmony_ci	makeFileCopyGroup	("modules/gles31",							"src/modules/gles31",					SRC_FILE_PATTERNS),
441e5c31af7Sopenharmony_ci	makeFileCopyGroup	("data/gles31",								"src/data/gles31",						["*.*"]),
442e5c31af7Sopenharmony_ci	makeFileCopyGroup	("doc/testspecs/GLES31",					"doc/testspecs/GLES31",					["*.txt"])
443e5c31af7Sopenharmony_ci])
444e5c31af7Sopenharmony_ci
445e5c31af7Sopenharmony_ciEGL = Module("EGL", [
446e5c31af7Sopenharmony_ci	makeFileCopyGroup	("modules/egl",								"src/modules/egl",						SRC_FILE_PATTERNS)
447e5c31af7Sopenharmony_ci])
448e5c31af7Sopenharmony_ci
449e5c31af7Sopenharmony_ciINTERNAL = Module("Internal", [
450e5c31af7Sopenharmony_ci	makeFileCopyGroup	("modules/internal",						"src/modules/internal",					SRC_FILE_PATTERNS),
451e5c31af7Sopenharmony_ci	makeFileCopyGroup	("data/internal",							"src/data/internal",					["*.*"]),
452e5c31af7Sopenharmony_ci])
453e5c31af7Sopenharmony_ci
454e5c31af7Sopenharmony_ciEXTERNAL_SRCS = Module("External sources", [
455e5c31af7Sopenharmony_ci	FetchExternalSourcesTarget()
456e5c31af7Sopenharmony_ci])
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_ciANDROID_BINARIES = Module("Android Binaries", [
459e5c31af7Sopenharmony_ci	BuildAndroidTarget	("bin/android/dEQP.apk"),
460e5c31af7Sopenharmony_ci	makeFileCopyGroup	("targets/android",							"bin/android",							["*.bat", "*.sh"]),
461e5c31af7Sopenharmony_ci])
462e5c31af7Sopenharmony_ci
463e5c31af7Sopenharmony_ciCOMMON_BUILD_ARGS	= ['-DPNG_SRC_PATH=%s' % os.path.realpath(os.path.join(DEQP_DIR, '..', 'libpng'))]
464e5c31af7Sopenharmony_ciNULL_X32_CONFIG		= BuildConfig('null-x32',	'Release', ['-DDEQP_TARGET=null', '-DCMAKE_C_FLAGS=-m32', '-DCMAKE_CXX_FLAGS=-m32'] + COMMON_BUILD_ARGS)
465e5c31af7Sopenharmony_ciNULL_X64_CONFIG		= BuildConfig('null-x64',	'Release', ['-DDEQP_TARGET=null', '-DCMAKE_C_FLAGS=-m64', '-DCMAKE_CXX_FLAGS=-m64'] + COMMON_BUILD_ARGS)
466e5c31af7Sopenharmony_ciGLX_X32_CONFIG		= BuildConfig('glx-x32',	'Release', ['-DDEQP_TARGET=x11_glx', '-DCMAKE_C_FLAGS=-m32', '-DCMAKE_CXX_FLAGS=-m32'] + COMMON_BUILD_ARGS)
467e5c31af7Sopenharmony_ciGLX_X64_CONFIG		= BuildConfig('glx-x64',	'Release', ['-DDEQP_TARGET=x11_glx', '-DCMAKE_C_FLAGS=-m64', '-DCMAKE_CXX_FLAGS=-m64'] + COMMON_BUILD_ARGS)
468e5c31af7Sopenharmony_ci
469e5c31af7Sopenharmony_ciEXCLUDE_BUILD_FILES = ["CMakeFiles", "*.a", "*.cmake"]
470e5c31af7Sopenharmony_ci
471e5c31af7Sopenharmony_ciLINUX_X32_COMMON_BINARIES = Module("Linux x32 Common Binaries", [
472e5c31af7Sopenharmony_ci	BuildTarget			(NULL_X32_CONFIG, ANY_UNIX_GENERATOR),
473e5c31af7Sopenharmony_ci	makeTmpFileCopyGroup(NULL_X32_CONFIG.getBuildDir() + "/execserver",		"bin/linux32",					["*"],	EXCLUDE_BUILD_FILES),
474e5c31af7Sopenharmony_ci	makeTmpFileCopyGroup(NULL_X32_CONFIG.getBuildDir() + "/executor",		"bin/linux32",					["*"],	EXCLUDE_BUILD_FILES),
475e5c31af7Sopenharmony_ci])
476e5c31af7Sopenharmony_ci
477e5c31af7Sopenharmony_ciLINUX_X64_COMMON_BINARIES = Module("Linux x64 Common Binaries", [
478e5c31af7Sopenharmony_ci	BuildTarget			(NULL_X64_CONFIG, ANY_UNIX_GENERATOR),
479e5c31af7Sopenharmony_ci	makeTmpFileCopyGroup(NULL_X64_CONFIG.getBuildDir() + "/execserver",		"bin/linux64",					["*"],	EXCLUDE_BUILD_FILES),
480e5c31af7Sopenharmony_ci	makeTmpFileCopyGroup(NULL_X64_CONFIG.getBuildDir() + "/executor",		"bin/linux64",					["*"],	EXCLUDE_BUILD_FILES),
481e5c31af7Sopenharmony_ci])
482e5c31af7Sopenharmony_ci
483e5c31af7Sopenharmony_ci# Special module to remove src dir, for example after binary build
484e5c31af7Sopenharmony_ciREMOVE_SOURCES = Module("Remove sources from package", [
485e5c31af7Sopenharmony_ci	RemoveSourcesTarget()
486e5c31af7Sopenharmony_ci])
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci# Release configuration
489e5c31af7Sopenharmony_ci
490e5c31af7Sopenharmony_ciALL_MODULES		= [
491e5c31af7Sopenharmony_ci	BASE,
492e5c31af7Sopenharmony_ci	DOCUMENTATION,
493e5c31af7Sopenharmony_ci	GLSHARED,
494e5c31af7Sopenharmony_ci	GLES2,
495e5c31af7Sopenharmony_ci	GLES3,
496e5c31af7Sopenharmony_ci	GLES31,
497e5c31af7Sopenharmony_ci	EGL,
498e5c31af7Sopenharmony_ci	INTERNAL,
499e5c31af7Sopenharmony_ci	EXTERNAL_SRCS,
500e5c31af7Sopenharmony_ci]
501e5c31af7Sopenharmony_ci
502e5c31af7Sopenharmony_ciALL_BINARIES	= [
503e5c31af7Sopenharmony_ci	LINUX_X64_COMMON_BINARIES,
504e5c31af7Sopenharmony_ci	ANDROID_BINARIES,
505e5c31af7Sopenharmony_ci]
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ciRELEASE_CONFIGS	= {
508e5c31af7Sopenharmony_ci	"src":		ALL_MODULES,
509e5c31af7Sopenharmony_ci	"src-bin":	ALL_MODULES + ALL_BINARIES,
510e5c31af7Sopenharmony_ci	"bin":		ALL_MODULES + ALL_BINARIES + [REMOVE_SOURCES],
511e5c31af7Sopenharmony_ci}
512e5c31af7Sopenharmony_ci
513e5c31af7Sopenharmony_cidef parseArgs ():
514e5c31af7Sopenharmony_ci	parser = argparse.ArgumentParser(description = "Build release package")
515e5c31af7Sopenharmony_ci	parser.add_argument("-c",
516e5c31af7Sopenharmony_ci						"--config",
517e5c31af7Sopenharmony_ci						dest="config",
518e5c31af7Sopenharmony_ci						choices=RELEASE_CONFIGS.keys(),
519e5c31af7Sopenharmony_ci						required=True,
520e5c31af7Sopenharmony_ci						help="Release configuration")
521e5c31af7Sopenharmony_ci	parser.add_argument("-n",
522e5c31af7Sopenharmony_ci						"--name",
523e5c31af7Sopenharmony_ci						dest="name",
524e5c31af7Sopenharmony_ci						required=True,
525e5c31af7Sopenharmony_ci						help="Package-specific name")
526e5c31af7Sopenharmony_ci	parser.add_argument("-v",
527e5c31af7Sopenharmony_ci						"--version",
528e5c31af7Sopenharmony_ci						dest="version",
529e5c31af7Sopenharmony_ci						required=True,
530e5c31af7Sopenharmony_ci						help="Version code")
531e5c31af7Sopenharmony_ci	return parser.parse_args()
532e5c31af7Sopenharmony_ci
533e5c31af7Sopenharmony_ciif __name__ == "__main__":
534e5c31af7Sopenharmony_ci	args	= parseArgs()
535e5c31af7Sopenharmony_ci	config	= ReleaseConfig(args.name, args.version, RELEASE_CONFIGS[args.config])
536e5c31af7Sopenharmony_ci	makeRelease(config)
537