1*35238bceSAndroid Build Coastguard Worker# -*- coding: utf-8 -*- 2*35238bceSAndroid Build Coastguard Worker 3*35238bceSAndroid Build Coastguard Worker#------------------------------------------------------------------------- 4*35238bceSAndroid Build Coastguard Worker# drawElements Quality Program utilities 5*35238bceSAndroid Build Coastguard Worker# -------------------------------------- 6*35238bceSAndroid Build Coastguard Worker# 7*35238bceSAndroid Build Coastguard Worker# Copyright 2017 The Android Open Source Project 8*35238bceSAndroid Build Coastguard Worker# 9*35238bceSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 10*35238bceSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 11*35238bceSAndroid Build Coastguard Worker# You may obtain a copy of the License at 12*35238bceSAndroid Build Coastguard Worker# 13*35238bceSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 14*35238bceSAndroid Build Coastguard Worker# 15*35238bceSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 16*35238bceSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 17*35238bceSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18*35238bceSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 19*35238bceSAndroid Build Coastguard Worker# limitations under the License. 20*35238bceSAndroid Build Coastguard Worker# 21*35238bceSAndroid Build Coastguard Worker#------------------------------------------------------------------------- 22*35238bceSAndroid Build Coastguard Worker 23*35238bceSAndroid Build Coastguard Worker# \todo [2017-04-10 pyry] 24*35238bceSAndroid Build Coastguard Worker# * Use smarter asset copy in main build 25*35238bceSAndroid Build Coastguard Worker# * cmake -E copy_directory doesn't copy timestamps which will cause 26*35238bceSAndroid Build Coastguard Worker# assets to be always re-packaged 27*35238bceSAndroid Build Coastguard Worker# * Consider adding an option for downloading SDK & NDK 28*35238bceSAndroid Build Coastguard Worker 29*35238bceSAndroid Build Coastguard Workerimport os 30*35238bceSAndroid Build Coastguard Workerimport re 31*35238bceSAndroid Build Coastguard Workerimport sys 32*35238bceSAndroid Build Coastguard Workerimport glob 33*35238bceSAndroid Build Coastguard Workerimport string 34*35238bceSAndroid Build Coastguard Workerimport shutil 35*35238bceSAndroid Build Coastguard Workerimport argparse 36*35238bceSAndroid Build Coastguard Workerimport tempfile 37*35238bceSAndroid Build Coastguard Workerimport xml.etree.ElementTree 38*35238bceSAndroid Build Coastguard Worker 39*35238bceSAndroid Build Coastguard Worker# Import from <root>/scripts 40*35238bceSAndroid Build Coastguard Workersys.path.append(os.path.join(os.path.dirname(__file__), "..")) 41*35238bceSAndroid Build Coastguard Worker 42*35238bceSAndroid Build Coastguard Workerfrom ctsbuild.common import * 43*35238bceSAndroid Build Coastguard Workerfrom ctsbuild.config import * 44*35238bceSAndroid Build Coastguard Workerfrom ctsbuild.build import * 45*35238bceSAndroid Build Coastguard Worker 46*35238bceSAndroid Build Coastguard Workerclass SDKEnv: 47*35238bceSAndroid Build Coastguard Worker def __init__(self, path, desired_version): 48*35238bceSAndroid Build Coastguard Worker self.path = path 49*35238bceSAndroid Build Coastguard Worker self.buildToolsVersion = SDKEnv.selectBuildToolsVersion(self.path, desired_version) 50*35238bceSAndroid Build Coastguard Worker 51*35238bceSAndroid Build Coastguard Worker @staticmethod 52*35238bceSAndroid Build Coastguard Worker def getBuildToolsVersions (path): 53*35238bceSAndroid Build Coastguard Worker buildToolsPath = os.path.join(path, "build-tools") 54*35238bceSAndroid Build Coastguard Worker versions = {} 55*35238bceSAndroid Build Coastguard Worker 56*35238bceSAndroid Build Coastguard Worker if os.path.exists(buildToolsPath): 57*35238bceSAndroid Build Coastguard Worker for item in os.listdir(buildToolsPath): 58*35238bceSAndroid Build Coastguard Worker m = re.match(r'^([0-9]+)\.([0-9]+)\.([0-9]+)$', item) 59*35238bceSAndroid Build Coastguard Worker if m != None: 60*35238bceSAndroid Build Coastguard Worker versions[int(m.group(1))] = (int(m.group(1)), int(m.group(2)), int(m.group(3))) 61*35238bceSAndroid Build Coastguard Worker 62*35238bceSAndroid Build Coastguard Worker return versions 63*35238bceSAndroid Build Coastguard Worker 64*35238bceSAndroid Build Coastguard Worker @staticmethod 65*35238bceSAndroid Build Coastguard Worker def selectBuildToolsVersion (path, preferred): 66*35238bceSAndroid Build Coastguard Worker versions = SDKEnv.getBuildToolsVersions(path) 67*35238bceSAndroid Build Coastguard Worker 68*35238bceSAndroid Build Coastguard Worker if len(versions) == 0: 69*35238bceSAndroid Build Coastguard Worker return (0,0,0) 70*35238bceSAndroid Build Coastguard Worker 71*35238bceSAndroid Build Coastguard Worker if preferred == -1: 72*35238bceSAndroid Build Coastguard Worker return max(versions.values()) 73*35238bceSAndroid Build Coastguard Worker 74*35238bceSAndroid Build Coastguard Worker if preferred in versions: 75*35238bceSAndroid Build Coastguard Worker return versions[preferred] 76*35238bceSAndroid Build Coastguard Worker 77*35238bceSAndroid Build Coastguard Worker # Pick newest 78*35238bceSAndroid Build Coastguard Worker newest_version = max(versions.values()) 79*35238bceSAndroid Build Coastguard Worker print("Couldn't find Android Tool version %d, %d was selected." % (preferred, newest_version[0])) 80*35238bceSAndroid Build Coastguard Worker return newest_version 81*35238bceSAndroid Build Coastguard Worker 82*35238bceSAndroid Build Coastguard Worker def getPlatformLibrary (self, apiVersion): 83*35238bceSAndroid Build Coastguard Worker return os.path.join(self.path, "platforms", "android-%d" % apiVersion, "android.jar") 84*35238bceSAndroid Build Coastguard Worker 85*35238bceSAndroid Build Coastguard Worker def getBuildToolsPath (self): 86*35238bceSAndroid Build Coastguard Worker return os.path.join(self.path, "build-tools", "%d.%d.%d" % self.buildToolsVersion) 87*35238bceSAndroid Build Coastguard Worker 88*35238bceSAndroid Build Coastguard Workerclass NDKEnv: 89*35238bceSAndroid Build Coastguard Worker def __init__(self, path): 90*35238bceSAndroid Build Coastguard Worker self.path = path 91*35238bceSAndroid Build Coastguard Worker self.version = NDKEnv.detectVersion(self.path) 92*35238bceSAndroid Build Coastguard Worker self.hostOsName = NDKEnv.detectHostOsName(self.path) 93*35238bceSAndroid Build Coastguard Worker 94*35238bceSAndroid Build Coastguard Worker @staticmethod 95*35238bceSAndroid Build Coastguard Worker def getKnownAbis (): 96*35238bceSAndroid Build Coastguard Worker return ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"] 97*35238bceSAndroid Build Coastguard Worker 98*35238bceSAndroid Build Coastguard Worker @staticmethod 99*35238bceSAndroid Build Coastguard Worker def getAbiPrebuiltsName (abiName): 100*35238bceSAndroid Build Coastguard Worker prebuilts = { 101*35238bceSAndroid Build Coastguard Worker "armeabi-v7a": 'android-arm', 102*35238bceSAndroid Build Coastguard Worker "arm64-v8a": 'android-arm64', 103*35238bceSAndroid Build Coastguard Worker "x86": 'android-x86', 104*35238bceSAndroid Build Coastguard Worker "x86_64": 'android-x86_64', 105*35238bceSAndroid Build Coastguard Worker } 106*35238bceSAndroid Build Coastguard Worker 107*35238bceSAndroid Build Coastguard Worker if not abiName in prebuilts: 108*35238bceSAndroid Build Coastguard Worker raise Exception("Unknown ABI: " + abiName) 109*35238bceSAndroid Build Coastguard Worker 110*35238bceSAndroid Build Coastguard Worker return prebuilts[abiName] 111*35238bceSAndroid Build Coastguard Worker 112*35238bceSAndroid Build Coastguard Worker @staticmethod 113*35238bceSAndroid Build Coastguard Worker def detectVersion (path): 114*35238bceSAndroid Build Coastguard Worker propFilePath = os.path.join(path, "source.properties") 115*35238bceSAndroid Build Coastguard Worker try: 116*35238bceSAndroid Build Coastguard Worker with open(propFilePath) as propFile: 117*35238bceSAndroid Build Coastguard Worker for line in propFile: 118*35238bceSAndroid Build Coastguard Worker keyValue = list(map(lambda x: x.strip(), line.split("="))) 119*35238bceSAndroid Build Coastguard Worker if keyValue[0] == "Pkg.Revision": 120*35238bceSAndroid Build Coastguard Worker versionParts = keyValue[1].split(".") 121*35238bceSAndroid Build Coastguard Worker return tuple(map(int, versionParts[0:2])) 122*35238bceSAndroid Build Coastguard Worker except Exception as e: 123*35238bceSAndroid Build Coastguard Worker raise Exception("Failed to read source prop file '%s': %s" % (propFilePath, str(e))) 124*35238bceSAndroid Build Coastguard Worker except: 125*35238bceSAndroid Build Coastguard Worker raise Exception("Failed to read source prop file '%s': unkown error") 126*35238bceSAndroid Build Coastguard Worker 127*35238bceSAndroid Build Coastguard Worker raise Exception("Failed to detect NDK version (does %s/source.properties have Pkg.Revision?)" % path) 128*35238bceSAndroid Build Coastguard Worker 129*35238bceSAndroid Build Coastguard Worker @staticmethod 130*35238bceSAndroid Build Coastguard Worker def isHostOsSupported (hostOsName): 131*35238bceSAndroid Build Coastguard Worker os = HostInfo.getOs() 132*35238bceSAndroid Build Coastguard Worker bits = HostInfo.getArchBits() 133*35238bceSAndroid Build Coastguard Worker hostOsParts = hostOsName.split('-') 134*35238bceSAndroid Build Coastguard Worker 135*35238bceSAndroid Build Coastguard Worker if len(hostOsParts) > 1: 136*35238bceSAndroid Build Coastguard Worker assert(len(hostOsParts) == 2) 137*35238bceSAndroid Build Coastguard Worker assert(hostOsParts[1] == "x86_64") 138*35238bceSAndroid Build Coastguard Worker 139*35238bceSAndroid Build Coastguard Worker if bits != 64: 140*35238bceSAndroid Build Coastguard Worker return False 141*35238bceSAndroid Build Coastguard Worker 142*35238bceSAndroid Build Coastguard Worker if os == HostInfo.OS_WINDOWS: 143*35238bceSAndroid Build Coastguard Worker return hostOsParts[0] == 'windows' 144*35238bceSAndroid Build Coastguard Worker elif os == HostInfo.OS_LINUX: 145*35238bceSAndroid Build Coastguard Worker return hostOsParts[0] == 'linux' 146*35238bceSAndroid Build Coastguard Worker elif os == HostInfo.OS_OSX: 147*35238bceSAndroid Build Coastguard Worker return hostOsParts[0] == 'darwin' 148*35238bceSAndroid Build Coastguard Worker else: 149*35238bceSAndroid Build Coastguard Worker raise Exception("Unhandled HostInfo.getOs() '%d'" % os) 150*35238bceSAndroid Build Coastguard Worker 151*35238bceSAndroid Build Coastguard Worker @staticmethod 152*35238bceSAndroid Build Coastguard Worker def detectHostOsName (path): 153*35238bceSAndroid Build Coastguard Worker hostOsNames = [ 154*35238bceSAndroid Build Coastguard Worker "windows", 155*35238bceSAndroid Build Coastguard Worker "windows-x86_64", 156*35238bceSAndroid Build Coastguard Worker "darwin-x86", 157*35238bceSAndroid Build Coastguard Worker "darwin-x86_64", 158*35238bceSAndroid Build Coastguard Worker "linux-x86", 159*35238bceSAndroid Build Coastguard Worker "linux-x86_64" 160*35238bceSAndroid Build Coastguard Worker ] 161*35238bceSAndroid Build Coastguard Worker 162*35238bceSAndroid Build Coastguard Worker for name in hostOsNames: 163*35238bceSAndroid Build Coastguard Worker if os.path.exists(os.path.join(path, "prebuilt", name)): 164*35238bceSAndroid Build Coastguard Worker return name 165*35238bceSAndroid Build Coastguard Worker 166*35238bceSAndroid Build Coastguard Worker raise Exception("Failed to determine NDK host OS") 167*35238bceSAndroid Build Coastguard Worker 168*35238bceSAndroid Build Coastguard Workerclass Environment: 169*35238bceSAndroid Build Coastguard Worker def __init__(self, sdk, ndk): 170*35238bceSAndroid Build Coastguard Worker self.sdk = sdk 171*35238bceSAndroid Build Coastguard Worker self.ndk = ndk 172*35238bceSAndroid Build Coastguard Worker 173*35238bceSAndroid Build Coastguard Workerclass Configuration: 174*35238bceSAndroid Build Coastguard Worker def __init__(self, env, buildPath, abis, nativeApi, javaApi, minApi, nativeBuildType, gtfTarget, verbose, layers, angle): 175*35238bceSAndroid Build Coastguard Worker self.env = env 176*35238bceSAndroid Build Coastguard Worker self.sourcePath = DEQP_DIR 177*35238bceSAndroid Build Coastguard Worker self.buildPath = buildPath 178*35238bceSAndroid Build Coastguard Worker self.abis = abis 179*35238bceSAndroid Build Coastguard Worker self.nativeApi = nativeApi 180*35238bceSAndroid Build Coastguard Worker self.javaApi = javaApi 181*35238bceSAndroid Build Coastguard Worker self.minApi = minApi 182*35238bceSAndroid Build Coastguard Worker self.nativeBuildType = nativeBuildType 183*35238bceSAndroid Build Coastguard Worker self.gtfTarget = gtfTarget 184*35238bceSAndroid Build Coastguard Worker self.verbose = verbose 185*35238bceSAndroid Build Coastguard Worker self.layers = layers 186*35238bceSAndroid Build Coastguard Worker self.angle = angle 187*35238bceSAndroid Build Coastguard Worker self.dCompilerName = "d8" 188*35238bceSAndroid Build Coastguard Worker self.cmakeGenerator = selectFirstAvailableGenerator([NINJA_GENERATOR, MAKEFILE_GENERATOR, NMAKE_GENERATOR]) 189*35238bceSAndroid Build Coastguard Worker 190*35238bceSAndroid Build Coastguard Worker def check (self): 191*35238bceSAndroid Build Coastguard Worker if self.cmakeGenerator == None: 192*35238bceSAndroid Build Coastguard Worker raise Exception("Failed to find build tools for CMake") 193*35238bceSAndroid Build Coastguard Worker 194*35238bceSAndroid Build Coastguard Worker if not os.path.exists(self.env.ndk.path): 195*35238bceSAndroid Build Coastguard Worker raise Exception("Android NDK not found at %s" % self.env.ndk.path) 196*35238bceSAndroid Build Coastguard Worker 197*35238bceSAndroid Build Coastguard Worker if not NDKEnv.isHostOsSupported(self.env.ndk.hostOsName): 198*35238bceSAndroid Build Coastguard Worker raise Exception("NDK '%s' is not supported on this machine" % self.env.ndk.hostOsName) 199*35238bceSAndroid Build Coastguard Worker 200*35238bceSAndroid Build Coastguard Worker if self.env.ndk.version[0] < 15: 201*35238bceSAndroid Build Coastguard Worker raise Exception("Android NDK version %d is not supported; build requires NDK version >= 15" % (self.env.ndk.version[0])) 202*35238bceSAndroid Build Coastguard Worker 203*35238bceSAndroid Build Coastguard Worker if not (self.minApi <= self.javaApi <= self.nativeApi): 204*35238bceSAndroid Build Coastguard Worker raise Exception("Requires: min-api (%d) <= java-api (%d) <= native-api (%d)" % (self.minApi, self.javaApi, self.nativeApi)) 205*35238bceSAndroid Build Coastguard Worker 206*35238bceSAndroid Build Coastguard Worker if self.env.sdk.buildToolsVersion == (0,0,0): 207*35238bceSAndroid Build Coastguard Worker raise Exception("No build tools directory found at %s" % os.path.join(self.env.sdk.path, "build-tools")) 208*35238bceSAndroid Build Coastguard Worker 209*35238bceSAndroid Build Coastguard Worker if not os.path.exists(os.path.join(self.env.sdk.path, "platforms", "android-%d" % self.javaApi)): 210*35238bceSAndroid Build Coastguard Worker raise Exception("No SDK with api version %d directory found at %s for Java Api" % (self.javaApi, os.path.join(self.env.sdk.path, "platforms"))) 211*35238bceSAndroid Build Coastguard Worker 212*35238bceSAndroid Build Coastguard Worker # Try to find first d8 since dx was deprecated 213*35238bceSAndroid Build Coastguard Worker if which(self.dCompilerName, [self.env.sdk.getBuildToolsPath()]) == None: 214*35238bceSAndroid Build Coastguard Worker print("Couldn't find %s, will try to find dx", self.dCompilerName) 215*35238bceSAndroid Build Coastguard Worker self.dCompilerName = "dx" 216*35238bceSAndroid Build Coastguard Worker 217*35238bceSAndroid Build Coastguard Worker androidBuildTools = ["aapt", "zipalign", "apksigner", self.dCompilerName] 218*35238bceSAndroid Build Coastguard Worker for tool in androidBuildTools: 219*35238bceSAndroid Build Coastguard Worker if which(tool, [self.env.sdk.getBuildToolsPath()]) == None: 220*35238bceSAndroid Build Coastguard Worker raise Exception("Missing Android build tool: %s in %s" % (tool, self.env.sdk.getBuildToolsPath())) 221*35238bceSAndroid Build Coastguard Worker 222*35238bceSAndroid Build Coastguard Worker requiredToolsInPath = ["javac", "jar", "keytool"] 223*35238bceSAndroid Build Coastguard Worker for tool in requiredToolsInPath: 224*35238bceSAndroid Build Coastguard Worker if which(tool) == None: 225*35238bceSAndroid Build Coastguard Worker raise Exception("%s not in PATH" % tool) 226*35238bceSAndroid Build Coastguard Worker 227*35238bceSAndroid Build Coastguard Workerdef log (config, msg): 228*35238bceSAndroid Build Coastguard Worker if config.verbose: 229*35238bceSAndroid Build Coastguard Worker print(msg) 230*35238bceSAndroid Build Coastguard Worker 231*35238bceSAndroid Build Coastguard Workerdef executeAndLog (config, args): 232*35238bceSAndroid Build Coastguard Worker if config.verbose: 233*35238bceSAndroid Build Coastguard Worker print(" ".join(args)) 234*35238bceSAndroid Build Coastguard Worker execute(args) 235*35238bceSAndroid Build Coastguard Worker 236*35238bceSAndroid Build Coastguard Worker# Path components 237*35238bceSAndroid Build Coastguard Worker 238*35238bceSAndroid Build Coastguard Workerclass ResolvablePathComponent: 239*35238bceSAndroid Build Coastguard Worker def __init__ (self): 240*35238bceSAndroid Build Coastguard Worker pass 241*35238bceSAndroid Build Coastguard Worker 242*35238bceSAndroid Build Coastguard Workerclass SourceRoot (ResolvablePathComponent): 243*35238bceSAndroid Build Coastguard Worker def resolve (self, config): 244*35238bceSAndroid Build Coastguard Worker return config.sourcePath 245*35238bceSAndroid Build Coastguard Worker 246*35238bceSAndroid Build Coastguard Workerclass BuildRoot (ResolvablePathComponent): 247*35238bceSAndroid Build Coastguard Worker def resolve (self, config): 248*35238bceSAndroid Build Coastguard Worker return config.buildPath 249*35238bceSAndroid Build Coastguard Worker 250*35238bceSAndroid Build Coastguard Workerclass NativeBuildPath (ResolvablePathComponent): 251*35238bceSAndroid Build Coastguard Worker def __init__ (self, abiName): 252*35238bceSAndroid Build Coastguard Worker self.abiName = abiName 253*35238bceSAndroid Build Coastguard Worker 254*35238bceSAndroid Build Coastguard Worker def resolve (self, config): 255*35238bceSAndroid Build Coastguard Worker return getNativeBuildPath(config, self.abiName) 256*35238bceSAndroid Build Coastguard Worker 257*35238bceSAndroid Build Coastguard Workerclass GeneratedResSourcePath (ResolvablePathComponent): 258*35238bceSAndroid Build Coastguard Worker def __init__ (self, package): 259*35238bceSAndroid Build Coastguard Worker self.package = package 260*35238bceSAndroid Build Coastguard Worker 261*35238bceSAndroid Build Coastguard Worker def resolve (self, config): 262*35238bceSAndroid Build Coastguard Worker packageComps = self.package.getPackageName(config).split('.') 263*35238bceSAndroid Build Coastguard Worker packageDir = os.path.join(*packageComps) 264*35238bceSAndroid Build Coastguard Worker 265*35238bceSAndroid Build Coastguard Worker return os.path.join(config.buildPath, self.package.getAppDirName(), "src", packageDir, "R.java") 266*35238bceSAndroid Build Coastguard Worker 267*35238bceSAndroid Build Coastguard Workerdef resolvePath (config, path): 268*35238bceSAndroid Build Coastguard Worker resolvedComps = [] 269*35238bceSAndroid Build Coastguard Worker 270*35238bceSAndroid Build Coastguard Worker for component in path: 271*35238bceSAndroid Build Coastguard Worker if isinstance(component, ResolvablePathComponent): 272*35238bceSAndroid Build Coastguard Worker resolvedComps.append(component.resolve(config)) 273*35238bceSAndroid Build Coastguard Worker else: 274*35238bceSAndroid Build Coastguard Worker resolvedComps.append(str(component)) 275*35238bceSAndroid Build Coastguard Worker 276*35238bceSAndroid Build Coastguard Worker return os.path.join(*resolvedComps) 277*35238bceSAndroid Build Coastguard Worker 278*35238bceSAndroid Build Coastguard Workerdef resolvePaths (config, paths): 279*35238bceSAndroid Build Coastguard Worker return list(map(lambda p: resolvePath(config, p), paths)) 280*35238bceSAndroid Build Coastguard Worker 281*35238bceSAndroid Build Coastguard Workerclass BuildStep: 282*35238bceSAndroid Build Coastguard Worker def __init__ (self): 283*35238bceSAndroid Build Coastguard Worker pass 284*35238bceSAndroid Build Coastguard Worker 285*35238bceSAndroid Build Coastguard Worker def getInputs (self): 286*35238bceSAndroid Build Coastguard Worker return [] 287*35238bceSAndroid Build Coastguard Worker 288*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 289*35238bceSAndroid Build Coastguard Worker return [] 290*35238bceSAndroid Build Coastguard Worker 291*35238bceSAndroid Build Coastguard Worker @staticmethod 292*35238bceSAndroid Build Coastguard Worker def expandPathsToFiles (paths): 293*35238bceSAndroid Build Coastguard Worker """ 294*35238bceSAndroid Build Coastguard Worker Expand mixed list of file and directory paths into a flattened list 295*35238bceSAndroid Build Coastguard Worker of files. Any non-existent input paths are preserved as is. 296*35238bceSAndroid Build Coastguard Worker """ 297*35238bceSAndroid Build Coastguard Worker 298*35238bceSAndroid Build Coastguard Worker def getFiles (dirPath): 299*35238bceSAndroid Build Coastguard Worker for root, dirs, files in os.walk(dirPath): 300*35238bceSAndroid Build Coastguard Worker for file in files: 301*35238bceSAndroid Build Coastguard Worker yield os.path.join(root, file) 302*35238bceSAndroid Build Coastguard Worker 303*35238bceSAndroid Build Coastguard Worker files = [] 304*35238bceSAndroid Build Coastguard Worker for path in paths: 305*35238bceSAndroid Build Coastguard Worker if os.path.isdir(path): 306*35238bceSAndroid Build Coastguard Worker files += list(getFiles(path)) 307*35238bceSAndroid Build Coastguard Worker else: 308*35238bceSAndroid Build Coastguard Worker files.append(path) 309*35238bceSAndroid Build Coastguard Worker 310*35238bceSAndroid Build Coastguard Worker return files 311*35238bceSAndroid Build Coastguard Worker 312*35238bceSAndroid Build Coastguard Worker def isUpToDate (self, config): 313*35238bceSAndroid Build Coastguard Worker inputs = resolvePaths(config, self.getInputs()) 314*35238bceSAndroid Build Coastguard Worker outputs = resolvePaths(config, self.getOutputs()) 315*35238bceSAndroid Build Coastguard Worker 316*35238bceSAndroid Build Coastguard Worker assert len(inputs) > 0 and len(outputs) > 0 317*35238bceSAndroid Build Coastguard Worker 318*35238bceSAndroid Build Coastguard Worker expandedInputs = BuildStep.expandPathsToFiles(inputs) 319*35238bceSAndroid Build Coastguard Worker expandedOutputs = BuildStep.expandPathsToFiles(outputs) 320*35238bceSAndroid Build Coastguard Worker 321*35238bceSAndroid Build Coastguard Worker existingInputs = list(filter(os.path.exists, expandedInputs)) 322*35238bceSAndroid Build Coastguard Worker existingOutputs = list(filter(os.path.exists, expandedOutputs)) 323*35238bceSAndroid Build Coastguard Worker 324*35238bceSAndroid Build Coastguard Worker if len(existingInputs) != len(expandedInputs): 325*35238bceSAndroid Build Coastguard Worker for file in expandedInputs: 326*35238bceSAndroid Build Coastguard Worker if file not in existingInputs: 327*35238bceSAndroid Build Coastguard Worker print("ERROR: Missing input file: %s" % file) 328*35238bceSAndroid Build Coastguard Worker die("Missing input files") 329*35238bceSAndroid Build Coastguard Worker 330*35238bceSAndroid Build Coastguard Worker if len(existingOutputs) != len(expandedOutputs): 331*35238bceSAndroid Build Coastguard Worker return False # One or more output files are missing 332*35238bceSAndroid Build Coastguard Worker 333*35238bceSAndroid Build Coastguard Worker lastInputChange = max(map(os.path.getmtime, existingInputs)) 334*35238bceSAndroid Build Coastguard Worker firstOutputChange = min(map(os.path.getmtime, existingOutputs)) 335*35238bceSAndroid Build Coastguard Worker 336*35238bceSAndroid Build Coastguard Worker return lastInputChange <= firstOutputChange 337*35238bceSAndroid Build Coastguard Worker 338*35238bceSAndroid Build Coastguard Worker def update (config): 339*35238bceSAndroid Build Coastguard Worker die("BuildStep.update() not implemented") 340*35238bceSAndroid Build Coastguard Worker 341*35238bceSAndroid Build Coastguard Workerdef getNativeBuildPath (config, abiName): 342*35238bceSAndroid Build Coastguard Worker return os.path.join(config.buildPath, "%s-%s-%d" % (abiName, config.nativeBuildType, config.nativeApi)) 343*35238bceSAndroid Build Coastguard Worker 344*35238bceSAndroid Build Coastguard Workerdef clearCMakeCacheVariables(args): 345*35238bceSAndroid Build Coastguard Worker # New value, so clear the necessary cmake variables 346*35238bceSAndroid Build Coastguard Worker args.append('-UANGLE_LIBS') 347*35238bceSAndroid Build Coastguard Worker args.append('-UGLES1_LIBRARY') 348*35238bceSAndroid Build Coastguard Worker args.append('-UGLES2_LIBRARY') 349*35238bceSAndroid Build Coastguard Worker args.append('-UEGL_LIBRARY') 350*35238bceSAndroid Build Coastguard Worker 351*35238bceSAndroid Build Coastguard Workerdef buildNativeLibrary (config, abiName): 352*35238bceSAndroid Build Coastguard Worker def makeNDKVersionString (version): 353*35238bceSAndroid Build Coastguard Worker minorVersionString = (chr(ord('a') + version[1]) if version[1] > 0 else "") 354*35238bceSAndroid Build Coastguard Worker return "r%d%s" % (version[0], minorVersionString) 355*35238bceSAndroid Build Coastguard Worker 356*35238bceSAndroid Build Coastguard Worker def getBuildArgs (config, abiName): 357*35238bceSAndroid Build Coastguard Worker args = ['-DDEQP_TARGET=android', 358*35238bceSAndroid Build Coastguard Worker '-DDEQP_TARGET_TOOLCHAIN=ndk-modern', 359*35238bceSAndroid Build Coastguard Worker '-DCMAKE_C_FLAGS=-Werror', 360*35238bceSAndroid Build Coastguard Worker '-DCMAKE_CXX_FLAGS=-Werror', 361*35238bceSAndroid Build Coastguard Worker '-DANDROID_NDK_PATH=%s' % config.env.ndk.path, 362*35238bceSAndroid Build Coastguard Worker '-DANDROID_ABI=%s' % abiName, 363*35238bceSAndroid Build Coastguard Worker '-DDE_ANDROID_API=%s' % config.nativeApi, 364*35238bceSAndroid Build Coastguard Worker '-DGLCTS_GTF_TARGET=%s' % config.gtfTarget] 365*35238bceSAndroid Build Coastguard Worker 366*35238bceSAndroid Build Coastguard Worker if config.angle is None: 367*35238bceSAndroid Build Coastguard Worker # Find any previous builds that may have embedded ANGLE libs and clear the CMake cache 368*35238bceSAndroid Build Coastguard Worker for abi in NDKEnv.getKnownAbis(): 369*35238bceSAndroid Build Coastguard Worker cMakeCachePath = os.path.join(getNativeBuildPath(config, abi), "CMakeCache.txt") 370*35238bceSAndroid Build Coastguard Worker try: 371*35238bceSAndroid Build Coastguard Worker if 'ANGLE_LIBS' in open(cMakeCachePath).read(): 372*35238bceSAndroid Build Coastguard Worker clearCMakeCacheVariables(args) 373*35238bceSAndroid Build Coastguard Worker except IOError: 374*35238bceSAndroid Build Coastguard Worker pass 375*35238bceSAndroid Build Coastguard Worker else: 376*35238bceSAndroid Build Coastguard Worker cMakeCachePath = os.path.join(getNativeBuildPath(config, abiName), "CMakeCache.txt") 377*35238bceSAndroid Build Coastguard Worker angleLibsDir = os.path.join(config.angle, abiName) 378*35238bceSAndroid Build Coastguard Worker # Check if the user changed where the ANGLE libs are being loaded from 379*35238bceSAndroid Build Coastguard Worker try: 380*35238bceSAndroid Build Coastguard Worker if angleLibsDir not in open(cMakeCachePath).read(): 381*35238bceSAndroid Build Coastguard Worker clearCMakeCacheVariables(args) 382*35238bceSAndroid Build Coastguard Worker except IOError: 383*35238bceSAndroid Build Coastguard Worker pass 384*35238bceSAndroid Build Coastguard Worker args.append('-DANGLE_LIBS=%s' % angleLibsDir) 385*35238bceSAndroid Build Coastguard Worker 386*35238bceSAndroid Build Coastguard Worker return args 387*35238bceSAndroid Build Coastguard Worker 388*35238bceSAndroid Build Coastguard Worker nativeBuildPath = getNativeBuildPath(config, abiName) 389*35238bceSAndroid Build Coastguard Worker buildConfig = BuildConfig(nativeBuildPath, config.nativeBuildType, getBuildArgs(config, abiName)) 390*35238bceSAndroid Build Coastguard Worker 391*35238bceSAndroid Build Coastguard Worker build(buildConfig, config.cmakeGenerator, ["deqp"]) 392*35238bceSAndroid Build Coastguard Worker 393*35238bceSAndroid Build Coastguard Workerdef executeSteps (config, steps): 394*35238bceSAndroid Build Coastguard Worker for step in steps: 395*35238bceSAndroid Build Coastguard Worker if not step.isUpToDate(config): 396*35238bceSAndroid Build Coastguard Worker step.update(config) 397*35238bceSAndroid Build Coastguard Worker 398*35238bceSAndroid Build Coastguard Workerdef parsePackageName (manifestPath): 399*35238bceSAndroid Build Coastguard Worker tree = xml.etree.ElementTree.parse(manifestPath) 400*35238bceSAndroid Build Coastguard Worker 401*35238bceSAndroid Build Coastguard Worker if not 'package' in tree.getroot().attrib: 402*35238bceSAndroid Build Coastguard Worker raise Exception("'package' attribute missing from root element in %s" % manifestPath) 403*35238bceSAndroid Build Coastguard Worker 404*35238bceSAndroid Build Coastguard Worker return tree.getroot().attrib['package'] 405*35238bceSAndroid Build Coastguard Worker 406*35238bceSAndroid Build Coastguard Workerclass PackageDescription: 407*35238bceSAndroid Build Coastguard Worker def __init__ (self, appDirName, appName, hasResources = True): 408*35238bceSAndroid Build Coastguard Worker self.appDirName = appDirName 409*35238bceSAndroid Build Coastguard Worker self.appName = appName 410*35238bceSAndroid Build Coastguard Worker self.hasResources = hasResources 411*35238bceSAndroid Build Coastguard Worker 412*35238bceSAndroid Build Coastguard Worker def getAppName (self): 413*35238bceSAndroid Build Coastguard Worker return self.appName 414*35238bceSAndroid Build Coastguard Worker 415*35238bceSAndroid Build Coastguard Worker def getAppDirName (self): 416*35238bceSAndroid Build Coastguard Worker return self.appDirName 417*35238bceSAndroid Build Coastguard Worker 418*35238bceSAndroid Build Coastguard Worker def getPackageName (self, config): 419*35238bceSAndroid Build Coastguard Worker manifestPath = resolvePath(config, self.getManifestPath()) 420*35238bceSAndroid Build Coastguard Worker 421*35238bceSAndroid Build Coastguard Worker return parsePackageName(manifestPath) 422*35238bceSAndroid Build Coastguard Worker 423*35238bceSAndroid Build Coastguard Worker def getManifestPath (self): 424*35238bceSAndroid Build Coastguard Worker return [SourceRoot(), "android", self.appDirName, "AndroidManifest.xml"] 425*35238bceSAndroid Build Coastguard Worker 426*35238bceSAndroid Build Coastguard Worker def getResPath (self): 427*35238bceSAndroid Build Coastguard Worker return [SourceRoot(), "android", self.appDirName, "res"] 428*35238bceSAndroid Build Coastguard Worker 429*35238bceSAndroid Build Coastguard Worker def getSourcePaths (self): 430*35238bceSAndroid Build Coastguard Worker return [ 431*35238bceSAndroid Build Coastguard Worker [SourceRoot(), "android", self.appDirName, "src"] 432*35238bceSAndroid Build Coastguard Worker ] 433*35238bceSAndroid Build Coastguard Worker 434*35238bceSAndroid Build Coastguard Worker def getAssetsPath (self): 435*35238bceSAndroid Build Coastguard Worker return [BuildRoot(), self.appDirName, "assets"] 436*35238bceSAndroid Build Coastguard Worker 437*35238bceSAndroid Build Coastguard Worker def getClassesJarPath (self): 438*35238bceSAndroid Build Coastguard Worker return [BuildRoot(), self.appDirName, "bin", "classes.jar"] 439*35238bceSAndroid Build Coastguard Worker 440*35238bceSAndroid Build Coastguard Worker def getClassesDexDirectory (self): 441*35238bceSAndroid Build Coastguard Worker return [BuildRoot(), self.appDirName, "bin",] 442*35238bceSAndroid Build Coastguard Worker 443*35238bceSAndroid Build Coastguard Worker def getClassesDexPath (self): 444*35238bceSAndroid Build Coastguard Worker return [BuildRoot(), self.appDirName, "bin", "classes.dex"] 445*35238bceSAndroid Build Coastguard Worker 446*35238bceSAndroid Build Coastguard Worker def getAPKPath (self): 447*35238bceSAndroid Build Coastguard Worker return [BuildRoot(), self.appDirName, "bin", self.appName + ".apk"] 448*35238bceSAndroid Build Coastguard Worker 449*35238bceSAndroid Build Coastguard Worker# Build step implementations 450*35238bceSAndroid Build Coastguard Worker 451*35238bceSAndroid Build Coastguard Workerclass BuildNativeLibrary (BuildStep): 452*35238bceSAndroid Build Coastguard Worker def __init__ (self, abi): 453*35238bceSAndroid Build Coastguard Worker self.abi = abi 454*35238bceSAndroid Build Coastguard Worker 455*35238bceSAndroid Build Coastguard Worker def isUpToDate (self, config): 456*35238bceSAndroid Build Coastguard Worker return False 457*35238bceSAndroid Build Coastguard Worker 458*35238bceSAndroid Build Coastguard Worker def update (self, config): 459*35238bceSAndroid Build Coastguard Worker log(config, "BuildNativeLibrary: %s" % self.abi) 460*35238bceSAndroid Build Coastguard Worker buildNativeLibrary(config, self.abi) 461*35238bceSAndroid Build Coastguard Worker 462*35238bceSAndroid Build Coastguard Workerclass GenResourcesSrc (BuildStep): 463*35238bceSAndroid Build Coastguard Worker def __init__ (self, package): 464*35238bceSAndroid Build Coastguard Worker self.package = package 465*35238bceSAndroid Build Coastguard Worker 466*35238bceSAndroid Build Coastguard Worker def getInputs (self): 467*35238bceSAndroid Build Coastguard Worker return [self.package.getResPath(), self.package.getManifestPath()] 468*35238bceSAndroid Build Coastguard Worker 469*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 470*35238bceSAndroid Build Coastguard Worker return [[GeneratedResSourcePath(self.package)]] 471*35238bceSAndroid Build Coastguard Worker 472*35238bceSAndroid Build Coastguard Worker def update (self, config): 473*35238bceSAndroid Build Coastguard Worker aaptPath = which("aapt", [config.env.sdk.getBuildToolsPath()]) 474*35238bceSAndroid Build Coastguard Worker dstDir = os.path.dirname(resolvePath(config, [GeneratedResSourcePath(self.package)])) 475*35238bceSAndroid Build Coastguard Worker 476*35238bceSAndroid Build Coastguard Worker if not os.path.exists(dstDir): 477*35238bceSAndroid Build Coastguard Worker os.makedirs(dstDir) 478*35238bceSAndroid Build Coastguard Worker 479*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 480*35238bceSAndroid Build Coastguard Worker aaptPath, 481*35238bceSAndroid Build Coastguard Worker "package", 482*35238bceSAndroid Build Coastguard Worker "-f", 483*35238bceSAndroid Build Coastguard Worker "-m", 484*35238bceSAndroid Build Coastguard Worker "-S", resolvePath(config, self.package.getResPath()), 485*35238bceSAndroid Build Coastguard Worker "-M", resolvePath(config, self.package.getManifestPath()), 486*35238bceSAndroid Build Coastguard Worker "-J", resolvePath(config, [BuildRoot(), self.package.getAppDirName(), "src"]), 487*35238bceSAndroid Build Coastguard Worker "-I", config.env.sdk.getPlatformLibrary(config.javaApi) 488*35238bceSAndroid Build Coastguard Worker ]) 489*35238bceSAndroid Build Coastguard Worker 490*35238bceSAndroid Build Coastguard Worker# Builds classes.jar from *.java files 491*35238bceSAndroid Build Coastguard Workerclass BuildJavaSource (BuildStep): 492*35238bceSAndroid Build Coastguard Worker def __init__ (self, package, libraries = []): 493*35238bceSAndroid Build Coastguard Worker self.package = package 494*35238bceSAndroid Build Coastguard Worker self.libraries = libraries 495*35238bceSAndroid Build Coastguard Worker 496*35238bceSAndroid Build Coastguard Worker def getSourcePaths (self): 497*35238bceSAndroid Build Coastguard Worker srcPaths = self.package.getSourcePaths() 498*35238bceSAndroid Build Coastguard Worker 499*35238bceSAndroid Build Coastguard Worker if self.package.hasResources: 500*35238bceSAndroid Build Coastguard Worker srcPaths.append([BuildRoot(), self.package.getAppDirName(), "src"]) # Generated sources 501*35238bceSAndroid Build Coastguard Worker 502*35238bceSAndroid Build Coastguard Worker return srcPaths 503*35238bceSAndroid Build Coastguard Worker 504*35238bceSAndroid Build Coastguard Worker def getInputs (self): 505*35238bceSAndroid Build Coastguard Worker inputs = self.getSourcePaths() 506*35238bceSAndroid Build Coastguard Worker 507*35238bceSAndroid Build Coastguard Worker for lib in self.libraries: 508*35238bceSAndroid Build Coastguard Worker inputs.append(lib.getClassesJarPath()) 509*35238bceSAndroid Build Coastguard Worker 510*35238bceSAndroid Build Coastguard Worker return inputs 511*35238bceSAndroid Build Coastguard Worker 512*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 513*35238bceSAndroid Build Coastguard Worker return [self.package.getClassesJarPath()] 514*35238bceSAndroid Build Coastguard Worker 515*35238bceSAndroid Build Coastguard Worker def update (self, config): 516*35238bceSAndroid Build Coastguard Worker srcPaths = resolvePaths(config, self.getSourcePaths()) 517*35238bceSAndroid Build Coastguard Worker srcFiles = BuildStep.expandPathsToFiles(srcPaths) 518*35238bceSAndroid Build Coastguard Worker jarPath = resolvePath(config, self.package.getClassesJarPath()) 519*35238bceSAndroid Build Coastguard Worker objPath = resolvePath(config, [BuildRoot(), self.package.getAppDirName(), "obj"]) 520*35238bceSAndroid Build Coastguard Worker classPaths = [objPath] + [resolvePath(config, lib.getClassesJarPath()) for lib in self.libraries] 521*35238bceSAndroid Build Coastguard Worker pathSep = ";" if HostInfo.getOs() == HostInfo.OS_WINDOWS else ":" 522*35238bceSAndroid Build Coastguard Worker 523*35238bceSAndroid Build Coastguard Worker if os.path.exists(objPath): 524*35238bceSAndroid Build Coastguard Worker shutil.rmtree(objPath) 525*35238bceSAndroid Build Coastguard Worker 526*35238bceSAndroid Build Coastguard Worker os.makedirs(objPath) 527*35238bceSAndroid Build Coastguard Worker 528*35238bceSAndroid Build Coastguard Worker for srcFile in srcFiles: 529*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 530*35238bceSAndroid Build Coastguard Worker "javac", 531*35238bceSAndroid Build Coastguard Worker "-source", "1.7", 532*35238bceSAndroid Build Coastguard Worker "-target", "1.7", 533*35238bceSAndroid Build Coastguard Worker "-d", objPath, 534*35238bceSAndroid Build Coastguard Worker "-bootclasspath", config.env.sdk.getPlatformLibrary(config.javaApi), 535*35238bceSAndroid Build Coastguard Worker "-classpath", pathSep.join(classPaths), 536*35238bceSAndroid Build Coastguard Worker "-sourcepath", pathSep.join(srcPaths), 537*35238bceSAndroid Build Coastguard Worker srcFile 538*35238bceSAndroid Build Coastguard Worker ]) 539*35238bceSAndroid Build Coastguard Worker 540*35238bceSAndroid Build Coastguard Worker if not os.path.exists(os.path.dirname(jarPath)): 541*35238bceSAndroid Build Coastguard Worker os.makedirs(os.path.dirname(jarPath)) 542*35238bceSAndroid Build Coastguard Worker 543*35238bceSAndroid Build Coastguard Worker try: 544*35238bceSAndroid Build Coastguard Worker pushWorkingDir(objPath) 545*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 546*35238bceSAndroid Build Coastguard Worker "jar", 547*35238bceSAndroid Build Coastguard Worker "cf", 548*35238bceSAndroid Build Coastguard Worker jarPath, 549*35238bceSAndroid Build Coastguard Worker "." 550*35238bceSAndroid Build Coastguard Worker ]) 551*35238bceSAndroid Build Coastguard Worker finally: 552*35238bceSAndroid Build Coastguard Worker popWorkingDir() 553*35238bceSAndroid Build Coastguard Worker 554*35238bceSAndroid Build Coastguard Workerclass BuildDex (BuildStep): 555*35238bceSAndroid Build Coastguard Worker def __init__ (self, package, libraries): 556*35238bceSAndroid Build Coastguard Worker self.package = package 557*35238bceSAndroid Build Coastguard Worker self.libraries = libraries 558*35238bceSAndroid Build Coastguard Worker 559*35238bceSAndroid Build Coastguard Worker def getInputs (self): 560*35238bceSAndroid Build Coastguard Worker return [self.package.getClassesJarPath()] + [lib.getClassesJarPath() for lib in self.libraries] 561*35238bceSAndroid Build Coastguard Worker 562*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 563*35238bceSAndroid Build Coastguard Worker return [self.package.getClassesDexPath()] 564*35238bceSAndroid Build Coastguard Worker 565*35238bceSAndroid Build Coastguard Worker def update (self, config): 566*35238bceSAndroid Build Coastguard Worker dxPath = which(config.dCompilerName, [config.env.sdk.getBuildToolsPath()]) 567*35238bceSAndroid Build Coastguard Worker dexPath = resolvePath(config, self.package.getClassesDexDirectory()) 568*35238bceSAndroid Build Coastguard Worker jarPaths = [resolvePath(config, self.package.getClassesJarPath())] 569*35238bceSAndroid Build Coastguard Worker 570*35238bceSAndroid Build Coastguard Worker for lib in self.libraries: 571*35238bceSAndroid Build Coastguard Worker jarPaths.append(resolvePath(config, lib.getClassesJarPath())) 572*35238bceSAndroid Build Coastguard Worker 573*35238bceSAndroid Build Coastguard Worker args = [ dxPath ] 574*35238bceSAndroid Build Coastguard Worker if config.dCompilerName == "d8": 575*35238bceSAndroid Build Coastguard Worker args.append("--lib") 576*35238bceSAndroid Build Coastguard Worker args.append(config.env.sdk.getPlatformLibrary(config.javaApi)) 577*35238bceSAndroid Build Coastguard Worker else: 578*35238bceSAndroid Build Coastguard Worker args.append("--dex") 579*35238bceSAndroid Build Coastguard Worker args.append("--output") 580*35238bceSAndroid Build Coastguard Worker args.append(dexPath) 581*35238bceSAndroid Build Coastguard Worker 582*35238bceSAndroid Build Coastguard Worker executeAndLog(config, args + jarPaths) 583*35238bceSAndroid Build Coastguard Worker 584*35238bceSAndroid Build Coastguard Workerclass CreateKeystore (BuildStep): 585*35238bceSAndroid Build Coastguard Worker def __init__ (self): 586*35238bceSAndroid Build Coastguard Worker self.keystorePath = [BuildRoot(), "debug.keystore"] 587*35238bceSAndroid Build Coastguard Worker 588*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 589*35238bceSAndroid Build Coastguard Worker return [self.keystorePath] 590*35238bceSAndroid Build Coastguard Worker 591*35238bceSAndroid Build Coastguard Worker def isUpToDate (self, config): 592*35238bceSAndroid Build Coastguard Worker return os.path.exists(resolvePath(config, self.keystorePath)) 593*35238bceSAndroid Build Coastguard Worker 594*35238bceSAndroid Build Coastguard Worker def update (self, config): 595*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 596*35238bceSAndroid Build Coastguard Worker "keytool", 597*35238bceSAndroid Build Coastguard Worker "-genkeypair", 598*35238bceSAndroid Build Coastguard Worker "-keystore", resolvePath(config, self.keystorePath), 599*35238bceSAndroid Build Coastguard Worker "-storepass", "android", 600*35238bceSAndroid Build Coastguard Worker "-alias", "androiddebugkey", 601*35238bceSAndroid Build Coastguard Worker "-keypass", "android", 602*35238bceSAndroid Build Coastguard Worker "-keyalg", "RSA", 603*35238bceSAndroid Build Coastguard Worker "-keysize", "2048", 604*35238bceSAndroid Build Coastguard Worker "-validity", "10000", 605*35238bceSAndroid Build Coastguard Worker "-dname", "CN=, OU=, O=, L=, S=, C=", 606*35238bceSAndroid Build Coastguard Worker ]) 607*35238bceSAndroid Build Coastguard Worker 608*35238bceSAndroid Build Coastguard Worker# Builds APK without code 609*35238bceSAndroid Build Coastguard Workerclass BuildBaseAPK (BuildStep): 610*35238bceSAndroid Build Coastguard Worker def __init__ (self, package, libraries = []): 611*35238bceSAndroid Build Coastguard Worker self.package = package 612*35238bceSAndroid Build Coastguard Worker self.libraries = libraries 613*35238bceSAndroid Build Coastguard Worker self.dstPath = [BuildRoot(), self.package.getAppDirName(), "tmp", "base.apk"] 614*35238bceSAndroid Build Coastguard Worker 615*35238bceSAndroid Build Coastguard Worker def getResPaths (self): 616*35238bceSAndroid Build Coastguard Worker paths = [] 617*35238bceSAndroid Build Coastguard Worker for pkg in [self.package] + self.libraries: 618*35238bceSAndroid Build Coastguard Worker if pkg.hasResources: 619*35238bceSAndroid Build Coastguard Worker paths.append(pkg.getResPath()) 620*35238bceSAndroid Build Coastguard Worker return paths 621*35238bceSAndroid Build Coastguard Worker 622*35238bceSAndroid Build Coastguard Worker def getInputs (self): 623*35238bceSAndroid Build Coastguard Worker return [self.package.getManifestPath()] + self.getResPaths() 624*35238bceSAndroid Build Coastguard Worker 625*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 626*35238bceSAndroid Build Coastguard Worker return [self.dstPath] 627*35238bceSAndroid Build Coastguard Worker 628*35238bceSAndroid Build Coastguard Worker def update (self, config): 629*35238bceSAndroid Build Coastguard Worker aaptPath = which("aapt", [config.env.sdk.getBuildToolsPath()]) 630*35238bceSAndroid Build Coastguard Worker dstPath = resolvePath(config, self.dstPath) 631*35238bceSAndroid Build Coastguard Worker 632*35238bceSAndroid Build Coastguard Worker if not os.path.exists(os.path.dirname(dstPath)): 633*35238bceSAndroid Build Coastguard Worker os.makedirs(os.path.dirname(dstPath)) 634*35238bceSAndroid Build Coastguard Worker 635*35238bceSAndroid Build Coastguard Worker args = [ 636*35238bceSAndroid Build Coastguard Worker aaptPath, 637*35238bceSAndroid Build Coastguard Worker "package", 638*35238bceSAndroid Build Coastguard Worker "-f", 639*35238bceSAndroid Build Coastguard Worker "--min-sdk-version", str(config.minApi), 640*35238bceSAndroid Build Coastguard Worker "--target-sdk-version", str(config.javaApi), 641*35238bceSAndroid Build Coastguard Worker "-M", resolvePath(config, self.package.getManifestPath()), 642*35238bceSAndroid Build Coastguard Worker "-I", config.env.sdk.getPlatformLibrary(config.javaApi), 643*35238bceSAndroid Build Coastguard Worker "-F", dstPath, 644*35238bceSAndroid Build Coastguard Worker "-0", "arsc" # arsc files need to be uncompressed for SDK version 30 and up 645*35238bceSAndroid Build Coastguard Worker ] 646*35238bceSAndroid Build Coastguard Worker 647*35238bceSAndroid Build Coastguard Worker for resPath in self.getResPaths(): 648*35238bceSAndroid Build Coastguard Worker args += ["-S", resolvePath(config, resPath)] 649*35238bceSAndroid Build Coastguard Worker 650*35238bceSAndroid Build Coastguard Worker if config.verbose: 651*35238bceSAndroid Build Coastguard Worker args.append("-v") 652*35238bceSAndroid Build Coastguard Worker 653*35238bceSAndroid Build Coastguard Worker executeAndLog(config, args) 654*35238bceSAndroid Build Coastguard Worker 655*35238bceSAndroid Build Coastguard Workerdef addFilesToAPK (config, apkPath, baseDir, relFilePaths): 656*35238bceSAndroid Build Coastguard Worker aaptPath = which("aapt", [config.env.sdk.getBuildToolsPath()]) 657*35238bceSAndroid Build Coastguard Worker maxBatchSize = 25 658*35238bceSAndroid Build Coastguard Worker 659*35238bceSAndroid Build Coastguard Worker pushWorkingDir(baseDir) 660*35238bceSAndroid Build Coastguard Worker try: 661*35238bceSAndroid Build Coastguard Worker workQueue = list(relFilePaths) 662*35238bceSAndroid Build Coastguard Worker # Workaround for Windows. 663*35238bceSAndroid Build Coastguard Worker if os.path.sep == "\\": 664*35238bceSAndroid Build Coastguard Worker workQueue = [i.replace("\\", "/") for i in workQueue] 665*35238bceSAndroid Build Coastguard Worker 666*35238bceSAndroid Build Coastguard Worker while len(workQueue) > 0: 667*35238bceSAndroid Build Coastguard Worker batchSize = min(len(workQueue), maxBatchSize) 668*35238bceSAndroid Build Coastguard Worker items = workQueue[0:batchSize] 669*35238bceSAndroid Build Coastguard Worker 670*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 671*35238bceSAndroid Build Coastguard Worker aaptPath, 672*35238bceSAndroid Build Coastguard Worker "add", 673*35238bceSAndroid Build Coastguard Worker "-f", apkPath, 674*35238bceSAndroid Build Coastguard Worker ] + items) 675*35238bceSAndroid Build Coastguard Worker 676*35238bceSAndroid Build Coastguard Worker del workQueue[0:batchSize] 677*35238bceSAndroid Build Coastguard Worker finally: 678*35238bceSAndroid Build Coastguard Worker popWorkingDir() 679*35238bceSAndroid Build Coastguard Worker 680*35238bceSAndroid Build Coastguard Workerdef addFileToAPK (config, apkPath, baseDir, relFilePath): 681*35238bceSAndroid Build Coastguard Worker addFilesToAPK(config, apkPath, baseDir, [relFilePath]) 682*35238bceSAndroid Build Coastguard Worker 683*35238bceSAndroid Build Coastguard Workerclass AddJavaToAPK (BuildStep): 684*35238bceSAndroid Build Coastguard Worker def __init__ (self, package): 685*35238bceSAndroid Build Coastguard Worker self.package = package 686*35238bceSAndroid Build Coastguard Worker self.srcPath = BuildBaseAPK(self.package).getOutputs()[0] 687*35238bceSAndroid Build Coastguard Worker self.dstPath = [BuildRoot(), self.package.getAppDirName(), "tmp", "with-java.apk"] 688*35238bceSAndroid Build Coastguard Worker 689*35238bceSAndroid Build Coastguard Worker def getInputs (self): 690*35238bceSAndroid Build Coastguard Worker return [ 691*35238bceSAndroid Build Coastguard Worker self.srcPath, 692*35238bceSAndroid Build Coastguard Worker self.package.getClassesDexPath(), 693*35238bceSAndroid Build Coastguard Worker ] 694*35238bceSAndroid Build Coastguard Worker 695*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 696*35238bceSAndroid Build Coastguard Worker return [self.dstPath] 697*35238bceSAndroid Build Coastguard Worker 698*35238bceSAndroid Build Coastguard Worker def update (self, config): 699*35238bceSAndroid Build Coastguard Worker srcPath = resolvePath(config, self.srcPath) 700*35238bceSAndroid Build Coastguard Worker dstPath = resolvePath(config, self.getOutputs()[0]) 701*35238bceSAndroid Build Coastguard Worker dexPath = resolvePath(config, self.package.getClassesDexPath()) 702*35238bceSAndroid Build Coastguard Worker 703*35238bceSAndroid Build Coastguard Worker shutil.copyfile(srcPath, dstPath) 704*35238bceSAndroid Build Coastguard Worker addFileToAPK(config, dstPath, os.path.dirname(dexPath), os.path.basename(dexPath)) 705*35238bceSAndroid Build Coastguard Worker 706*35238bceSAndroid Build Coastguard Workerclass AddAssetsToAPK (BuildStep): 707*35238bceSAndroid Build Coastguard Worker def __init__ (self, package, abi): 708*35238bceSAndroid Build Coastguard Worker self.package = package 709*35238bceSAndroid Build Coastguard Worker self.buildPath = [NativeBuildPath(abi)] 710*35238bceSAndroid Build Coastguard Worker self.srcPath = AddJavaToAPK(self.package).getOutputs()[0] 711*35238bceSAndroid Build Coastguard Worker self.dstPath = [BuildRoot(), self.package.getAppDirName(), "tmp", "with-assets.apk"] 712*35238bceSAndroid Build Coastguard Worker 713*35238bceSAndroid Build Coastguard Worker def getInputs (self): 714*35238bceSAndroid Build Coastguard Worker return [ 715*35238bceSAndroid Build Coastguard Worker self.srcPath, 716*35238bceSAndroid Build Coastguard Worker self.buildPath + ["assets"] 717*35238bceSAndroid Build Coastguard Worker ] 718*35238bceSAndroid Build Coastguard Worker 719*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 720*35238bceSAndroid Build Coastguard Worker return [self.dstPath] 721*35238bceSAndroid Build Coastguard Worker 722*35238bceSAndroid Build Coastguard Worker @staticmethod 723*35238bceSAndroid Build Coastguard Worker def getAssetFiles (buildPath): 724*35238bceSAndroid Build Coastguard Worker allFiles = BuildStep.expandPathsToFiles([os.path.join(buildPath, "assets")]) 725*35238bceSAndroid Build Coastguard Worker return [os.path.relpath(p, buildPath) for p in allFiles] 726*35238bceSAndroid Build Coastguard Worker 727*35238bceSAndroid Build Coastguard Worker def update (self, config): 728*35238bceSAndroid Build Coastguard Worker srcPath = resolvePath(config, self.srcPath) 729*35238bceSAndroid Build Coastguard Worker dstPath = resolvePath(config, self.getOutputs()[0]) 730*35238bceSAndroid Build Coastguard Worker buildPath = resolvePath(config, self.buildPath) 731*35238bceSAndroid Build Coastguard Worker assetFiles = AddAssetsToAPK.getAssetFiles(buildPath) 732*35238bceSAndroid Build Coastguard Worker 733*35238bceSAndroid Build Coastguard Worker shutil.copyfile(srcPath, dstPath) 734*35238bceSAndroid Build Coastguard Worker 735*35238bceSAndroid Build Coastguard Worker addFilesToAPK(config, dstPath, buildPath, assetFiles) 736*35238bceSAndroid Build Coastguard Worker 737*35238bceSAndroid Build Coastguard Workerclass AddNativeLibsToAPK (BuildStep): 738*35238bceSAndroid Build Coastguard Worker def __init__ (self, package, abis): 739*35238bceSAndroid Build Coastguard Worker self.package = package 740*35238bceSAndroid Build Coastguard Worker self.abis = abis 741*35238bceSAndroid Build Coastguard Worker self.srcPath = AddAssetsToAPK(self.package, "").getOutputs()[0] 742*35238bceSAndroid Build Coastguard Worker self.dstPath = [BuildRoot(), self.package.getAppDirName(), "tmp", "with-native-libs.apk"] 743*35238bceSAndroid Build Coastguard Worker 744*35238bceSAndroid Build Coastguard Worker def getInputs (self): 745*35238bceSAndroid Build Coastguard Worker paths = [self.srcPath] 746*35238bceSAndroid Build Coastguard Worker for abi in self.abis: 747*35238bceSAndroid Build Coastguard Worker paths.append([NativeBuildPath(abi), "libdeqp.so"]) 748*35238bceSAndroid Build Coastguard Worker return paths 749*35238bceSAndroid Build Coastguard Worker 750*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 751*35238bceSAndroid Build Coastguard Worker return [self.dstPath] 752*35238bceSAndroid Build Coastguard Worker 753*35238bceSAndroid Build Coastguard Worker def update (self, config): 754*35238bceSAndroid Build Coastguard Worker srcPath = resolvePath(config, self.srcPath) 755*35238bceSAndroid Build Coastguard Worker dstPath = resolvePath(config, self.getOutputs()[0]) 756*35238bceSAndroid Build Coastguard Worker pkgPath = resolvePath(config, [BuildRoot(), self.package.getAppDirName()]) 757*35238bceSAndroid Build Coastguard Worker libFiles = [] 758*35238bceSAndroid Build Coastguard Worker 759*35238bceSAndroid Build Coastguard Worker # Create right directory structure first 760*35238bceSAndroid Build Coastguard Worker for abi in self.abis: 761*35238bceSAndroid Build Coastguard Worker libSrcPath = resolvePath(config, [NativeBuildPath(abi), "libdeqp.so"]) 762*35238bceSAndroid Build Coastguard Worker libRelPath = os.path.join("lib", abi, "libdeqp.so") 763*35238bceSAndroid Build Coastguard Worker libAbsPath = os.path.join(pkgPath, libRelPath) 764*35238bceSAndroid Build Coastguard Worker 765*35238bceSAndroid Build Coastguard Worker if not os.path.exists(os.path.dirname(libAbsPath)): 766*35238bceSAndroid Build Coastguard Worker os.makedirs(os.path.dirname(libAbsPath)) 767*35238bceSAndroid Build Coastguard Worker 768*35238bceSAndroid Build Coastguard Worker shutil.copyfile(libSrcPath, libAbsPath) 769*35238bceSAndroid Build Coastguard Worker libFiles.append(libRelPath) 770*35238bceSAndroid Build Coastguard Worker 771*35238bceSAndroid Build Coastguard Worker if config.layers: 772*35238bceSAndroid Build Coastguard Worker # Need to copy everything in the layer folder 773*35238bceSAndroid Build Coastguard Worker layersGlob = os.path.join(config.layers, abi, "*") 774*35238bceSAndroid Build Coastguard Worker libVkLayers = glob.glob(layersGlob) 775*35238bceSAndroid Build Coastguard Worker for layer in libVkLayers: 776*35238bceSAndroid Build Coastguard Worker layerFilename = os.path.basename(layer) 777*35238bceSAndroid Build Coastguard Worker layerRelPath = os.path.join("lib", abi, layerFilename) 778*35238bceSAndroid Build Coastguard Worker layerAbsPath = os.path.join(pkgPath, layerRelPath) 779*35238bceSAndroid Build Coastguard Worker shutil.copyfile(layer, layerAbsPath) 780*35238bceSAndroid Build Coastguard Worker libFiles.append(layerRelPath) 781*35238bceSAndroid Build Coastguard Worker print("Adding layer binary: %s" % (layer,)) 782*35238bceSAndroid Build Coastguard Worker 783*35238bceSAndroid Build Coastguard Worker if config.angle: 784*35238bceSAndroid Build Coastguard Worker angleGlob = os.path.join(config.angle, abi, "lib*_angle.so") 785*35238bceSAndroid Build Coastguard Worker libAngle = glob.glob(angleGlob) 786*35238bceSAndroid Build Coastguard Worker for lib in libAngle: 787*35238bceSAndroid Build Coastguard Worker libFilename = os.path.basename(lib) 788*35238bceSAndroid Build Coastguard Worker libRelPath = os.path.join("lib", abi, libFilename) 789*35238bceSAndroid Build Coastguard Worker libAbsPath = os.path.join(pkgPath, libRelPath) 790*35238bceSAndroid Build Coastguard Worker shutil.copyfile(lib, libAbsPath) 791*35238bceSAndroid Build Coastguard Worker libFiles.append(libRelPath) 792*35238bceSAndroid Build Coastguard Worker print("Adding ANGLE binary: %s" % (lib,)) 793*35238bceSAndroid Build Coastguard Worker 794*35238bceSAndroid Build Coastguard Worker shutil.copyfile(srcPath, dstPath) 795*35238bceSAndroid Build Coastguard Worker addFilesToAPK(config, dstPath, pkgPath, libFiles) 796*35238bceSAndroid Build Coastguard Worker 797*35238bceSAndroid Build Coastguard Workerclass SignAPK (BuildStep): 798*35238bceSAndroid Build Coastguard Worker def __init__ (self, package): 799*35238bceSAndroid Build Coastguard Worker self.package = package 800*35238bceSAndroid Build Coastguard Worker self.srcPath = AlignAPK(self.package).getOutputs()[0] 801*35238bceSAndroid Build Coastguard Worker self.dstPath = [BuildRoot(), getBuildRootRelativeAPKPath(self.package)] 802*35238bceSAndroid Build Coastguard Worker self.keystorePath = CreateKeystore().getOutputs()[0] 803*35238bceSAndroid Build Coastguard Worker 804*35238bceSAndroid Build Coastguard Worker def getInputs (self): 805*35238bceSAndroid Build Coastguard Worker return [self.srcPath, self.keystorePath] 806*35238bceSAndroid Build Coastguard Worker 807*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 808*35238bceSAndroid Build Coastguard Worker return [self.dstPath] 809*35238bceSAndroid Build Coastguard Worker 810*35238bceSAndroid Build Coastguard Worker def update (self, config): 811*35238bceSAndroid Build Coastguard Worker apksigner = which("apksigner", [config.env.sdk.getBuildToolsPath()]) 812*35238bceSAndroid Build Coastguard Worker srcPath = resolvePath(config, self.srcPath) 813*35238bceSAndroid Build Coastguard Worker dstPath = resolvePath(config, self.dstPath) 814*35238bceSAndroid Build Coastguard Worker 815*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 816*35238bceSAndroid Build Coastguard Worker apksigner, 817*35238bceSAndroid Build Coastguard Worker "sign", 818*35238bceSAndroid Build Coastguard Worker "--ks", resolvePath(config, self.keystorePath), 819*35238bceSAndroid Build Coastguard Worker "--ks-key-alias", "androiddebugkey", 820*35238bceSAndroid Build Coastguard Worker "--ks-pass", "pass:android", 821*35238bceSAndroid Build Coastguard Worker "--key-pass", "pass:android", 822*35238bceSAndroid Build Coastguard Worker "--min-sdk-version", str(config.minApi), 823*35238bceSAndroid Build Coastguard Worker "--max-sdk-version", str(config.javaApi), 824*35238bceSAndroid Build Coastguard Worker "--out", dstPath, 825*35238bceSAndroid Build Coastguard Worker srcPath 826*35238bceSAndroid Build Coastguard Worker ]) 827*35238bceSAndroid Build Coastguard Worker 828*35238bceSAndroid Build Coastguard Workerdef getBuildRootRelativeAPKPath (package): 829*35238bceSAndroid Build Coastguard Worker return os.path.join(package.getAppDirName(), package.getAppName() + ".apk") 830*35238bceSAndroid Build Coastguard Worker 831*35238bceSAndroid Build Coastguard Workerclass AlignAPK (BuildStep): 832*35238bceSAndroid Build Coastguard Worker def __init__ (self, package): 833*35238bceSAndroid Build Coastguard Worker self.package = package 834*35238bceSAndroid Build Coastguard Worker self.srcPath = AddNativeLibsToAPK(self.package, []).getOutputs()[0] 835*35238bceSAndroid Build Coastguard Worker self.dstPath = [BuildRoot(), self.package.getAppDirName(), "tmp", "aligned.apk"] 836*35238bceSAndroid Build Coastguard Worker self.keystorePath = CreateKeystore().getOutputs()[0] 837*35238bceSAndroid Build Coastguard Worker 838*35238bceSAndroid Build Coastguard Worker def getInputs (self): 839*35238bceSAndroid Build Coastguard Worker return [self.srcPath] 840*35238bceSAndroid Build Coastguard Worker 841*35238bceSAndroid Build Coastguard Worker def getOutputs (self): 842*35238bceSAndroid Build Coastguard Worker return [self.dstPath] 843*35238bceSAndroid Build Coastguard Worker 844*35238bceSAndroid Build Coastguard Worker def update (self, config): 845*35238bceSAndroid Build Coastguard Worker srcPath = resolvePath(config, self.srcPath) 846*35238bceSAndroid Build Coastguard Worker dstPath = resolvePath(config, self.dstPath) 847*35238bceSAndroid Build Coastguard Worker zipalignPath = os.path.join(config.env.sdk.getBuildToolsPath(), "zipalign") 848*35238bceSAndroid Build Coastguard Worker 849*35238bceSAndroid Build Coastguard Worker executeAndLog(config, [ 850*35238bceSAndroid Build Coastguard Worker zipalignPath, 851*35238bceSAndroid Build Coastguard Worker "-f", "4", 852*35238bceSAndroid Build Coastguard Worker srcPath, 853*35238bceSAndroid Build Coastguard Worker dstPath 854*35238bceSAndroid Build Coastguard Worker ]) 855*35238bceSAndroid Build Coastguard Worker 856*35238bceSAndroid Build Coastguard Workerdef getBuildStepsForPackage (abis, package, libraries = []): 857*35238bceSAndroid Build Coastguard Worker steps = [] 858*35238bceSAndroid Build Coastguard Worker 859*35238bceSAndroid Build Coastguard Worker assert len(abis) > 0 860*35238bceSAndroid Build Coastguard Worker 861*35238bceSAndroid Build Coastguard Worker # Build native code first 862*35238bceSAndroid Build Coastguard Worker for abi in abis: 863*35238bceSAndroid Build Coastguard Worker steps += [BuildNativeLibrary(abi)] 864*35238bceSAndroid Build Coastguard Worker 865*35238bceSAndroid Build Coastguard Worker # Build library packages 866*35238bceSAndroid Build Coastguard Worker for library in libraries: 867*35238bceSAndroid Build Coastguard Worker if library.hasResources: 868*35238bceSAndroid Build Coastguard Worker steps.append(GenResourcesSrc(library)) 869*35238bceSAndroid Build Coastguard Worker steps.append(BuildJavaSource(library)) 870*35238bceSAndroid Build Coastguard Worker 871*35238bceSAndroid Build Coastguard Worker # Build main package .java sources 872*35238bceSAndroid Build Coastguard Worker if package.hasResources: 873*35238bceSAndroid Build Coastguard Worker steps.append(GenResourcesSrc(package)) 874*35238bceSAndroid Build Coastguard Worker steps.append(BuildJavaSource(package, libraries)) 875*35238bceSAndroid Build Coastguard Worker steps.append(BuildDex(package, libraries)) 876*35238bceSAndroid Build Coastguard Worker 877*35238bceSAndroid Build Coastguard Worker # Build base APK 878*35238bceSAndroid Build Coastguard Worker steps.append(BuildBaseAPK(package, libraries)) 879*35238bceSAndroid Build Coastguard Worker steps.append(AddJavaToAPK(package)) 880*35238bceSAndroid Build Coastguard Worker 881*35238bceSAndroid Build Coastguard Worker # Add assets from first ABI 882*35238bceSAndroid Build Coastguard Worker steps.append(AddAssetsToAPK(package, abis[0])) 883*35238bceSAndroid Build Coastguard Worker 884*35238bceSAndroid Build Coastguard Worker # Add native libs to APK 885*35238bceSAndroid Build Coastguard Worker steps.append(AddNativeLibsToAPK(package, abis)) 886*35238bceSAndroid Build Coastguard Worker 887*35238bceSAndroid Build Coastguard Worker # Finalize APK 888*35238bceSAndroid Build Coastguard Worker steps.append(CreateKeystore()) 889*35238bceSAndroid Build Coastguard Worker steps.append(AlignAPK(package)) 890*35238bceSAndroid Build Coastguard Worker steps.append(SignAPK(package)) 891*35238bceSAndroid Build Coastguard Worker 892*35238bceSAndroid Build Coastguard Worker return steps 893*35238bceSAndroid Build Coastguard Worker 894*35238bceSAndroid Build Coastguard Workerdef getPackageAndLibrariesForTarget (target): 895*35238bceSAndroid Build Coastguard Worker deqpPackage = PackageDescription("package", "dEQP") 896*35238bceSAndroid Build Coastguard Worker ctsPackage = PackageDescription("openglcts", "Khronos-CTS", hasResources = False) 897*35238bceSAndroid Build Coastguard Worker 898*35238bceSAndroid Build Coastguard Worker if target == 'deqp': 899*35238bceSAndroid Build Coastguard Worker return (deqpPackage, []) 900*35238bceSAndroid Build Coastguard Worker elif target == 'openglcts': 901*35238bceSAndroid Build Coastguard Worker return (ctsPackage, [deqpPackage]) 902*35238bceSAndroid Build Coastguard Worker else: 903*35238bceSAndroid Build Coastguard Worker raise Exception("Uknown target '%s'" % target) 904*35238bceSAndroid Build Coastguard Worker 905*35238bceSAndroid Build Coastguard Workerdef findNDK (): 906*35238bceSAndroid Build Coastguard Worker ndkBuildPath = which('ndk-build') 907*35238bceSAndroid Build Coastguard Worker if ndkBuildPath != None: 908*35238bceSAndroid Build Coastguard Worker return os.path.dirname(ndkBuildPath) 909*35238bceSAndroid Build Coastguard Worker else: 910*35238bceSAndroid Build Coastguard Worker return None 911*35238bceSAndroid Build Coastguard Worker 912*35238bceSAndroid Build Coastguard Workerdef findSDK (): 913*35238bceSAndroid Build Coastguard Worker sdkBuildPath = which('android') 914*35238bceSAndroid Build Coastguard Worker if sdkBuildPath != None: 915*35238bceSAndroid Build Coastguard Worker return os.path.dirname(os.path.dirname(sdkBuildPath)) 916*35238bceSAndroid Build Coastguard Worker else: 917*35238bceSAndroid Build Coastguard Worker return None 918*35238bceSAndroid Build Coastguard Worker 919*35238bceSAndroid Build Coastguard Workerdef getDefaultBuildRoot (): 920*35238bceSAndroid Build Coastguard Worker return os.path.join(tempfile.gettempdir(), "deqp-android-build") 921*35238bceSAndroid Build Coastguard Worker 922*35238bceSAndroid Build Coastguard Workerdef parseArgs (): 923*35238bceSAndroid Build Coastguard Worker nativeBuildTypes = ['Release', 'Debug', 'MinSizeRel', 'RelWithAsserts', 'RelWithDebInfo'] 924*35238bceSAndroid Build Coastguard Worker defaultNDKPath = findNDK() 925*35238bceSAndroid Build Coastguard Worker defaultSDKPath = findSDK() 926*35238bceSAndroid Build Coastguard Worker defaultBuildRoot = getDefaultBuildRoot() 927*35238bceSAndroid Build Coastguard Worker 928*35238bceSAndroid Build Coastguard Worker parser = argparse.ArgumentParser(os.path.basename(__file__), 929*35238bceSAndroid Build Coastguard Worker formatter_class=argparse.ArgumentDefaultsHelpFormatter) 930*35238bceSAndroid Build Coastguard Worker parser.add_argument('--native-build-type', 931*35238bceSAndroid Build Coastguard Worker dest='nativeBuildType', 932*35238bceSAndroid Build Coastguard Worker default="RelWithAsserts", 933*35238bceSAndroid Build Coastguard Worker choices=nativeBuildTypes, 934*35238bceSAndroid Build Coastguard Worker help="Native code build type") 935*35238bceSAndroid Build Coastguard Worker parser.add_argument('--build-root', 936*35238bceSAndroid Build Coastguard Worker dest='buildRoot', 937*35238bceSAndroid Build Coastguard Worker default=defaultBuildRoot, 938*35238bceSAndroid Build Coastguard Worker help="Root build directory") 939*35238bceSAndroid Build Coastguard Worker parser.add_argument('--abis', 940*35238bceSAndroid Build Coastguard Worker dest='abis', 941*35238bceSAndroid Build Coastguard Worker default=",".join(NDKEnv.getKnownAbis()), 942*35238bceSAndroid Build Coastguard Worker help="ABIs to build") 943*35238bceSAndroid Build Coastguard Worker parser.add_argument('--native-api', 944*35238bceSAndroid Build Coastguard Worker type=int, 945*35238bceSAndroid Build Coastguard Worker dest='nativeApi', 946*35238bceSAndroid Build Coastguard Worker default=28, 947*35238bceSAndroid Build Coastguard Worker help="Android API level to target in native code") 948*35238bceSAndroid Build Coastguard Worker parser.add_argument('--java-api', 949*35238bceSAndroid Build Coastguard Worker type=int, 950*35238bceSAndroid Build Coastguard Worker dest='javaApi', 951*35238bceSAndroid Build Coastguard Worker default=28, 952*35238bceSAndroid Build Coastguard Worker help="Android API level to target in Java code") 953*35238bceSAndroid Build Coastguard Worker parser.add_argument('--tool-api', 954*35238bceSAndroid Build Coastguard Worker type=int, 955*35238bceSAndroid Build Coastguard Worker dest='toolApi', 956*35238bceSAndroid Build Coastguard Worker default=-1, 957*35238bceSAndroid Build Coastguard Worker help="Android Tools level to target (-1 being maximum present)") 958*35238bceSAndroid Build Coastguard Worker parser.add_argument('--min-api', 959*35238bceSAndroid Build Coastguard Worker type=int, 960*35238bceSAndroid Build Coastguard Worker dest='minApi', 961*35238bceSAndroid Build Coastguard Worker default=22, 962*35238bceSAndroid Build Coastguard Worker help="Minimum Android API level for which the APK can be installed") 963*35238bceSAndroid Build Coastguard Worker parser.add_argument('--sdk', 964*35238bceSAndroid Build Coastguard Worker dest='sdkPath', 965*35238bceSAndroid Build Coastguard Worker default=defaultSDKPath, 966*35238bceSAndroid Build Coastguard Worker help="Android SDK path", 967*35238bceSAndroid Build Coastguard Worker required=(True if defaultSDKPath == None else False)) 968*35238bceSAndroid Build Coastguard Worker parser.add_argument('--ndk', 969*35238bceSAndroid Build Coastguard Worker dest='ndkPath', 970*35238bceSAndroid Build Coastguard Worker default=defaultNDKPath, 971*35238bceSAndroid Build Coastguard Worker help="Android NDK path", 972*35238bceSAndroid Build Coastguard Worker required=(True if defaultNDKPath == None else False)) 973*35238bceSAndroid Build Coastguard Worker parser.add_argument('-v', '--verbose', 974*35238bceSAndroid Build Coastguard Worker dest='verbose', 975*35238bceSAndroid Build Coastguard Worker help="Verbose output", 976*35238bceSAndroid Build Coastguard Worker default=False, 977*35238bceSAndroid Build Coastguard Worker action='store_true') 978*35238bceSAndroid Build Coastguard Worker parser.add_argument('--target', 979*35238bceSAndroid Build Coastguard Worker dest='target', 980*35238bceSAndroid Build Coastguard Worker help='Build target', 981*35238bceSAndroid Build Coastguard Worker choices=['deqp', 'openglcts'], 982*35238bceSAndroid Build Coastguard Worker default='deqp') 983*35238bceSAndroid Build Coastguard Worker parser.add_argument('--kc-cts-target', 984*35238bceSAndroid Build Coastguard Worker dest='gtfTarget', 985*35238bceSAndroid Build Coastguard Worker default='gles32', 986*35238bceSAndroid Build Coastguard Worker choices=['gles32', 'gles31', 'gles3', 'gles2', 'gl'], 987*35238bceSAndroid Build Coastguard Worker help="KC-CTS (GTF) target API (only used in openglcts target)") 988*35238bceSAndroid Build Coastguard Worker parser.add_argument('--layers-path', 989*35238bceSAndroid Build Coastguard Worker dest='layers', 990*35238bceSAndroid Build Coastguard Worker default=None, 991*35238bceSAndroid Build Coastguard Worker required=False) 992*35238bceSAndroid Build Coastguard Worker parser.add_argument('--angle-path', 993*35238bceSAndroid Build Coastguard Worker dest='angle', 994*35238bceSAndroid Build Coastguard Worker default=None, 995*35238bceSAndroid Build Coastguard Worker required=False) 996*35238bceSAndroid Build Coastguard Worker 997*35238bceSAndroid Build Coastguard Worker args = parser.parse_args() 998*35238bceSAndroid Build Coastguard Worker 999*35238bceSAndroid Build Coastguard Worker def parseAbis (abisStr): 1000*35238bceSAndroid Build Coastguard Worker knownAbis = set(NDKEnv.getKnownAbis()) 1001*35238bceSAndroid Build Coastguard Worker abis = [] 1002*35238bceSAndroid Build Coastguard Worker 1003*35238bceSAndroid Build Coastguard Worker for abi in abisStr.split(','): 1004*35238bceSAndroid Build Coastguard Worker abi = abi.strip() 1005*35238bceSAndroid Build Coastguard Worker if not abi in knownAbis: 1006*35238bceSAndroid Build Coastguard Worker raise Exception("Unknown ABI: %s" % abi) 1007*35238bceSAndroid Build Coastguard Worker abis.append(abi) 1008*35238bceSAndroid Build Coastguard Worker 1009*35238bceSAndroid Build Coastguard Worker return abis 1010*35238bceSAndroid Build Coastguard Worker 1011*35238bceSAndroid Build Coastguard Worker # Custom parsing & checks 1012*35238bceSAndroid Build Coastguard Worker try: 1013*35238bceSAndroid Build Coastguard Worker args.abis = parseAbis(args.abis) 1014*35238bceSAndroid Build Coastguard Worker if len(args.abis) == 0: 1015*35238bceSAndroid Build Coastguard Worker raise Exception("--abis can't be empty") 1016*35238bceSAndroid Build Coastguard Worker except Exception as e: 1017*35238bceSAndroid Build Coastguard Worker print("ERROR: %s" % str(e)) 1018*35238bceSAndroid Build Coastguard Worker parser.print_help() 1019*35238bceSAndroid Build Coastguard Worker sys.exit(-1) 1020*35238bceSAndroid Build Coastguard Worker 1021*35238bceSAndroid Build Coastguard Worker return args 1022*35238bceSAndroid Build Coastguard Worker 1023*35238bceSAndroid Build Coastguard Workerif __name__ == "__main__": 1024*35238bceSAndroid Build Coastguard Worker args = parseArgs() 1025*35238bceSAndroid Build Coastguard Worker 1026*35238bceSAndroid Build Coastguard Worker ndk = NDKEnv(os.path.realpath(args.ndkPath)) 1027*35238bceSAndroid Build Coastguard Worker sdk = SDKEnv(os.path.realpath(args.sdkPath), args.toolApi) 1028*35238bceSAndroid Build Coastguard Worker buildPath = os.path.realpath(args.buildRoot) 1029*35238bceSAndroid Build Coastguard Worker env = Environment(sdk, ndk) 1030*35238bceSAndroid Build Coastguard Worker config = Configuration(env, buildPath, abis=args.abis, nativeApi=args.nativeApi, javaApi=args.javaApi, minApi=args.minApi, nativeBuildType=args.nativeBuildType, gtfTarget=args.gtfTarget, 1031*35238bceSAndroid Build Coastguard Worker verbose=args.verbose, layers=args.layers, angle=args.angle) 1032*35238bceSAndroid Build Coastguard Worker 1033*35238bceSAndroid Build Coastguard Worker try: 1034*35238bceSAndroid Build Coastguard Worker config.check() 1035*35238bceSAndroid Build Coastguard Worker except Exception as e: 1036*35238bceSAndroid Build Coastguard Worker print("ERROR: %s" % str(e)) 1037*35238bceSAndroid Build Coastguard Worker print("") 1038*35238bceSAndroid Build Coastguard Worker print("Please check your configuration:") 1039*35238bceSAndroid Build Coastguard Worker print(" --sdk=%s" % args.sdkPath) 1040*35238bceSAndroid Build Coastguard Worker print(" --ndk=%s" % args.ndkPath) 1041*35238bceSAndroid Build Coastguard Worker sys.exit(-1) 1042*35238bceSAndroid Build Coastguard Worker 1043*35238bceSAndroid Build Coastguard Worker pkg, libs = getPackageAndLibrariesForTarget(args.target) 1044*35238bceSAndroid Build Coastguard Worker steps = getBuildStepsForPackage(config.abis, pkg, libs) 1045*35238bceSAndroid Build Coastguard Worker 1046*35238bceSAndroid Build Coastguard Worker executeSteps(config, steps) 1047*35238bceSAndroid Build Coastguard Worker 1048*35238bceSAndroid Build Coastguard Worker print("") 1049*35238bceSAndroid Build Coastguard Worker print("Built %s" % os.path.join(buildPath, getBuildRootRelativeAPKPath(pkg))) 1050