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):
|
def set_target(self, target):
|
||||||
'''Set the target to use (one of buildozer.targets, such as "android")
|
'''Set the target to use (one of buildozer.targets, such as "android")
|
||||||
'''
|
'''
|
||||||
target = self.translate_target(target)
|
|
||||||
self.targetname = target
|
self.targetname = target
|
||||||
m = __import__('buildozer.targets.{0}'.format(target),
|
m = __import__('buildozer.targets.{0}'.format(target),
|
||||||
fromlist=['buildozer'])
|
fromlist=['buildozer'])
|
||||||
|
@ -919,23 +918,6 @@ class Buildozer(object):
|
||||||
# command line invocation
|
# 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):
|
def targets(self):
|
||||||
for fn in listdir(join(dirname(__file__), 'targets')):
|
for fn in listdir(join(dirname(__file__), 'targets')):
|
||||||
if fn.startswith('.') or fn.startswith('__'):
|
if fn.startswith('.') or fn.startswith('__'):
|
||||||
|
@ -946,7 +928,7 @@ class Buildozer(object):
|
||||||
try:
|
try:
|
||||||
m = __import__('buildozer.targets.{0}'.format(target),
|
m = __import__('buildozer.targets.{0}'.format(target),
|
||||||
fromlist=['buildozer'])
|
fromlist=['buildozer'])
|
||||||
yield self.translate_target(target, inverse=True), m
|
yield target, m
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
@ -1054,7 +1036,7 @@ class Buildozer(object):
|
||||||
|
|
||||||
# maybe it's a target?
|
# maybe it's a target?
|
||||||
targets = [x[0] for x in self.targets()]
|
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)))
|
print('Unknown command/target {}'.format(self.translate_target(command, inverse=True)))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,7 @@ import ast
|
||||||
import sh
|
import sh
|
||||||
from pipes import quote
|
from pipes import quote
|
||||||
from sys import platform, executable
|
from sys import platform, executable
|
||||||
from buildozer import BuildozerException
|
from buildozer import BuildozerException, USE_COLOR, IS_PY3
|
||||||
from buildozer import IS_PY3
|
|
||||||
from buildozer.target import Target
|
from buildozer.target import Target
|
||||||
from os import environ
|
from os import environ
|
||||||
from os.path import exists, join, realpath, expanduser, basename, relpath
|
from os.path import exists, join, realpath, expanduser, basename, relpath
|
||||||
|
@ -42,10 +41,55 @@ from distutils.version import LooseVersion
|
||||||
|
|
||||||
|
|
||||||
class TargetAndroid(Target):
|
class TargetAndroid(Target):
|
||||||
targetname = 'android_old'
|
targetname = 'android'
|
||||||
p4a_directory = "python-for-android"
|
p4a_directory = "python-for-android"
|
||||||
p4a_branch = 'old_toolchain'
|
p4a_branch = 'master'
|
||||||
p4a_apk_cmd = "python build.py"
|
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
|
@property
|
||||||
def android_sdk_version(self):
|
def android_sdk_version(self):
|
||||||
|
@ -73,10 +117,8 @@ class TargetAndroid(Target):
|
||||||
'app', 'android.sdk_path', ''))
|
'app', 'android.sdk_path', ''))
|
||||||
if directory:
|
if directory:
|
||||||
return realpath(directory)
|
return realpath(directory)
|
||||||
version = self.buildozer.config.getdefault('app', 'android.sdk',
|
|
||||||
self.android_sdk_version)
|
|
||||||
return join(self.buildozer.global_platform_dir,
|
return join(self.buildozer.global_platform_dir,
|
||||||
'android-sdk-{0}'.format(version))
|
'android-sdk')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def android_ndk_dir(self):
|
def android_ndk_dir(self):
|
||||||
|
@ -248,30 +290,31 @@ class TargetAndroid(Target):
|
||||||
|
|
||||||
self.buildozer.info('Android SDK is missing, downloading')
|
self.buildozer.info('Android SDK is missing, downloading')
|
||||||
if platform in ('win32', 'cygwin'):
|
if platform in ('win32', 'cygwin'):
|
||||||
archive = 'android-sdk_r{0}-windows.zip'
|
archive = 'sdk-tools-windows-4333796.zip'
|
||||||
unpacked = 'android-sdk-windows'
|
unpacked = 'android-sdk-windows'
|
||||||
elif platform in ('darwin', ):
|
elif platform in ('darwin', ):
|
||||||
archive = 'android-sdk_r{0}-macosx.zip'
|
archive = 'sdk-tools-darwin-4333796.zip'
|
||||||
unpacked = 'android-sdk-macosx'
|
unpacked = 'android-sdk-macosx'
|
||||||
elif platform.startswith('linux'):
|
elif platform.startswith('linux'):
|
||||||
archive = 'android-sdk_r{0}-linux.tgz'
|
archive = 'sdk-tools-linux-4333796.zip'
|
||||||
unpacked = 'android-sdk-linux'
|
unpacked = 'android-sdk-linux'
|
||||||
else:
|
else:
|
||||||
raise SystemError('Unsupported platform: {0}'.format(platform))
|
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)
|
archive = archive.format(self.android_sdk_version)
|
||||||
url = 'http://dl.google.com/android/'
|
url = 'http://dl.google.com/android/repository/'
|
||||||
self.buildozer.download(url,
|
self.buildozer.download(url,
|
||||||
archive,
|
archive,
|
||||||
cwd=self.buildozer.global_platform_dir)
|
cwd=sdk_dir)
|
||||||
|
|
||||||
self.buildozer.info('Unpacking Android SDK')
|
self.buildozer.info('Unpacking Android SDK')
|
||||||
self.buildozer.file_extract(archive,
|
self.buildozer.file_extract(archive,
|
||||||
cwd=self.buildozer.global_platform_dir)
|
cwd=sdk_dir)
|
||||||
self.buildozer.file_rename(unpacked,
|
|
||||||
sdk_dir,
|
self.buildozer.info('Android SDK tools base installation done.')
|
||||||
cwd=self.buildozer.global_platform_dir)
|
|
||||||
self.buildozer.info('Android SDK installation done.')
|
|
||||||
|
|
||||||
return sdk_dir
|
return sdk_dir
|
||||||
|
|
||||||
|
@ -341,21 +384,24 @@ class TargetAndroid(Target):
|
||||||
self.buildozer.info('Android NDK installation done.')
|
self.buildozer.info('Android NDK installation done.')
|
||||||
return ndk_dir
|
return ndk_dir
|
||||||
|
|
||||||
def _android_list_sdk(self, include_all=False):
|
def _android_list_build_tools_versions(self):
|
||||||
cmd = '{} list sdk -u -e'.format(self.android_cmd)
|
available_packages = self._sdkmanager('--list')
|
||||||
if include_all:
|
|
||||||
cmd += ' -a'
|
|
||||||
available_packages = self.buildozer.cmd(
|
|
||||||
cmd,
|
|
||||||
cwd=self.buildozer.global_platform_dir,
|
|
||||||
get_stdout=True)[0]
|
|
||||||
|
|
||||||
# get only the line like -> id: 5 or "build-tools-19.0.1"
|
lines = available_packages[0].split('\n')
|
||||||
# and extract the name part.
|
|
||||||
print(available_packages)
|
build_tools_versions = []
|
||||||
return [x.split('"')[1]
|
|
||||||
for x in available_packages.splitlines()
|
for line in lines:
|
||||||
if x.startswith('id: ')]
|
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):
|
def _android_update_sdk(self, packages):
|
||||||
from pexpect import EOF
|
from pexpect import EOF
|
||||||
|
@ -376,9 +422,6 @@ class TargetAndroid(Target):
|
||||||
break
|
break
|
||||||
child.sendline('y')
|
child.sendline('y')
|
||||||
|
|
||||||
def _build_package_string(self, package_name, version):
|
|
||||||
return '{}-{}'.format(package_name, version)
|
|
||||||
|
|
||||||
def _read_version_subdir(self, *args):
|
def _read_version_subdir(self, *args):
|
||||||
versions = []
|
versions = []
|
||||||
if not os.path.exists(join(*args)):
|
if not os.path.exists(join(*args)):
|
||||||
|
@ -420,68 +463,38 @@ class TargetAndroid(Target):
|
||||||
if self.buildozer.state.get(cache_key, None) == cache_value:
|
if self.buildozer.state.get(cache_key, None) == cache_value:
|
||||||
return True
|
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
|
# 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:
|
if not skip_upd:
|
||||||
self.android_cmd = old_android_cmd
|
# just calling sdkmanager with the items will install them if necessary
|
||||||
sh.rm('-rf', join(self.android_sdk_dir, 'tools.save'))
|
self._sdkmanager('tools', 'platform-tools')
|
||||||
else:
|
self._sdkmanager('--update')
|
||||||
self.buildozer.info('Skipping Android SDK update due to spec file setting')
|
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
|
# 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')
|
'build-tools')
|
||||||
packages = self._android_list_sdk(include_all=True)
|
available_v_build_tools = self._android_list_build_tools_versions()
|
||||||
ver = self._find_latest_package(packages, 'build-tools-')
|
if not available_v_build_tools:
|
||||||
if ver and ver > v_build_tools and not skip_upd:
|
self.buildozer.warning('Did not find any build tools available to download')
|
||||||
self._android_update_sdk(self._build_package_string('build-tools', ver))
|
|
||||||
|
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
|
# 2. check aidl can be run
|
||||||
self._check_aidl(v_build_tools)
|
self._check_aidl(v_build_tools)
|
||||||
|
|
||||||
# 3. finally, install the android for the current api
|
# 3. finally, install the android for the current api
|
||||||
android_platform = join(self.android_sdk_dir, 'platforms', 'android-{0}'.format(self.android_api))
|
android_platform = join(self.android_sdk_dir, 'platforms', 'android-{0}'.format(self.android_api))
|
||||||
if not self.buildozer.file_exists(android_platform):
|
if not self.buildozer.file_exists(android_platform) and not skip_upd:
|
||||||
packages = self._android_list_sdk()
|
self._sdkmanager('"platforms;android-{}"'.format(self.android_api))
|
||||||
android_package = 'android-{}'.format(self.android_api)
|
|
||||||
if android_package in packages and not skip_upd:
|
|
||||||
self._android_update_sdk(android_package)
|
|
||||||
|
|
||||||
self.buildozer.info('Android packages installation done.')
|
self.buildozer.info('Android packages installation done.')
|
||||||
|
|
||||||
|
@ -586,81 +599,190 @@ class TargetAndroid(Target):
|
||||||
options = "--user"
|
options = "--user"
|
||||||
if "VIRTUAL_ENV" in os.environ or "CONDA_PREFIX" in os.environ:
|
if "VIRTUAL_ENV" in os.environ or "CONDA_PREFIX" in os.environ:
|
||||||
options = ""
|
options = ""
|
||||||
|
print('pa dir', self.pa_dir)
|
||||||
|
print('pip_deps', pip_deps)
|
||||||
cmd('{} -m pip install -q {} {}'.format(executable, options, " ".join(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):
|
def compile_platform(self):
|
||||||
# for android, the compilation depends really on the app requirements.
|
app_requirements = self.buildozer.config.getlist(
|
||||||
# compile the distribution only if the requirements changed.
|
'app', 'requirements', '')
|
||||||
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
|
|
||||||
|
|
||||||
dist_name = self.buildozer.config.get('app', 'package.name')
|
dist_name = self.buildozer.config.get('app', 'package.name')
|
||||||
dist_dir = join(self.pa_dir, 'dist', dist_name)
|
local_recipes = self.get_local_recipes_dir()
|
||||||
dist_file = join(dist_dir, 'private', 'include', 'python2.7',
|
requirements = ','.join(app_requirements)
|
||||||
'pyconfig.h')
|
options = []
|
||||||
if not exists(dist_file):
|
|
||||||
need_compile = 1
|
|
||||||
|
|
||||||
# len('requirements.source.') == 20, so use name[20:]
|
|
||||||
source_dirs = {
|
source_dirs = {
|
||||||
'P4A_{}_DIR'.format(name[20:]): realpath(expanduser(value))
|
'P4A_{}_DIR'.format(name[20:]): realpath(expanduser(value))
|
||||||
for name, value in self.buildozer.config.items('app')
|
for name, value in self.buildozer.config.items('app')
|
||||||
if name.startswith('requirements.source.')
|
if name.startswith('requirements.source.')
|
||||||
}
|
}
|
||||||
if source_dirs:
|
if source_dirs:
|
||||||
self.buildozer.environ.update(source_dirs)
|
self.buildozer.environ.update(source_dirs)
|
||||||
self.buildozer.info('Using custom source dirs:\n {}'.format(
|
self.buildozer.info('Using custom source dirs:\n {}'.format(
|
||||||
'\n '.join(['{} = {}'.format(k, v)
|
'\n '.join(['{} = {}'.format(k, v)
|
||||||
for k, v in source_dirs.items()])))
|
for k, v in source_dirs.items()])))
|
||||||
|
|
||||||
last_source_requirements = self.buildozer.state.get(
|
if self.buildozer.config.getbooldefault('app', 'android.copy_libs', True):
|
||||||
'android.requirements.source', {})
|
options.append("--copy-libs")
|
||||||
if source_dirs != last_source_requirements:
|
# support for recipes in a local directory within the project
|
||||||
need_compile = 1
|
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:
|
def get_available_packages(self):
|
||||||
self.buildozer.info('Distribution already compiled, pass.')
|
return True
|
||||||
return
|
|
||||||
|
|
||||||
modules_str = ' '.join(android_requirements)
|
def get_dist_dir(self, dist_name):
|
||||||
cmd = self.buildozer.cmd
|
return join(self._build_dir, 'dists', dist_name)
|
||||||
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.')
|
|
||||||
|
|
||||||
# ensure we will not compile again
|
def get_local_recipes_dir(self):
|
||||||
self.buildozer.state['android.requirements'] = android_requirements
|
local_recipes = self.buildozer.config.getdefault('app', 'p4a.local_recipes')
|
||||||
self.buildozer.state['android.requirements.source'] = source_dirs
|
return realpath(expanduser(local_recipes)) if local_recipes else None
|
||||||
self.buildozer.state.sync()
|
|
||||||
|
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):
|
def _get_package(self):
|
||||||
config = self.buildozer.config
|
config = self.buildozer.config
|
||||||
|
@ -678,22 +800,6 @@ class TargetAndroid(Target):
|
||||||
for wl in p4a_whitelist:
|
for wl in p4a_whitelist:
|
||||||
fd.write(wl + '\n')
|
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):
|
def build_package(self):
|
||||||
dist_name = self.buildozer.config.get('app', 'package.name')
|
dist_name = self.buildozer.config.get('app', 'package.name')
|
||||||
dist_dir = self.get_dist_dir(dist_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:latestapk'] = apk_dest
|
||||||
self.buildozer.state['android:latestmode'] = self.build_mode
|
self.buildozer.state['android:latestmode'] = self.build_mode
|
||||||
|
|
||||||
def get_release_mode(self):
|
|
||||||
return "release-unsigned"
|
|
||||||
|
|
||||||
def _update_libraries_references(self, dist_dir):
|
def _update_libraries_references(self, dist_dir):
|
||||||
# ensure the project.properties exist
|
# ensure the project.properties exist
|
||||||
project_fn = join(dist_dir, 'project.properties')
|
project_fn = join(dist_dir, 'project.properties')
|
||||||
|
@ -1029,27 +1132,6 @@ class TargetAndroid(Target):
|
||||||
|
|
||||||
self.buildozer.info('Application pushed.')
|
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):
|
def cmd_logcat(self, *args):
|
||||||
'''Show the log from the device
|
'''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