# -*- coding: utf-8 -*-
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-------------------------------------------------------------------------
+
import os
import re
import sys
import shutil
+import string
import argparse
+import time
import common
def getAssetsDir (buildRoot, nativeLib, buildType):
return os.path.join(getNativeBuildDir(buildRoot, nativeLib, buildType), "assets")
-def getPrebuiltsDirName (abiName):
- PREBUILT_DIRS = {
- 'x86': 'android-x86',
- 'armeabi-v7a': 'android-arm',
- 'arm64-v8a': 'android-arm64'
- }
-
- if not abiName in PREBUILT_DIRS:
- raise Exception("Unknown ABI %s, don't know where prebuilts are" % abiName)
-
- return PREBUILT_DIRS[abiName]
-
def buildNative (buildRoot, libTargetDir, nativeLib, buildType):
deqpDir = os.path.normpath(os.path.join(common.ANDROID_DIR, ".."))
buildDir = getNativeBuildDir(buildRoot, nativeLib, buildType)
# Make build directory if necessary
if not os.path.exists(buildDir):
os.makedirs(buildDir)
- os.chdir(buildDir)
toolchainFile = '%s/framework/delibs/cmake/toolchain-android-%s.cmake' % (deqpDir, common.ANDROID_NDK_TOOLCHAIN_VERSION)
- common.execArgs([
+ common.execArgsInDirectory([
'cmake',
'-G%s' % common.CMAKE_GENERATOR,
'-DCMAKE_TOOLCHAIN_FILE=%s' % toolchainFile,
'-DCMAKE_BUILD_TYPE=%s' % buildType,
'-DDEQP_TARGET=android',
deqpDir
- ])
+ ], buildDir)
- os.chdir(buildDir)
- common.execArgs(['cmake', '--build', '.'] + common.EXTRA_BUILD_ARGS)
+ common.execArgsInDirectory(['cmake', '--build', '.'] + common.EXTRA_BUILD_ARGS, buildDir)
if not os.path.exists(libsDir):
os.makedirs(libsDir)
if buildType.lower() == "debug":
srcGdbserverPath = os.path.join(common.ANDROID_NDK_PATH,
'prebuilt',
- getPrebuiltsDirName(nativeLib.abiVersion),
+ nativeLib.prebuiltDir,
'gdbserver',
'gdbserver')
dstGdbserverPath = os.path.join(libsDir, 'gdbserver')
else:
assert not os.path.exists(os.path.join(libsDir, "gdbserver"))
-def buildApp (buildRoot, isRelease):
+def buildApp (buildRoot, androidBuildType, javaApi):
appDir = os.path.join(buildRoot, "package")
# Set up app
'update', 'project',
'--name', 'dEQP',
'--path', '.',
- '--target', str(common.ANDROID_JAVA_API),
+ '--target', javaApi,
])
# Build
common.execArgs([
common.ANT_BIN,
- "release" if isRelease else "debug",
+ androidBuildType,
"-Dsource.dir=" + os.path.join(common.ANDROID_DIR, "package", "src"),
"-Dresource.absolute.dir=" + os.path.join(common.ANDROID_DIR, "package", "res")
])
'bin/dEQP-release.apk'
])
-def build (buildRoot=common.ANDROID_DIR, isRelease=False, nativeBuildType="Release"):
+def build (buildRoot=common.ANDROID_DIR, androidBuildType='debug', nativeBuildType="Release", javaApi=common.ANDROID_JAVA_API, doParallelBuild=False):
curDir = os.getcwd()
try:
shutil.rmtree(libTargetDir)
# Build native code
- for lib in common.NATIVE_LIBS:
- buildNative(buildRoot, libTargetDir, lib, nativeBuildType)
+ nativeBuildArgs = [(buildRoot, libTargetDir, nativeLib, nativeBuildType) for nativeLib in common.NATIVE_LIBS]
+ if doParallelBuild:
+ common.parallelApply(buildNative, nativeBuildArgs)
+ else:
+ common.serialApply(buildNative, nativeBuildArgs)
# Copy assets
if os.path.exists(assetsSrcDir):
shutil.copytree(assetsSrcDir, assetsDstDir)
# Build java code and .apk
- buildApp(buildRoot, isRelease)
+ buildApp(buildRoot, androidBuildType, javaApi)
finally:
# Restore working dir
os.chdir(curDir)
+def dumpConfig ():
+ print " "
+ for entry in common.CONFIG_STRINGS:
+ print "%-30s : %s" % (entry[0], entry[1])
+ print " "
+
+# Return NDK version as [<major>,<minor>] or None if cannot be figured out.
+def getNdkVersion (path):
+ if path == None:
+ return None
+
+ propFilePath = os.path.join(path, "source.properties")
+ try:
+ with open(propFilePath) as propFile:
+ for line in propFile:
+ keyValue = map(lambda x: string.strip(x), line.split("="))
+ if keyValue[0] == "Pkg.Revision":
+ versionParts = keyValue[1].split(".")
+ return tuple(map(int, versionParts[0:2]))
+ except:
+ print("Could not read source prop file '%s'" % propFilePath)
+
+ return None
+
+def checkConfig ():
+ HOST_OS_TO_DOWNLOAD_STRING = {
+ "linux-x86_64" : "linux-x86_64",
+ "windows" : "windows-x86",
+ "windows-x86_64" : "windows-x86_64"
+ }
+
+ version = getNdkVersion(common.ANDROID_NDK_PATH)
+ # Note: NDK currently maintains compatibility between minor
+ # versions. Error out only on major version mismatch.
+ if version == None or version[0] != common.ANDROID_NDK_VERSION[0]:
+ print("**** WARNING! Deqp requires NDK version %s" % common.ANDROID_NDK_VERSION_STRING)
+ print("**** NDK Path %s does not appear to have that version." % common.ANDROID_NDK_PATH)
+
+ # Download hint will use the version encored in common.py, not
+ # the latest minor version available
+ versionString = common.ANDROID_NDK_VERSION_STRING
+ if common.ANDROID_NDK_HOST_OS in HOST_OS_TO_DOWNLOAD_STRING:
+ osString = HOST_OS_TO_DOWNLOAD_STRING[common.ANDROID_NDK_HOST_OS]
+ print("**** Please install from https://dl.google.com/android/repository/android-ndk-%s-%s.zip" % (versionString, osString))
+ else:
+ print("**** Please download version", versionString, "from https://developer.android.com/ndk/downloads/index.html")
+
+ return False
+
+ return True
+
if __name__ == "__main__":
+ nativeBuildTypes = ['Release', 'Debug', 'MinSizeRel', 'RelWithAsserts', 'RelWithDebInfo']
+ androidBuildTypes = ['debug', 'release']
+
parser = argparse.ArgumentParser()
- parser.add_argument('--is-release', dest='isRelease', type=bool, default=False, help="Build android project in release mode.")
- parser.add_argument('--native-build-type', dest='nativeBuildType', default="Release", help="Build type passed cmake when building native code.")
+ parser.add_argument('--android-build-type', dest='androidBuildType', choices=androidBuildTypes, default='debug', help="Build type for android project..")
+ parser.add_argument('--native-build-type', dest='nativeBuildType', default="RelWithAsserts", choices=nativeBuildTypes, help="Build type passed to cmake when building native code.")
parser.add_argument('--build-root', dest='buildRoot', default=common.ANDROID_DIR, help="Root directory for storing build results.")
+ parser.add_argument('--dump-config', dest='dumpConfig', action='store_true', help="Print out all configurations variables")
+ parser.add_argument('--java-api', dest='javaApi', default=common.ANDROID_JAVA_API, help="Set the API signature for the java build.")
+ parser.add_argument('-p', '--parallel-build', dest='parallelBuild', action="store_true", help="Build native libraries in parallel.")
+ parser.add_argument('--skip-config-check', dest='skipConfigCheck', action="store_true", default=False, help="Skips config check. Warranty void.")
args = parser.parse_args()
- build(buildRoot=os.path.abspath(args.buildRoot), isRelease=args.isRelease, nativeBuildType=args.nativeBuildType)
+ if args.dumpConfig:
+ dumpConfig()
+
+ if not args.skipConfigCheck and not checkConfig():
+ print "Config check failed, exit"
+ exit(-1)
+
+ build(buildRoot=os.path.abspath(args.buildRoot), androidBuildType=args.androidBuildType, nativeBuildType=args.nativeBuildType, javaApi=args.javaApi, doParallelBuild=args.parallelBuild)