Removed android_old target and began update to sdk install
This commit is contained in:
parent
74e26fe6f2
commit
4936d31828
3 changed files with 267 additions and 420 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
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')
|
||||
skip_upd = self.buildozer.config.getdefault(
|
||||
'app', 'android.skip_update', False)
|
||||
|
||||
if WSL:
|
||||
self.android_cmd = old_android_cmd
|
||||
sh.rm('-rf', join(self.android_sdk_dir, 'tools.save'))
|
||||
else:
|
||||
self.buildozer.info('Skipping Android SDK update due to spec file setting')
|
||||
if not skip_upd:
|
||||
# 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,81 +599,190 @@ 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')
|
||||
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()])))
|
||||
|
||||
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
|
||||
'''
|
||||
|
|
|
@ -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)
|
Loading…
Reference in a new issue