Removed android_old target and began update to sdk install

This commit is contained in:
Alexander Taylor 2019-02-01 13:04:06 +00:00
parent 74e26fe6f2
commit 4936d31828
3 changed files with 267 additions and 420 deletions

View file

@ -155,7 +155,6 @@ class Buildozer(object):
def set_target(self, target):
'''Set the target to use (one of buildozer.targets, such as "android")
'''
target = self.translate_target(target)
self.targetname = target
m = __import__('buildozer.targets.{0}'.format(target),
fromlist=['buildozer'])
@ -919,23 +918,6 @@ class Buildozer(object):
# command line invocation
#
def translate_target(self, target, inverse=False):
# FIXME at some point, refactor to remove completely android old toolchain
if inverse:
if target == "android":
target = "android_old"
elif target == "android_new":
target = "android"
else:
if target == "android":
target = "android_new"
elif target == "android_new":
self.error("ERROR: The target android_new is now android")
exit(1)
elif target == "android_old":
target = "android"
return target
def targets(self):
for fn in listdir(join(dirname(__file__), 'targets')):
if fn.startswith('.') or fn.startswith('__'):
@ -946,7 +928,7 @@ class Buildozer(object):
try:
m = __import__('buildozer.targets.{0}'.format(target),
fromlist=['buildozer'])
yield self.translate_target(target, inverse=True), m
yield target, m
except NotImplementedError:
pass
except:
@ -1054,7 +1036,7 @@ class Buildozer(object):
# maybe it's a target?
targets = [x[0] for x in self.targets()]
if self.translate_target(command, inverse=True) not in targets:
if command not in targets:
print('Unknown command/target {}'.format(self.translate_target(command, inverse=True)))
exit(1)

View file

@ -28,8 +28,7 @@ import ast
import sh
from pipes import quote
from sys import platform, executable
from buildozer import BuildozerException
from buildozer import IS_PY3
from buildozer import BuildozerException, USE_COLOR, IS_PY3
from buildozer.target import Target
from os import environ
from os.path import exists, join, realpath, expanduser, basename, relpath
@ -42,10 +41,55 @@ from distutils.version import LooseVersion
class TargetAndroid(Target):
targetname = 'android_old'
targetname = 'android'
p4a_directory = "python-for-android"
p4a_branch = 'old_toolchain'
p4a_apk_cmd = "python build.py"
p4a_branch = 'master'
p4a_apk_cmd = "apk --debug --bootstrap="
extra_p4a_args = ''
def __init__(self, *args, **kwargs):
super(TargetAndroid, self).__init__(*args, **kwargs)
self._build_dir = join(self.buildozer.platform_dir, 'build')
executable = sys.executable or 'python'
self._p4a_cmd = '{} -m pythonforandroid.toolchain '.format(executable)
self._p4a_bootstrap = self.buildozer.config.getdefault(
'app', 'p4a.bootstrap', 'sdl2')
self.p4a_apk_cmd += self._p4a_bootstrap
color = 'always' if USE_COLOR else 'never'
self.extra_p4a_args = ' --color={} --storage-dir="{}"'.format(
color, self._build_dir)
# minapi should match ndk-api, so can use the same default if
# nothing is specified
ndk_api = self.buildozer.config.getdefault(
'app', 'android.ndk_api', self.android_minapi)
self.extra_p4a_args += ' --ndk-api={}'.format(ndk_api)
hook = self.buildozer.config.getdefault("app", "p4a.hook", None)
if hook is not None:
self.extra_p4a_args += ' --hook={}'.format(realpath(hook))
port = self.buildozer.config.getdefault('app', 'p4a.port', None)
if port is not None:
self.extra_p4a_args += ' --port={}'.format(port)
def _p4a(self, cmd, **kwargs):
if not hasattr(self, "pa_dir"):
self.pa_dir = join(self.buildozer.platform_dir, self.p4a_directory)
kwargs.setdefault('cwd', self.pa_dir)
return self.buildozer.cmd(self._p4a_cmd + cmd + self.extra_p4a_args, **kwargs)
def _sdkmanager(self, *args):
"""Call the sdkmanager in our Android SDK with the given arguments."""
sdkmanager_path = os.path.join(self.buildozer.global_platform_dir,
'android-sdk',
'tools',
'bin',
'sdkmanager')
assert os.path.isfile(sdkmanager_path)
return self.buildozer.cmd(sdkmanager_path + ' ' + ' '.join(args),
get_stdout=True)
@property
def android_sdk_version(self):
@ -73,10 +117,8 @@ class TargetAndroid(Target):
'app', 'android.sdk_path', ''))
if directory:
return realpath(directory)
version = self.buildozer.config.getdefault('app', 'android.sdk',
self.android_sdk_version)
return join(self.buildozer.global_platform_dir,
'android-sdk-{0}'.format(version))
'android-sdk')
@property
def android_ndk_dir(self):
@ -248,30 +290,31 @@ class TargetAndroid(Target):
self.buildozer.info('Android SDK is missing, downloading')
if platform in ('win32', 'cygwin'):
archive = 'android-sdk_r{0}-windows.zip'
archive = 'sdk-tools-windows-4333796.zip'
unpacked = 'android-sdk-windows'
elif platform in ('darwin', ):
archive = 'android-sdk_r{0}-macosx.zip'
archive = 'sdk-tools-darwin-4333796.zip'
unpacked = 'android-sdk-macosx'
elif platform.startswith('linux'):
archive = 'android-sdk_r{0}-linux.tgz'
archive = 'sdk-tools-linux-4333796.zip'
unpacked = 'android-sdk-linux'
else:
raise SystemError('Unsupported platform: {0}'.format(platform))
if not os.path.exists(sdk_dir):
os.makedirs(sdk_dir)
archive = archive.format(self.android_sdk_version)
url = 'http://dl.google.com/android/'
url = 'http://dl.google.com/android/repository/'
self.buildozer.download(url,
archive,
cwd=self.buildozer.global_platform_dir)
cwd=sdk_dir)
self.buildozer.info('Unpacking Android SDK')
self.buildozer.file_extract(archive,
cwd=self.buildozer.global_platform_dir)
self.buildozer.file_rename(unpacked,
sdk_dir,
cwd=self.buildozer.global_platform_dir)
self.buildozer.info('Android SDK installation done.')
cwd=sdk_dir)
self.buildozer.info('Android SDK tools base installation done.')
return sdk_dir
@ -341,21 +384,24 @@ class TargetAndroid(Target):
self.buildozer.info('Android NDK installation done.')
return ndk_dir
def _android_list_sdk(self, include_all=False):
cmd = '{} list sdk -u -e'.format(self.android_cmd)
if include_all:
cmd += ' -a'
available_packages = self.buildozer.cmd(
cmd,
cwd=self.buildozer.global_platform_dir,
get_stdout=True)[0]
def _android_list_build_tools_versions(self):
available_packages = self._sdkmanager('--list')
# get only the line like -> id: 5 or "build-tools-19.0.1"
# and extract the name part.
print(available_packages)
return [x.split('"')[1]
for x in available_packages.splitlines()
if x.startswith('id: ')]
lines = available_packages[0].split('\n')
build_tools_versions = []
for line in lines:
if not line.strip().startswith('build-tools;'):
continue
package_name = line.strip().split(' ')[0]
assert package_name.count(';') == 1, (
'could not parse package "{}"'.format(package_name))
version = package_name.split(';')[1]
build_tools_versions.append(parse(version))
return build_tools_versions
def _android_update_sdk(self, packages):
from pexpect import EOF
@ -376,9 +422,6 @@ class TargetAndroid(Target):
break
child.sendline('y')
def _build_package_string(self, package_name, version):
return '{}-{}'.format(package_name, version)
def _read_version_subdir(self, *args):
versions = []
if not os.path.exists(join(*args)):
@ -420,68 +463,38 @@ class TargetAndroid(Target):
if self.buildozer.state.get(cache_key, None) == cache_value:
return True
# 3 pass installation.
if not os.access(self.android_cmd, os.X_OK):
self.buildozer.cmd('chmod ug+x {}'.format(self.android_cmd))
# 1. update the tool and platform-tools if needed
packages = self._android_list_sdk()
skip_upd = self.buildozer.config.getdefault('app',
'android.skip_update', False)
if 'tools' in packages or 'platform-tools' in packages:
skip_upd = self.buildozer.config.getdefault(
'app', 'android.skip_update', False)
if not skip_upd:
if WSL:
# WSL (Windows Subsystem for Linux) allows running
# linux from windows 10, but some windows
# limitations still apply, namely you can't rename a
# directory that a program was started from, which
# is what the tools updates cause, and we end up
# with an empty dir, so we need to run from a
# different place, and the updater is still looking
# for things in tools, and specifically renames the
# tool dir, hence, moving and making a symlink
# works.
sh.mv(
join(self.android_sdk_dir, 'tools'),
join(self.android_sdk_dir, 'tools.save')
)
sh.ln(
'-s',
join(self.android_sdk_dir, 'tools.save'),
join(self.android_sdk_dir, 'tools')
)
old_android_cmd = self.android_cmd
self.android_cmd = join(
self.android_sdk_dir,
'tools.save',
self.android_cmd.split('/')[-1]
)
self._android_update_sdk('tools,platform-tools')
if WSL:
self.android_cmd = old_android_cmd
sh.rm('-rf', join(self.android_sdk_dir, 'tools.save'))
# just calling sdkmanager with the items will install them if necessary
self._sdkmanager('tools', 'platform-tools')
self._sdkmanager('--update')
else:
self.buildozer.info('Skipping Android SDK update due to spec file setting')
self.buildozer.info('Note: this also prevents installing missing '
'SDK components')
# 2. install the latest build tool
v_build_tools = self._read_version_subdir(self.android_sdk_dir,
installed_v_build_tools = self._read_version_subdir(self.android_sdk_dir,
'build-tools')
packages = self._android_list_sdk(include_all=True)
ver = self._find_latest_package(packages, 'build-tools-')
if ver and ver > v_build_tools and not skip_upd:
self._android_update_sdk(self._build_package_string('build-tools', ver))
available_v_build_tools = self._android_list_build_tools_versions()
if not available_v_build_tools:
self.buildozer.warning('Did not find any build tools available to download')
latest_v_build_tools = sorted(available_v_build_tools)[-1]
if latest_v_build_tools > installed_v_build_tools and not skip_upd:
self._sdkmanager('"build-tools;{}"'.format(latest_v_build_tools))
# 2. check aidl can be run
self._check_aidl(v_build_tools)
# 3. finally, install the android for the current api
android_platform = join(self.android_sdk_dir, 'platforms', 'android-{0}'.format(self.android_api))
if not self.buildozer.file_exists(android_platform):
packages = self._android_list_sdk()
android_package = 'android-{}'.format(self.android_api)
if android_package in packages and not skip_upd:
self._android_update_sdk(android_package)
if not self.buildozer.file_exists(android_platform) and not skip_upd:
self._sdkmanager('"platforms;android-{}"'.format(self.android_api))
self.buildozer.info('Android packages installation done.')
@ -586,44 +599,18 @@ class TargetAndroid(Target):
options = "--user"
if "VIRTUAL_ENV" in os.environ or "CONDA_PREFIX" in os.environ:
options = ""
print('pa dir', self.pa_dir)
print('pip_deps', pip_deps)
cmd('{} -m pip install -q {} {}'.format(executable, options, " ".join(pip_deps)))
def get_available_packages(self):
available_modules = self.buildozer.cmd('./distribute.sh -l',
cwd=self.pa_dir,
get_stdout=True)[0]
if not available_modules.startswith('Available modules:'):
self.buildozer.error('Python-for-android invalid output for -l')
return available_modules[19:].splitlines()[0].split()
def compile_platform(self):
# for android, the compilation depends really on the app requirements.
# compile the distribution only if the requirements changed.
last_requirements = self.buildozer.state.get('android.requirements',
'')
app_requirements = self.buildozer.config.getlist('app', 'requirements',
'')
# we need to extract the requirements that python-for-android knows
# about
available_modules = self.get_available_packages()
onlyname = lambda x: x.split('==')[0]
android_requirements = [x
for x in app_requirements
if onlyname(x) in available_modules]
need_compile = 0
if last_requirements != android_requirements:
need_compile = 1
app_requirements = self.buildozer.config.getlist(
'app', 'requirements', '')
dist_name = self.buildozer.config.get('app', 'package.name')
dist_dir = join(self.pa_dir, 'dist', dist_name)
dist_file = join(dist_dir, 'private', 'include', 'python2.7',
'pyconfig.h')
if not exists(dist_file):
need_compile = 1
local_recipes = self.get_local_recipes_dir()
requirements = ','.join(app_requirements)
options = []
# len('requirements.source.') == 20, so use name[20:]
source_dirs = {
'P4A_{}_DIR'.format(name[20:]): realpath(expanduser(value))
for name, value in self.buildozer.config.items('app')
@ -635,32 +622,167 @@ class TargetAndroid(Target):
'\n '.join(['{} = {}'.format(k, v)
for k, v in source_dirs.items()])))
last_source_requirements = self.buildozer.state.get(
'android.requirements.source', {})
if source_dirs != last_source_requirements:
need_compile = 1
if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True):
options.append("--copy-libs")
# support for recipes in a local directory within the project
if local_recipes:
options.append('--local-recipes')
options.append(local_recipes)
config = self.buildozer.config
self._p4a(
("create --dist_name={} --bootstrap={} --requirements={} "
"--arch {} {}").format(
dist_name, self._p4a_bootstrap, requirements,
config.getdefault('app', 'android.arch', "armeabi-v7a"), " ".join(options)),
get_stdout=True)[0]
if not need_compile:
self.buildozer.info('Distribution already compiled, pass.')
return
def get_available_packages(self):
return True
modules_str = ' '.join(android_requirements)
cmd = self.buildozer.cmd
self.buildozer.debug('Clean and build python-for-android')
self.buildozer.rmdir(dist_dir) # Delete existing distribution to stop
# p4a complaining
cmd('./distribute.sh -m "{0}" -d "{1}"'.format(modules_str, dist_name),
cwd=self.pa_dir)
self.buildozer.debug('Remove temporary build files')
self.buildozer.rmdir(join(self.pa_dir, 'build'))
self.buildozer.rmdir(join(self.pa_dir, '.packages'))
self.buildozer.rmdir(join(self.pa_dir, 'src', 'jni', 'obj', 'local'))
self.buildozer.info('Distribution compiled.')
def get_dist_dir(self, dist_name):
return join(self._build_dir, 'dists', dist_name)
# ensure we will not compile again
self.buildozer.state['android.requirements'] = android_requirements
self.buildozer.state['android.requirements.source'] = source_dirs
self.buildozer.state.sync()
def get_local_recipes_dir(self):
local_recipes = self.buildozer.config.getdefault('app', 'p4a.local_recipes')
return realpath(expanduser(local_recipes)) if local_recipes else None
def execute_build_package(self, build_cmd):
# wrapper from previous old_toolchain to new toolchain
dist_name = self.buildozer.config.get('app', 'package.name')
local_recipes = self.get_local_recipes_dir()
cmd = [self.p4a_apk_cmd, "--dist_name", dist_name]
for args in build_cmd:
option, values = args[0], args[1:]
if option == "debug":
continue
elif option == "release":
cmd.append("--release")
if self.check_p4a_sign_env(True):
cmd.append("--sign")
continue
if option == "--window":
cmd.append("--window")
elif option == "--sdk":
cmd.append("--android_api")
cmd.extend(values)
else:
cmd.extend(args)
# support for presplash background color
presplash_color = self.buildozer.config.getdefault('app', 'android.presplash_color', None)
if presplash_color:
cmd.append('--presplash-color')
cmd.append("'{}'".format(presplash_color))
# support for services
services = self.buildozer.config.getlist('app', 'services', [])
for service in services:
cmd.append("--service")
cmd.append(service)
# support for copy-libs
if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True):
cmd.append("--copy-libs")
# support for recipes in a local directory within the project
if local_recipes:
cmd.append('--local-recipes')
cmd.append(local_recipes)
# support for blacklist/whitelist filename
whitelist_src = self.buildozer.config.getdefault('app', 'android.whitelist_src', None)
blacklist_src = self.buildozer.config.getdefault('app', 'android.blacklist_src', None)
if whitelist_src:
cmd.append('--whitelist')
cmd.append(realpath(whitelist_src))
if blacklist_src:
cmd.append('--blacklist')
cmd.append(realpath(blacklist_src))
# support for aars
aars = self.buildozer.config.getlist('app', 'android.add_aars', [])
for aar in aars:
cmd.append('--add-aar')
cmd.append(realpath(aar))
# support for gradle dependencies
gradle_dependencies = self.buildozer.config.getlist('app', 'android.gradle_dependencies', [])
for gradle_dependency in gradle_dependencies:
cmd.append('--depend')
cmd.append(gradle_dependency)
cmd.append('--arch')
cmd.append(self.buildozer.config.getdefault('app', 'android.arch', "armeabi-v7a"))
cmd = " ".join(cmd)
self._p4a(cmd)
def get_release_mode(self):
if self.check_p4a_sign_env():
return "release"
return "release-unsigned"
def check_p4a_sign_env(self, error=False):
keys = ["KEYALIAS", "KEYSTORE_PASSWD", "KEYSTORE", "KEYALIAS_PASSWD"]
check = True
for key in keys:
key = "P4A_RELEASE_{}".format(key)
if key not in os.environ:
if error:
self.buildozer.error(
("Asking for release but {} is missing"
"--sign will not be passed").format(key))
check = False
return check
def cmd_run(self, *args):
entrypoint = self.buildozer.config.getdefault(
'app', 'android.entrypoint')
if not entrypoint:
self.buildozer.config.set('app', 'android.entrypoint', 'org.kivy.android.PythonActivity')
super(TargetAndroid, self).cmd_run(*args)
entrypoint = self.buildozer.config.getdefault(
'app', 'android.entrypoint', 'org.renpy.android.PythonActivity')
package = self._get_package()
# push on the device
for serial in self.serials:
self.buildozer.environ['ANDROID_SERIAL'] = serial
self.buildozer.info('Run on {}'.format(serial))
self.buildozer.cmd(
'{adb} shell am start -n {package}/{entry} -a {entry}'.format(
adb=self.adb_cmd,
package=package,
entry=entrypoint),
cwd=self.buildozer.global_platform_dir)
self.buildozer.environ.pop('ANDROID_SERIAL', None)
self.buildozer.info('Application started.')
def cmd_p4a(self, *args):
'''
Run p4a commands. Args must come after --, or
use --alias to make an alias
'''
self.check_requirements()
self.install_platform()
args = args[0]
if args and args[0] == '--alias':
print('To set up p4a in this shell session, execute:')
print(' alias p4a=$(buildozer {} p4a --alias 2>&1 >/dev/null)'
.format(self.targetname))
sys.stderr.write('PYTHONPATH={} {}\n'.format(self.pa_dir, self._p4a_cmd))
else:
self._p4a(' '.join(args) if args else '')
def cmd_clean(self, *args):
'''
Clean the build and distribution
'''
self._p4a("clean_builds")
self._p4a("clean_dists")
def _get_package(self):
config = self.buildozer.config
@ -678,22 +800,6 @@ class TargetAndroid(Target):
for wl in p4a_whitelist:
fd.write(wl + '\n')
def get_dist_dir(self, dist_name):
return join(self.pa_dir, 'dist', dist_name)
@property
def dist_dir(self):
dist_name = self.buildozer.config.get('app', 'package.name')
return self.get_dist_dir(dist_name)
def execute_build_package(self, build_cmd):
dist_name = self.buildozer.config.get('app', 'package.name')
cmd = [self.p4a_apk_cmd]
for args in build_cmd:
cmd.append(" ".join(args))
cmd = " ".join(cmd)
self.buildozer.cmd(cmd, cwd=self.get_dist_dir(dist_name))
def build_package(self):
dist_name = self.buildozer.config.get('app', 'package.name')
dist_dir = self.get_dist_dir(dist_name)
@ -892,9 +998,6 @@ class TargetAndroid(Target):
self.buildozer.state['android:latestapk'] = apk_dest
self.buildozer.state['android:latestmode'] = self.build_mode
def get_release_mode(self):
return "release-unsigned"
def _update_libraries_references(self, dist_dir):
# ensure the project.properties exist
project_fn = join(dist_dir, 'project.properties')
@ -1029,27 +1132,6 @@ class TargetAndroid(Target):
self.buildozer.info('Application pushed.')
def cmd_run(self, *args):
super(TargetAndroid, self).cmd_run(*args)
entrypoint = self.buildozer.config.getdefault(
'app', 'android.entrypoint', 'org.renpy.android.PythonActivity')
package = self._get_package()
# push on the device
for serial in self.serials:
self.buildozer.environ['ANDROID_SERIAL'] = serial
self.buildozer.info('Run on {}'.format(serial))
self.buildozer.cmd(
'{adb} shell am start -n {package}/{entry} -a {entry}'.format(
adb=self.adb_cmd,
package=package,
entry=entrypoint),
cwd=self.buildozer.global_platform_dir)
self.buildozer.environ.pop('ANDROID_SERIAL', None)
self.buildozer.info('Application started.')
def cmd_logcat(self, *args):
'''Show the log from the device
'''

View file

@ -1,217 +0,0 @@
# coding=utf-8
'''
Android target, based on python-for-android project
'''
import sys
import os
from buildozer import USE_COLOR
from buildozer.targets.android import TargetAndroid
from os.path import join, expanduser, realpath
class TargetAndroidNew(TargetAndroid):
targetname = 'android'
p4a_branch = "master"
p4a_directory = "python-for-android-new-toolchain"
p4a_apk_cmd = "apk --debug --bootstrap="
extra_p4a_args = ''
def __init__(self, *args, **kwargs):
super(TargetAndroidNew, self).__init__(*args, **kwargs)
self._build_dir = join(self.buildozer.platform_dir, 'build')
executable = sys.executable or 'python'
self._p4a_cmd = '{} -m pythonforandroid.toolchain '.format(executable)
self._p4a_bootstrap = self.buildozer.config.getdefault(
'app', 'p4a.bootstrap', 'sdl2')
self.p4a_apk_cmd += self._p4a_bootstrap
color = 'always' if USE_COLOR else 'never'
self.extra_p4a_args = ' --color={} --storage-dir="{}"'.format(
color, self._build_dir)
# minapi should match ndk-api, so can use the same default if
# nothing is specified
ndk_api = self.buildozer.config.getdefault(
'app', 'android.ndk_api', self.android_minapi)
self.extra_p4a_args += ' --ndk-api={}'.format(ndk_api)
hook = self.buildozer.config.getdefault("app", "p4a.hook", None)
if hook is not None:
self.extra_p4a_args += ' --hook={}'.format(realpath(hook))
port = self.buildozer.config.getdefault('app', 'p4a.port', None)
if port is not None:
self.extra_p4a_args += ' --port={}'.format(port)
def _p4a(self, cmd, **kwargs):
if not hasattr(self, "pa_dir"):
self.pa_dir = join(self.buildozer.platform_dir, self.p4a_directory)
kwargs.setdefault('cwd', self.pa_dir)
return self.buildozer.cmd(self._p4a_cmd + cmd + self.extra_p4a_args, **kwargs)
def get_available_packages(self):
return True
def compile_platform(self):
app_requirements = self.buildozer.config.getlist(
'app', 'requirements', '')
dist_name = self.buildozer.config.get('app', 'package.name')
local_recipes = self.get_local_recipes_dir()
requirements = ','.join(app_requirements)
options = []
source_dirs = {
'P4A_{}_DIR'.format(name[20:]): realpath(expanduser(value))
for name, value in self.buildozer.config.items('app')
if name.startswith('requirements.source.')
}
if source_dirs:
self.buildozer.environ.update(source_dirs)
self.buildozer.info('Using custom source dirs:\n {}'.format(
'\n '.join(['{} = {}'.format(k, v)
for k, v in source_dirs.items()])))
if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True):
options.append("--copy-libs")
# support for recipes in a local directory within the project
if local_recipes:
options.append('--local-recipes')
options.append(local_recipes)
config = self.buildozer.config
self._p4a(
("create --dist_name={} --bootstrap={} --requirements={} "
"--arch {} {}").format(
dist_name, self._p4a_bootstrap, requirements,
config.getdefault('app', 'android.arch', "armeabi-v7a"), " ".join(options)),
get_stdout=True)[0]
def get_dist_dir(self, dist_name):
return join(self._build_dir, 'dists', dist_name)
def get_local_recipes_dir(self):
local_recipes = self.buildozer.config.getdefault('app', 'p4a.local_recipes')
return realpath(expanduser(local_recipes)) if local_recipes else None
def execute_build_package(self, build_cmd):
# wrapper from previous old_toolchain to new toolchain
dist_name = self.buildozer.config.get('app', 'package.name')
local_recipes = self.get_local_recipes_dir()
cmd = [self.p4a_apk_cmd, "--dist_name", dist_name]
for args in build_cmd:
option, values = args[0], args[1:]
if option == "debug":
continue
elif option == "release":
cmd.append("--release")
if self.check_p4a_sign_env(True):
cmd.append("--sign")
continue
if option == "--window":
cmd.append("--window")
elif option == "--sdk":
cmd.append("--android_api")
cmd.extend(values)
else:
cmd.extend(args)
# support for presplash background color
presplash_color = self.buildozer.config.getdefault('app', 'android.presplash_color', None)
if presplash_color:
cmd.append('--presplash-color')
cmd.append("'{}'".format(presplash_color))
# support for services
services = self.buildozer.config.getlist('app', 'services', [])
for service in services:
cmd.append("--service")
cmd.append(service)
# support for copy-libs
if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True):
cmd.append("--copy-libs")
# support for recipes in a local directory within the project
if local_recipes:
cmd.append('--local-recipes')
cmd.append(local_recipes)
# support for blacklist/whitelist filename
whitelist_src = self.buildozer.config.getdefault('app', 'android.whitelist_src', None)
blacklist_src = self.buildozer.config.getdefault('app', 'android.blacklist_src', None)
if whitelist_src:
cmd.append('--whitelist')
cmd.append(realpath(whitelist_src))
if blacklist_src:
cmd.append('--blacklist')
cmd.append(realpath(blacklist_src))
# support for aars
aars = self.buildozer.config.getlist('app', 'android.add_aars', [])
for aar in aars:
cmd.append('--add-aar')
cmd.append(realpath(aar))
# support for gradle dependencies
gradle_dependencies = self.buildozer.config.getlist('app', 'android.gradle_dependencies', [])
for gradle_dependency in gradle_dependencies:
cmd.append('--depend')
cmd.append(gradle_dependency)
cmd.append('--arch')
cmd.append(self.buildozer.config.getdefault('app', 'android.arch', "armeabi-v7a"))
cmd = " ".join(cmd)
self._p4a(cmd)
def get_release_mode(self):
if self.check_p4a_sign_env():
return "release"
return "release-unsigned"
def check_p4a_sign_env(self, error=False):
keys = ["KEYALIAS", "KEYSTORE_PASSWD", "KEYSTORE", "KEYALIAS_PASSWD"]
check = True
for key in keys:
key = "P4A_RELEASE_{}".format(key)
if key not in os.environ:
if error:
self.buildozer.error(
("Asking for release but {} is missing"
"--sign will not be passed").format(key))
check = False
return check
def cmd_run(self, *args):
entrypoint = self.buildozer.config.getdefault(
'app', 'android.entrypoint')
if not entrypoint:
self.buildozer.config.set('app', 'android.entrypoint', 'org.kivy.android.PythonActivity')
return super(TargetAndroidNew, self).cmd_run(*args)
def cmd_p4a(self, *args):
'''
Run p4a commands. Args must come after --, or
use --alias to make an alias
'''
self.check_requirements()
self.install_platform()
args = args[0]
if args and args[0] == '--alias':
print('To set up p4a in this shell session, execute:')
print(' alias p4a=$(buildozer {} p4a --alias 2>&1 >/dev/null)'
.format(self.targetname))
sys.stderr.write('PYTHONPATH={} {}\n'.format(self.pa_dir, self._p4a_cmd))
else:
self._p4a(' '.join(args) if args else '')
def cmd_clean(self, *args):
'''
Clean the build and distribution
'''
self._p4a("clean_builds")
self._p4a("clean_dists")
def get_target(buildozer):
buildozer.targetname = "android"
return TargetAndroidNew(buildozer)