lbry-fdroid/p4a/pythonforandroid/bdistapk.py
g1tman fe01f50c65 Perf: Use of sort and sorted functions optimized (#748)
* Update mixer.py
* Update graph.py
* Update mixer.py
* Update mixer.py
* Update bdistapk.py
* Update toolchain.py
* Update build.py
* Update build.py
2019-11-25 11:28:16 +01:00

148 lines
5.3 KiB
Python

from __future__ import print_function
from setuptools import Command
from pythonforandroid import toolchain
import sys
from os.path import realpath, join, exists, dirname, curdir, basename, split
from os import makedirs
from glob import glob
from shutil import rmtree, copyfile
def argv_contains(t):
for arg in sys.argv:
if arg.startswith(t):
return True
return False
class BdistAPK(Command):
description = 'Create an APK with python-for-android'
user_options = []
def initialize_options(self):
for option in self.user_options:
setattr(self, option[0].strip('=').replace('-', '_'), None)
option_dict = self.distribution.get_option_dict('apk')
# This is a hack, we probably aren't supposed to loop through
# the option_dict so early because distutils does exactly the
# same thing later to check that we support the
# options. However, it works...
for (option, (source, value)) in option_dict.items():
setattr(self, option, str(value))
def finalize_options(self):
setup_options = self.distribution.get_option_dict('apk')
for (option, (source, value)) in setup_options.items():
if source == 'command line':
continue
if not argv_contains('--' + option):
# allow 'permissions': ['permission', 'permission] in apk
if option == 'permissions':
for perm in value:
sys.argv.append('--permission={}'.format(perm))
elif value in (None, 'None'):
sys.argv.append('--{}'.format(option))
else:
sys.argv.append('--{}={}'.format(option, value))
# Inject some argv options from setup.py if the user did not
# provide them
if not argv_contains('--name'):
name = self.distribution.get_name()
sys.argv.append('--name="{}"'.format(name))
self.name = name
if not argv_contains('--package'):
package = 'org.test.{}'.format(self.name.lower().replace(' ', ''))
print('WARNING: You did not supply an Android package '
'identifier, trying {} instead.'.format(package))
print(' This may fail if this is not a valid identifier')
sys.argv.append('--package={}'.format(package))
if not argv_contains('--version'):
version = self.distribution.get_version()
sys.argv.append('--version={}'.format(version))
if not argv_contains('--arch'):
arch = 'arm64-v8a'
self.arch = arch
sys.argv.append('--arch={}'.format(arch))
def run(self):
self.prepare_build_dir()
from pythonforandroid.toolchain import main
sys.argv[1] = 'apk'
main()
def prepare_build_dir(self):
if argv_contains('--private') and not argv_contains('--launcher'):
print('WARNING: Received --private argument when this would '
'normally be generated automatically.')
print(' This is probably bad unless you meant to do '
'that.')
bdist_dir = 'build/bdist.android-{}'.format(self.arch)
if exists(bdist_dir):
rmtree(bdist_dir)
makedirs(bdist_dir)
globs = []
for directory, patterns in self.distribution.package_data.items():
for pattern in patterns:
globs.append(join(directory, pattern))
filens = []
for pattern in globs:
filens.extend(glob(pattern))
main_py_dirs = []
if not argv_contains('--launcher'):
for filen in filens:
new_dir = join(bdist_dir, dirname(filen))
if not exists(new_dir):
makedirs(new_dir)
print('Including {}'.format(filen))
copyfile(filen, join(bdist_dir, filen))
if basename(filen) in ('main.py', 'main.pyo'):
main_py_dirs.append(filen)
# This feels ridiculous, but how else to define the main.py dir?
# Maybe should just fail?
if not main_py_dirs and not argv_contains('--launcher'):
print('ERROR: Could not find main.py, so no app build dir defined')
print('You should name your app entry point main.py')
exit(1)
if len(main_py_dirs) > 1:
print('WARNING: Multiple main.py dirs found, using the shortest path')
main_py_dirs.sort(key=lambda j: len(split(j)))
if not argv_contains('--launcher'):
sys.argv.append('--private={}'.format(
join(realpath(curdir), bdist_dir, dirname(main_py_dirs[0])))
)
def _set_user_options():
# This seems like a silly way to do things, but not sure if there's a
# better way to pass arbitrary options onwards to p4a
user_options = [('requirements=', None, None),]
for i, arg in enumerate(sys.argv):
if arg.startswith('--'):
if ('=' in arg or
(i < (len(sys.argv) - 1) and not sys.argv[i+1].startswith('-'))):
user_options.append((arg[2:].split('=')[0] + '=', None, None))
else:
user_options.append((arg[2:], None, None))
BdistAPK.user_options = user_options
_set_user_options()