blob: cf61577adc1d288f8243e2afdf80c99aa37d414e [file] [log] [blame]
# Copyright 2013 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.
"""The android specific platform implementation module."""
import os
import subprocess
import cr
# This is the set of environment variables that are not automatically
# copied back from the envsetup shell
_IGNORE_ENV = [
'SHLVL', # Because it's nothing to do with envsetup
'GYP_GENERATOR_FLAGS', # because we set them in they gyp handler
'GYP_GENERATORS', # because we set them in they gyp handler
'PATH', # Because it gets a special merge handler
'GYP_DEFINES', # Because it gets a special merge handler
]
# The message to print when we detect use of an android output directory in a
# client that cannot build android.
_NOT_ANDROID_MESSAGE = """
You are trying to build for the android platform in a client that is not
android capable.
Please get a new client using "fetch android".
See https://code.google.com/p/chromium/wiki/AndroidBuildInstructions for more
details.
"""
class AndroidPlatform(cr.Platform):
"""The implementation of Platform for the android target."""
ACTIVE = cr.Config.From(
CR_ENVSETUP=os.path.join('{CR_SRC}', 'build', 'android', 'envsetup.sh'),
CR_ADB=os.path.join('{ANDROID_SDK_ROOT}', 'platform-tools', 'adb'),
CR_TARGET_SUFFIX='_apk',
CR_BINARY=os.path.join('{CR_BUILD_DIR}', 'apks', '{CR_TARGET_NAME}.apk'),
CR_ACTION='android.intent.action.VIEW',
CR_PACKAGE='com.google.android.apps.{CR_TARGET}',
CR_PROCESS='{CR_PACKAGE}',
CR_ACTIVITY='.Main',
CR_INTENT='{CR_PACKAGE}/{CR_ACTIVITY}',
CR_TEST_RUNNER=os.path.join(
'{CR_SRC}', 'build', 'android', 'test_runner.py'),
CR_ADB_GDB=os.path.join('{CR_SRC}', 'build', 'android', 'adb_gdb'),
CHROMIUM_OUT_DIR='{CR_OUT_BASE}',
CR_DEFAULT_TARGET='chromium_testshell',
)
def __init__(self):
super(AndroidPlatform, self).__init__()
self._env = cr.Config('android-env', literal=True, export=True)
self.detected_config.AddChild(self._env)
self._env_ready = False
self._env_paths = []
@property
def priority(self):
return super(AndroidPlatform, self).priority + 1
def Prepare(self, context):
"""Override Prepare from cr.Platform."""
super(AndroidPlatform, self).Prepare(context)
# Check we are an android capable client
is_android = 'android' in context.gclient.get('target_os', '')
if not is_android:
url = context.gclient.get('solutions', [{}])[0].get('url')
is_android = (url.startswith(
'https://chrome-internal.googlesource.com/') and
url.endswith('/internal/apps.git'))
if not is_android:
print _NOT_ANDROID_MESSAGE
exit(1)
try:
# capture the result of env setup if we have not already done so
if not self._env_ready:
# See what the env would be without env setup
before = context.exported
# Run env setup and capture/parse it's output
envsetup = 'source {CR_ENVSETUP} --target-arch={CR_ENVSETUP_ARCH}'
output = cr.Host.CaptureShell(context, envsetup + ' > /dev/null && env')
env_setup = cr.Config('envsetup', literal=True, export=True)
for line in output.split('\n'):
(key, op, value) = line.partition('=')
if op:
key = key.strip()
if key not in _IGNORE_ENV:
env_setup[key] = env_setup.ParseValue(value.strip())
if key == 'PATH':
self._env_paths = value.strip().split(os.path.pathsep)
if key == 'GYP_DEFINES':
# Make a version of GYP_DEFINES that is the combination of base
# setting and envsetup, needs to override the overrides
# Note: Forcing it into the top level scope - sledge-hammer
context[key] = value.strip() + ' ' + before.get(key, '')
items = env_setup.exported.items()
if not items:
# Because of the way envsetup is run, the exit code does not make it
# back to us. Instead, we assume if we got no environment at all, it
# must have failed.
print 'Envsetup failed!'
exit(1)
# Find all the things that envsetup changed
for key, value in env_setup.exported.items():
if str(value) != str(before.get(key, None)):
self._env[key] = value
self._env_ready = True
except subprocess.CalledProcessError, e:
exit(e.returncode)
@property
def paths(self):
return self._env_paths