Merge "DO NOT MERGE: Add cube gather tests that avoid corners; remove D32F from...
[platform/upstream/VK-GL-CTS.git] / android / scripts / build.py
1 # -*- coding: utf-8 -*-
2
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
6 #
7 # Copyright 2015 The Android Open Source Project
8 #
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 #      http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 #
21 #-------------------------------------------------------------------------
22
23 import os
24 import re
25 import sys
26 import shutil
27 import argparse
28
29 import common
30
31 def getStoreKeyPasswords (filename):
32         f                       = open(filename)
33         storepass       = None
34         keypass         = None
35         for line in f:
36                 m = re.search('([a-z]+)\s*\=\s*"([^"]+)"', line)
37                 if m != None:
38                         if m.group(1) == "storepass":
39                                 storepass = m.group(2)
40                         elif m.group(1) == "keypass":
41                                 keypass = m.group(2)
42         f.close()
43         if storepass == None or keypass == None:
44                 common.die("Could not read signing key passwords")
45         return (storepass, keypass)
46
47 def getNativeBuildDir (buildRoot, nativeLib, buildType):
48         buildName = "%s-%d-%s" % (buildType.lower(), nativeLib.apiVersion, nativeLib.abiVersion)
49         return os.path.normpath(os.path.join(buildRoot, "native", buildName))
50
51 def getAssetsDir (buildRoot, nativeLib, buildType):
52         return os.path.join(getNativeBuildDir(buildRoot, nativeLib, buildType), "assets")
53
54 def buildNative (buildRoot, libTargetDir, nativeLib, buildType):
55         deqpDir         = os.path.normpath(os.path.join(common.ANDROID_DIR, ".."))
56         buildDir        = getNativeBuildDir(buildRoot, nativeLib, buildType)
57         libsDir         = os.path.join(libTargetDir, nativeLib.abiVersion)
58         srcLibFile      = os.path.join(buildDir, common.NATIVE_LIB_NAME)
59         dstLibFile      = os.path.join(libsDir, common.NATIVE_LIB_NAME)
60
61         # Make build directory if necessary
62         if not os.path.exists(buildDir):
63                 os.makedirs(buildDir)
64                 toolchainFile = '%s/framework/delibs/cmake/toolchain-android-%s.cmake' % (deqpDir, common.ANDROID_NDK_TOOLCHAIN_VERSION)
65                 common.execArgsInDirectory([
66                                 'cmake',
67                                 '-G%s' % common.CMAKE_GENERATOR,
68                                 '-DCMAKE_TOOLCHAIN_FILE=%s' % toolchainFile,
69                                 '-DANDROID_NDK_HOST_OS=%s' % common.ANDROID_NDK_HOST_OS,
70                                 '-DANDROID_NDK_PATH=%s' % common.ANDROID_NDK_PATH,
71                                 '-DANDROID_ABI=%s' % nativeLib.abiVersion,
72                                 '-DDE_ANDROID_API=%s' % nativeLib.apiVersion,
73                                 '-DCMAKE_BUILD_TYPE=%s' % buildType,
74                                 '-DDEQP_TARGET=android',
75                                 deqpDir
76                         ], buildDir)
77
78         common.execArgsInDirectory(['cmake', '--build', '.'] + common.EXTRA_BUILD_ARGS, buildDir)
79
80         if not os.path.exists(libsDir):
81                 os.makedirs(libsDir)
82
83         shutil.copyfile(srcLibFile, dstLibFile)
84
85         # Copy gdbserver for debugging
86         if buildType.lower() == "debug":
87                 srcGdbserverPath = os.path.join(common.ANDROID_NDK_PATH,
88                                                                                 'prebuilt',
89                                                                                 nativeLib.prebuiltDir,
90                                                                                 'gdbserver',
91                                                                                 'gdbserver')
92                 dstGdbserverPath = os.path.join(libsDir, 'gdbserver')
93                 shutil.copyfile(srcGdbserverPath, dstGdbserverPath)
94         else:
95                 assert not os.path.exists(os.path.join(libsDir, "gdbserver"))
96
97 def buildApp (buildRoot, androidBuildType, javaApi):
98         appDir  = os.path.join(buildRoot, "package")
99
100         # Set up app
101         os.chdir(appDir)
102
103         manifestSrcPath = os.path.normpath(os.path.join(common.ANDROID_DIR, "package", "AndroidManifest.xml"))
104         manifestDstPath = os.path.normpath(os.path.join(appDir, "AndroidManifest.xml"))
105
106         # Build dir can be the Android dir, in which case the copy is not needed.
107         if manifestSrcPath != manifestDstPath:
108                 shutil.copy(manifestSrcPath, manifestDstPath)
109
110         common.execArgs([
111                         common.ANDROID_BIN,
112                         'update', 'project',
113                         '--name', 'dEQP',
114                         '--path', '.',
115                         '--target', javaApi,
116                 ])
117
118         # Build
119         common.execArgs([
120                         common.ANT_BIN,
121                         androidBuildType,
122                         "-Dsource.dir=" + os.path.join(common.ANDROID_DIR, "package", "src"),
123                         "-Dresource.absolute.dir=" + os.path.join(common.ANDROID_DIR, "package", "res")
124                 ])
125
126 def signApp (keystore, keyname, storepass, keypass):
127         os.chdir(os.path.join(common.ANDROID_DIR, "package"))
128         common.execArgs([
129                         common.JARSIGNER_BIN,
130                         '-keystore', keystore,
131                         '-storepass', storepass,
132                         '-keypass', keypass,
133                         '-sigfile', 'CERT',
134                         '-digestalg', 'SHA1',
135                         '-sigalg', 'MD5withRSA',
136                         '-signedjar', 'bin/dEQP-unaligned.apk',
137                         'bin/dEQP-release-unsigned.apk',
138                         keyname
139                 ])
140         common.execArgs([
141                         common.ZIPALIGN_BIN,
142                         '-f', '4',
143                         'bin/dEQP-unaligned.apk',
144                         'bin/dEQP-release.apk'
145                 ])
146
147 def build (buildRoot=common.ANDROID_DIR, androidBuildType='debug', nativeBuildType="Release", javaApi=common.ANDROID_JAVA_API, doParallelBuild=False):
148         curDir = os.getcwd()
149
150         try:
151                 assetsSrcDir = getAssetsDir(buildRoot, common.NATIVE_LIBS[0], nativeBuildType)
152                 assetsDstDir = os.path.join(buildRoot, "package", "assets")
153
154                 # Remove assets from the first build dir where we copy assets from
155                 # to avoid collecting cruft there.
156                 if os.path.exists(assetsSrcDir):
157                         shutil.rmtree(assetsSrcDir)
158                 if os.path.exists(assetsDstDir):
159                         shutil.rmtree(assetsDstDir)
160
161                 # Remove old libs dir to avoid collecting out-of-date versions
162                 # of libs for ABIs not built this time.
163                 libTargetDir = os.path.join(buildRoot, "package", "libs")
164                 if os.path.exists(libTargetDir):
165                         shutil.rmtree(libTargetDir)
166
167                 # Build native code
168                 nativeBuildArgs = [(buildRoot, libTargetDir, nativeLib, nativeBuildType) for nativeLib in common.NATIVE_LIBS]
169                 if doParallelBuild:
170                         common.parallelApply(buildNative, nativeBuildArgs)
171                 else:
172                         common.serialApply(buildNative, nativeBuildArgs)
173
174                 # Copy assets
175                 if os.path.exists(assetsSrcDir):
176                         shutil.copytree(assetsSrcDir, assetsDstDir)
177
178                 # Build java code and .apk
179                 buildApp(buildRoot, androidBuildType, javaApi)
180
181         finally:
182                 # Restore working dir
183                 os.chdir(curDir)
184
185 def dumpConfig ():
186         print " "
187         for entry in common.CONFIG_STRINGS:
188                 print "%-30s : %s" % (entry[0], entry[1])
189         print " "
190
191 if __name__ == "__main__":
192         nativeBuildTypes = ['Release', 'Debug', 'MinSizeRel', 'RelWithAsserts', 'RelWithDebInfo']
193         androidBuildTypes = ['debug', 'release']
194
195         parser = argparse.ArgumentParser()
196         parser.add_argument('--android-build-type', dest='androidBuildType', choices=androidBuildTypes, default='debug', help="Build type for android project..")
197         parser.add_argument('--native-build-type', dest='nativeBuildType', default="RelWithAsserts", choices=nativeBuildTypes, help="Build type passed to cmake when building native code.")
198         parser.add_argument('--build-root', dest='buildRoot', default=common.ANDROID_DIR, help="Root directory for storing build results.")
199         parser.add_argument('--dump-config', dest='dumpConfig', action='store_true', help="Print out all configurations variables")
200         parser.add_argument('--java-api', dest='javaApi', default=common.ANDROID_JAVA_API, help="Set the API signature for the java build.")
201         parser.add_argument('-p', '--parallel-build', dest='parallelBuild', action="store_true", help="Build native libraries in parallel.")
202
203         args = parser.parse_args()
204
205         if args.dumpConfig:
206                 dumpConfig()
207
208         build(buildRoot=os.path.abspath(args.buildRoot), androidBuildType=args.androidBuildType, nativeBuildType=args.nativeBuildType, javaApi=args.javaApi, doParallelBuild=args.parallelBuild)