Android custom apps can now be compiled for individual architectures #6

This commit is contained in:
mhutti1 2016-07-27 21:25:30 +01:00
parent 5a78089a1f
commit db2c8db537
2 changed files with 63 additions and 43 deletions

View File

@ -21,6 +21,17 @@ from subprocess import call, check_output
ALL_ARCHS = ['arm-linux-androideabi', 'mipsel-linux-android', 'x86', 'aarch64-linux-android'] ALL_ARCHS = ['arm-linux-androideabi', 'mipsel-linux-android', 'x86', 'aarch64-linux-android']
def syscall(args, shell=False, with_print=True):
''' make a system call '''
args = args.split()
if with_print:
print(u"-----------\n" + u" ".join(args) + u"\n-----------")
if shell:
args = ' '.join(args)
call(args, shell=shell)
def find_package(): def find_package():
d = parse('AndroidManifest.xml') d = parse('AndroidManifest.xml')
return [e.getAttribute('package').strip() return [e.getAttribute('package').strip()
@ -91,6 +102,9 @@ def init_with_args(args):
#doptions.pop(idx) #doptions.pop(idx)
# recreate options list from other items # recreate options list from other items
options = [v for v in doptions.values() if not v.startswith('--on=')] options = [v for v in doptions.values() if not v.startswith('--on=')]
# clean out current libs
os.chdir(curdir)
syscall('rm -rf libs/*', shell=True)
if len(options): if len(options):
# we received options. # we received options.
@ -137,6 +151,9 @@ CURRENT_PATH = os.path.dirname(os.path.abspath(__file__))
# the parent directory of this file for relative referencing # the parent directory of this file for relative referencing
PARENT_PATH = os.path.dirname(CURRENT_PATH) PARENT_PATH = os.path.dirname(CURRENT_PATH)
# store where we are so we can go back
curdir = os.getcwd()
# different names of folder path for accessing files # different names of folder path for accessing files
ARCHS_FULL_NAMES = { ARCHS_FULL_NAMES = {
'arm-linux-androideabi': 'arm-linux-androideabi', 'arm-linux-androideabi': 'arm-linux-androideabi',
@ -159,6 +176,7 @@ CREATE_TOOLCHAIN, COMPILE_LIBLZMA, COMPILE_LIBICU, COMPILE_LIBZIM, \
COMPILE_LIBKIWIX, COMPILE_LIBXAPIAN, STRIP_LIBKIWIX, COMPILE_APK, \ COMPILE_LIBKIWIX, COMPILE_LIBXAPIAN, STRIP_LIBKIWIX, COMPILE_APK, \
COMPILE_GLASSIFY, LOCALES_TXT, CLEAN, ARCHS = init_with_args(sys.argv) COMPILE_GLASSIFY, LOCALES_TXT, CLEAN, ARCHS = init_with_args(sys.argv)
# compiler version to use # compiler version to use
# list of available toolchains in <NDK_PATH>/toolchains # list of available toolchains in <NDK_PATH>/toolchains
# 4.4.3, 4.6, 4.7, clang3.1, clang3.2 # 4.4.3, 4.6, 4.7, clang3.1, clang3.2
@ -244,18 +262,6 @@ def fail_on_missing(path):
u"and run 'make' in 'src/dependencies'" % path) u"and run 'make' in 'src/dependencies'" % path)
sys.exit(1) sys.exit(1)
def syscall(args, shell=False, with_print=True):
''' make a system call '''
args = args.split()
if with_print:
print(u"-----------\n" + u" ".join(args) + u"\n-----------")
if shell:
args = ' '.join(args)
call(args, shell=shell)
def change_env(values): def change_env(values):
''' update a set of environment variables ''' ''' update a set of environment variables '''
for k, v in values.items(): for k, v in values.items():
@ -271,9 +277,6 @@ def failed_on_step(error_msg):
for path in REQUIRED_PATHS: for path in REQUIRED_PATHS:
fail_on_missing(path) fail_on_missing(path)
# store where we are so we can go back
curdir = os.getcwd()
# Prepare the libicu cross-compilation # Prepare the libicu cross-compilation
if COMPILE_LIBICU: if COMPILE_LIBICU:
if (not os.path.exists(ICU_TMP)): if (not os.path.exists(ICU_TMP)):
@ -293,6 +296,9 @@ for arch in ARCHS:
arch_full = ARCHS_FULL_NAMES.get(arch) arch_full = ARCHS_FULL_NAMES.get(arch)
arch_short = ARCHS_SHORT_NAMES.get(arch) arch_short = ARCHS_SHORT_NAMES.get(arch)
if (not os.path.exists('libs/' + arch_short)):
syscall('mkdir libs/' + arch_short, shell=True)
# platform contains the toolchain # platform contains the toolchain
platform = os.path.join(PLATFORM_PREFIX, arch) platform = os.path.join(PLATFORM_PREFIX, arch)
@ -652,7 +658,7 @@ for arch in ARCHS:
os.remove(obj) os.remove(obj)
# check that the step went well # check that the step went well
if COMPILE_LIBKIWIX or STRIP_LIBKIWIX or COMPILE_APK: if COMPILE_LIBKIWIX or STRIP_LIBKIWIX:
if not os.path.exists(os.path.join('libs', arch_short, 'libkiwix.so')): if not os.path.exists(os.path.join('libs', arch_short, 'libkiwix.so')):
failed_on_step('The libkiwix.so shared lib has not been created ' failed_on_step('The libkiwix.so shared lib has not been created '
'and is not present.') 'and is not present.')

View File

@ -42,6 +42,8 @@ PY3 = sys.version_info.major >= 3
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
architectures = [];
DEFAULT_JSDATA = { DEFAULT_JSDATA = {
# mandatory fields # mandatory fields
# 'app_name': "Kiwix Custom App", # 'app_name': "Kiwix Custom App",
@ -432,16 +434,23 @@ def step_compile_libkiwix(jsdata, **options):
move_to_android_placeholder() move_to_android_placeholder()
# compile libkiwix and all dependencies if not architectures:
syscall('./build-android-with-native.py ' # compile libkiwix and all dependencies
'--toolchain ' syscall('./build-android-with-native.py '
'--lzma ' '--toolchain '
'--icu ' '--lzma '
'--zim ' '--icu '
'--kiwix ' '--zim '
'--strip ' '--kiwix '
'--locales ') '--strip '
'--locales ')
else:
command = './build-android-with-native.py --toolchain --lzma --icu --zim --kiwix --strip --locales '
for arch in architectures:
command += "--on=" + arch
syscall(command)
def step_embed_zimfile(jsdata, **options): def step_embed_zimfile(jsdata, **options):
''' prepare a content-libs.jar file with ZIM file for inclusion in APK ''' ''' prepare a content-libs.jar file with ZIM file for inclusion in APK '''
@ -450,19 +459,17 @@ def step_embed_zimfile(jsdata, **options):
return return
move_to_android_placeholder() move_to_android_placeholder()
# create content-libs.jar # create content-libs.jar
tmpd = tempfile.mkdtemp() tmpd = tempfile.mkdtemp()
archs = os.listdir('libs') for arch in architectures:
for arch in archs:
os.makedirs(os.path.join(tmpd, 'lib', arch)) os.makedirs(os.path.join(tmpd, 'lib', arch))
# shutil.copy(os.path.join('libs', arch, 'libkiwix.so'), # shutil.copy(os.path.join('libs', arch, 'libkiwix.so'),
# os.path.join(tmpd, 'lib', arch, 'libkiwix.so')) # os.path.join(tmpd, 'lib', arch, 'libkiwix.so'))
copy_to(jsdata.get('zim_file'), copy_to(jsdata.get('zim_file'),
os.path.join(tmpd, 'lib', archs[0], jsdata.get('zim_name'))) os.path.join(tmpd, 'lib', architectures[0], jsdata.get('zim_name')))
for arch in archs[1:]: for arch in architectures[1:]:
os.chdir(os.path.join(tmpd, 'lib', arch)) os.chdir(os.path.join(tmpd, 'lib', arch))
os.link('../{}/{}'.format(archs[0], jsdata.get('zim_name')), os.link('../{}/{}'.format(architectures[0], jsdata.get('zim_name')),
jsdata.get('zim_name')) jsdata.get('zim_name'))
os.chdir(tmpd) os.chdir(tmpd)
syscall('zip -r -0 -y {} lib' syscall('zip -r -0 -y {} lib'
@ -479,7 +486,6 @@ def step_build_apk(jsdata, **options):
'--apk ' '--apk '
'--clean ') '--clean ')
def step_move_apk_to_destination(jsdata, **options): def step_move_apk_to_destination(jsdata, **options):
''' place and rename built APKs to main output directory ''' ''' place and rename built APKs to main output directory '''
@ -607,16 +613,24 @@ if __name__ == '__main__':
jspath = sys.argv[1] jspath = sys.argv[1]
args = sys.argv[2:] args = sys.argv[2:]
if len(args) == 0: full = True
for arg in args:
step_name = re.sub(r'^\-\-', '', arg)
if step_name in ARGS_MATRIX.keys():
full = False
if (len(args) == 0) or (full):
options = OrderedDict([('do_{}'.format(step), True) options = OrderedDict([('do_{}'.format(step), True)
for step in ARGS_MATRIX.keys()]) for step in ARGS_MATRIX.keys()])
else: if (len(args) != 0):
options = OrderedDict()
for arg in args: for arg in args:
step_name = re.sub(r'^\-\-', '', arg) step_name = re.sub(r'^\-\-', '', arg)
if step_name not in ARGS_MATRIX.keys(): if step_name not in ARGS_MATRIX.keys():
logger.error("{} not a valid step. Exiting.".format(step_name)) if step_name.startswith('on='):
usage(sys.argv[0], 1) rarch = step_name.split('=', 1)[1]
architectures.append(rarch)
else:
logger.error("{} not a valid step. Exiting.".format(step_name))
usage(sys.argv[0], 1)
else: else:
options.update({'do_{}'.format(step_name): True}) options.update({'do_{}'.format(step_name): True})