1 # -*- coding: utf-8 -*- 2 3 import os 4 import re 5 import sys 6 import shutil 7 import argparse 8 9 import common 10 11 def getStoreKeyPasswords (filename): 12 f = open(filename) 13 storepass = None 14 keypass = None 15 for line in f: 16 m = re.search('([a-z]+)\s*\=\s*"([^"]+)"', line) 17 if m != None: 18 if m.group(1) == "storepass": 19 storepass = m.group(2) 20 elif m.group(1) == "keypass": 21 keypass = m.group(2) 22 f.close() 23 if storepass == None or keypass == None: 24 common.die("Could not read signing key passwords") 25 return (storepass, keypass) 26 27 def getNativeBuildDir (buildRoot, nativeLib, buildType): 28 buildName = "%s-%d-%s" % (buildType.lower(), nativeLib.apiVersion, nativeLib.abiVersion) 29 return os.path.normpath(os.path.join(buildRoot, "native", buildName)) 30 31 def getAssetsDir (buildRoot, nativeLib, buildType): 32 return os.path.join(getNativeBuildDir(buildRoot, nativeLib, buildType), "assets") 33 34 def getPrebuiltsDirName (abiName): 35 PREBUILT_DIRS = { 36 'x86': 'android-x86', 37 'armeabi-v7a': 'android-arm', 38 'arm64-v8a': 'android-arm64' 39 } 40 41 if not abiName in PREBUILT_DIRS: 42 raise Exception("Unknown ABI %s, don't know where prebuilts are" % abiName) 43 44 return PREBUILT_DIRS[abiName] 45 46 def buildNative (buildRoot, libTargetDir, nativeLib, buildType): 47 deqpDir = os.path.normpath(os.path.join(common.ANDROID_DIR, "..")) 48 buildDir = getNativeBuildDir(buildRoot, nativeLib, buildType) 49 libsDir = os.path.join(libTargetDir, nativeLib.abiVersion) 50 srcLibFile = os.path.join(buildDir, common.NATIVE_LIB_NAME) 51 dstLibFile = os.path.join(libsDir, common.NATIVE_LIB_NAME) 52 53 # Make build directory if necessary 54 if not os.path.exists(buildDir): 55 os.makedirs(buildDir) 56 os.chdir(buildDir) 57 toolchainFile = '%s/framework/delibs/cmake/toolchain-android-%s.cmake' % (deqpDir, common.ANDROID_NDK_TOOLCHAIN_VERSION) 58 common.execArgs([ 59 'cmake', 60 '-G%s' % common.CMAKE_GENERATOR, 61 '-DCMAKE_TOOLCHAIN_FILE=%s' % toolchainFile, 62 '-DANDROID_NDK_HOST_OS=%s' % common.ANDROID_NDK_HOST_OS, 63 '-DANDROID_NDK_PATH=%s' % common.ANDROID_NDK_PATH, 64 '-DANDROID_ABI=%s' % nativeLib.abiVersion, 65 '-DDE_ANDROID_API=%s' % nativeLib.apiVersion, 66 '-DCMAKE_BUILD_TYPE=%s' % buildType, 67 '-DDEQP_TARGET=android', 68 deqpDir 69 ]) 70 71 os.chdir(buildDir) 72 common.execArgs(['cmake', '--build', '.'] + common.EXTRA_BUILD_ARGS) 73 74 if not os.path.exists(libsDir): 75 os.makedirs(libsDir) 76 77 shutil.copyfile(srcLibFile, dstLibFile) 78 79 # Copy gdbserver for debugging 80 if buildType.lower() == "debug": 81 srcGdbserverPath = os.path.join(common.ANDROID_NDK_PATH, 82 'prebuilt', 83 getPrebuiltsDirName(nativeLib.abiVersion), 84 'gdbserver', 85 'gdbserver') 86 dstGdbserverPath = os.path.join(libsDir, 'gdbserver') 87 shutil.copyfile(srcGdbserverPath, dstGdbserverPath) 88 else: 89 assert not os.path.exists(os.path.join(libsDir, "gdbserver")) 90 91 def buildApp (buildRoot, isRelease): 92 appDir = os.path.join(buildRoot, "package") 93 94 # Set up app 95 os.chdir(appDir) 96 97 manifestSrcPath = os.path.normpath(os.path.join(common.ANDROID_DIR, "package", "AndroidManifest.xml")) 98 manifestDstPath = os.path.normpath(os.path.join(appDir, "AndroidManifest.xml")) 99 100 # Build dir can be the Android dir, in which case the copy is not needed. 101 if manifestSrcPath != manifestDstPath: 102 shutil.copy(manifestSrcPath, manifestDstPath) 103 104 common.execArgs([ 105 common.ANDROID_BIN, 106 'update', 'project', 107 '--name', 'dEQP', 108 '--path', '.', 109 '--target', str(common.ANDROID_JAVA_API), 110 ]) 111 112 # Build 113 common.execArgs([ 114 common.ANT_BIN, 115 "release" if isRelease else "debug", 116 "-Dsource.dir=" + os.path.join(common.ANDROID_DIR, "package", "src"), 117 "-Dresource.absolute.dir=" + os.path.join(common.ANDROID_DIR, "package", "res") 118 ]) 119 120 def signApp (keystore, keyname, storepass, keypass): 121 os.chdir(os.path.join(common.ANDROID_DIR, "package")) 122 common.execArgs([ 123 common.JARSIGNER_BIN, 124 '-keystore', keystore, 125 '-storepass', storepass, 126 '-keypass', keypass, 127 '-sigfile', 'CERT', 128 '-digestalg', 'SHA1', 129 '-sigalg', 'MD5withRSA', 130 '-signedjar', 'bin/dEQP-unaligned.apk', 131 'bin/dEQP-release-unsigned.apk', 132 keyname 133 ]) 134 common.execArgs([ 135 common.ZIPALIGN_BIN, 136 '-f', '4', 137 'bin/dEQP-unaligned.apk', 138 'bin/dEQP-release.apk' 139 ]) 140 141 def build (buildRoot=common.ANDROID_DIR, isRelease=False, nativeBuildType="Release"): 142 curDir = os.getcwd() 143 144 try: 145 assetsSrcDir = getAssetsDir(buildRoot, common.NATIVE_LIBS[0], nativeBuildType) 146 assetsDstDir = os.path.join(buildRoot, "package", "assets") 147 148 # Remove assets from the first build dir where we copy assets from 149 # to avoid collecting cruft there. 150 if os.path.exists(assetsSrcDir): 151 shutil.rmtree(assetsSrcDir) 152 if os.path.exists(assetsDstDir): 153 shutil.rmtree(assetsDstDir) 154 155 # Remove old libs dir to avoid collecting out-of-date versions 156 # of libs for ABIs not built this time. 157 libTargetDir = os.path.join(buildRoot, "package", "libs") 158 if os.path.exists(libTargetDir): 159 shutil.rmtree(libTargetDir) 160 161 # Build native code 162 for lib in common.NATIVE_LIBS: 163 buildNative(buildRoot, libTargetDir, lib, nativeBuildType) 164 165 # Copy assets 166 if os.path.exists(assetsSrcDir): 167 shutil.copytree(assetsSrcDir, assetsDstDir) 168 169 # Build java code and .apk 170 buildApp(buildRoot, isRelease) 171 172 finally: 173 # Restore working dir 174 os.chdir(curDir) 175 176 if __name__ == "__main__": 177 parser = argparse.ArgumentParser() 178 parser.add_argument('--is-release', dest='isRelease', type=bool, default=False, help="Build android project in release mode.") 179 parser.add_argument('--native-build-type', dest='nativeBuildType', default="Release", help="Build type passed cmake when building native code.") 180 parser.add_argument('--build-root', dest='buildRoot', default=common.ANDROID_DIR, help="Root directory for storing build results.") 181 182 args = parser.parse_args() 183 184 build(buildRoot=os.path.abspath(args.buildRoot), isRelease=args.isRelease, nativeBuildType=args.nativeBuildType) 185