blob: 3abcc70ed134bcd09466aa0e735dc945c1dda48d [file] [log] [blame]
#!src/build/run_python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Build APK from C/C++ and java sources with Android SDK and NDK."""
import argparse
import os
import shutil
import subprocess
import sys
from src.build import build_common
from src.build import toolchain
from src.build.util import file_util
_ARC_ROOT = build_common.get_arc_root()
_NDK_PATH = os.path.join(_ARC_ROOT, 'third_party', 'ndk')
_SDK_PATH = build_common.get_android_sdk_path()
_TOOLS_ROOT = os.path.join(_ARC_ROOT, 'third_party', 'tools')
def _build_apk(source_path, use_ndk, use_clang, build_path,
install_apk, debug, verbose):
if not os.path.isdir(_SDK_PATH):
raise Exception('Missing SDK path: ' + str(_SDK_PATH))
print
print '--------------------------'
print 'Building ' + os.path.basename(install_apk)
print '--------------------------'
# We use this work directory in order to allow us to completely
# create it from scratch every time we build. We cannot do that
# to the build_path since files in there (like the build.log)
# should not be deleted on every run.
work_path = os.path.join(build_path, 'work')
if os.path.isdir(work_path):
file_util.rmtree(work_path)
shutil.copytree(os.path.join('.', source_path), work_path)
print os.path.join(_SDK_PATH, 'tools', 'android')
# Any target 14+ should work (tested on 21).
subprocess.check_call([
os.path.join(_SDK_PATH, 'tools', 'android'),
'update', 'project',
'--target', 'android-%d' % toolchain.get_android_api_level(),
'--path', '.', '--name', 'test_app'], cwd=work_path)
if use_ndk:
if not os.path.isdir(_NDK_PATH):
raise Exception('Missing NDK path: ' + str(_NDK_PATH))
app_optim = 'release'
if debug:
app_optim = 'debug'
if not os.path.exists(os.path.join(work_path, 'jni', 'Application.mk')):
# Write desired ABI before calling ndk-build. Do not drop 'x86' since
# -t=bi uses x86 NDK binaries by default.
open(os.path.join(work_path, 'jni', 'Application.mk'), 'w').write(
'APP_ABI := x86 armeabi armeabi-v7a\n' +
('APP_OPTIM := %s\n' % app_optim) +
'APP_STL := stlport_static\n')
extras = []
if verbose:
extras.append('V=1')
if use_clang:
extras.append('NDK_TOOLCHAIN_VERSION=clang')
subprocess.check_call([os.path.join(_NDK_PATH, 'ndk-build'),
'-j', '16', '-l', '16',
'ARC_ROOT=' + _ARC_ROOT] + extras,
cwd=work_path)
subprocess.check_call([os.path.join(_TOOLS_ROOT, 'ant', 'bin', 'ant'),
'debug'], cwd=work_path)
shutil.copyfile(os.path.join(work_path, 'bin', 'test_app-debug.apk'),
install_apk)
def main():
# JAVA_HOME may be set by Android envsetup.sh script. If so, remove it
# from the environment and use the default.
if 'JAVA_HOME' in os.environ:
del os.environ['JAVA_HOME']
parser = argparse.ArgumentParser()
parser.add_argument('--apk', metavar='<output>', required='True')
parser.add_argument('--build_path', metavar='<path>', required='True')
parser.add_argument('--debug', action='store_true')
parser.add_argument('--ndk', metavar='<path>')
parser.add_argument('--sdk', metavar='<path>')
parser.add_argument('--source_path', metavar='<path>', required='True')
parser.add_argument('--use_ndk', action='store_true')
parser.add_argument('--use_clang', action='store_true')
parser.add_argument('--verbose', '-v', action='store_true')
args = parser.parse_args()
global _SDK_PATH
if args.sdk:
_SDK_PATH = os.path.abspath(args.sdk)
global _NDK_PATH
if args.ndk:
_NDK_PATH = os.path.abspath(args.ndk)
build_path = os.path.abspath(args.build_path)
install_apk = os.path.abspath(args.apk)
source_path = os.path.abspath(args.source_path)
try:
_build_apk(source_path, args.use_ndk, args.use_clang, build_path,
install_apk, args.debug, args.verbose)
except Exception, e:
print str(e)
return 1
return 0
if __name__ == '__main__':
sys.exit(main())