Be able to build multi-arch android apk.

By building kiwix-android on the `android` platform, we can now build
`kiwix-lib` on all `android_<arch>` platforms, and so have all
architectures in the same apk.

Fix #108
This commit is contained in:
Matthieu Gautier 2018-05-30 19:25:35 +02:00
parent 9b85791705
commit db82455f03
12 changed files with 84 additions and 20 deletions

View File

@ -82,6 +82,7 @@ platforms :
- native_static
- win32_dyn
- win32_static
- android
- android_arm
- android_arm64
- android_mips
@ -95,9 +96,35 @@ So, if you want to compile `kiwix-tools` for win32 using static linkage:
$ kiwix-build --target-platform win32_dyn
```
Or, android apk for android_arm :
## Android
Android apk (kiwix-android) is a bit a special case.
`kiwix-android` itself is architecture independent (it is written in
java) but it use `kiwix-lib` who is architecture dependent.
When building `kiwix-lib`, you should directly use the
target-platform `android_<arch>`:
```
$ kiwix-build --target-platform android_arm kiwix-android
$ kiwix-build kiwix-android --target-platform android_arm
```
But, `kiwix-android` apk can also be multi arch (ie, it includes
`kiwix-lib` for several architectures). To do so, you must ask to build
`kiwix-android` using the `android` platform:
```
$ kiwix-build --target-platform android kiwix-android
$ kiwix-build kiwix-android # because `android` platform is the default `kiwix-android`
```
By default, when using platform `android`, `kiwix-lib` will be build for
all architectures. This can be change by using the option `--android-arch` :
```
$ kiwix-build kiwix-android # apk for all architectures
$ kiwix-build kiwix-android --android-arch arm # apk for arm architectures (equivalent to `kiwix-android --target-platform android_arm`)
$ kiwix-build kiwix-anrdoid --android-arch arm --android-arch arm64 # apk for arm and arm64 architectures
```
# Outputs

View File

@ -37,6 +37,10 @@ def parse_args():
help="Clean all intermediate files after the (successfull) build")
subgroup.add_argument('--dont-install-packages', action='store_true',
help="Do not try to install packages before compiling")
subgroup.add_argument('--android-arch', action='append',
help=("Specify the architecture to build for android application/libraries.\n"
"Can be specified several times to build for several architectures.\n"
"If not specified, all architectures will be build."))
subgroup = parser.add_argument_group('custom app',
description="Android custom app specific options")
subgroup.add_argument('--android-custom-app',
@ -59,6 +63,8 @@ def parse_args():
err = True
if err:
sys.exit(1)
if not options.android_arch:
options.android_arch = ['arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64']
return options
def main():

View File

@ -57,7 +57,7 @@ class Builder:
return
targetPlatform = PlatformInfo.get_platform(targetPlatformName)
for dep in target.get_dependencies(targetPlatform):
for dep in target.get_dependencies(targetPlatform, True):
try:
depPlatform, depName = dep
except ValueError:

View File

@ -11,7 +11,7 @@ class AllBaseDependencies(Dependency):
Source = NoopSource
class Builder(NoopBuilder):
@classmethod
def get_dependencies(cls, platformInfo):
def get_dependencies(cls, platformInfo, allDeps):
base_deps = ['zlib', 'lzma', 'xapian-core', 'gumbo', 'pugixml', 'libmicrohttpd', 'libaria2', 'icu4c']
if platformInfo.build != 'win32':
base_deps += ["libmagic"]

View File

@ -202,7 +202,7 @@ class Builder:
self.buildEnv = buildEnv
@classmethod
def get_dependencies(cls, platformInfo):
def get_dependencies(cls, platformInfo, allDeps):
return cls.dependencies
@property

View File

@ -26,7 +26,7 @@ class Icu(Dependency):
subsource_dir = "source"
@classmethod
def get_dependencies(cls, platformInfo):
def get_dependencies(cls, platformInfo, allDeps):
plt = 'native_static' if platformInfo.static else 'native_dyn'
return [(plt, 'icu4c')]

View File

@ -5,8 +5,8 @@ from .base import (
GitClone,
GradleBuilder)
from kiwixbuild.utils import pj
from kiwixbuild._global import option
from kiwixbuild.utils import pj, copy_tree
from kiwixbuild._global import option, get_target_step
class KiwixAndroid(Dependency):
name = "kiwix-android"
@ -18,6 +18,15 @@ class KiwixAndroid(Dependency):
class Builder(GradleBuilder):
dependencies = ["kiwix-lib"]
@classmethod
def get_dependencies(cls, platformInfo, allDeps):
if not allDeps:
return super().get_dependencies(platformInfo, allDeps)
else:
deps = [('android_{}'.format(arch), 'kiwix-lib')
for arch in option('android_arch')]
return deps
def build(self):
if option('targets') == 'kiwix-android-custom':
print("SKIP")
@ -31,12 +40,25 @@ class KiwixAndroid(Dependency):
shutil.rmtree(pj(self.build_path, 'kiwixlib', 'src', 'main'))
except FileNotFoundError:
pass
shutil.copytree(pj(self.buildEnv.install_dir, 'kiwix-lib'),
pj(self.build_path, 'kiwixlib', 'src', 'main'))
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
copy_tree(pj(kiwix_builder.buildEnv.install_dir, 'kiwix-lib'),
pj(self.build_path, 'kiwixlib', 'src', 'main'))
os.makedirs(
pj(self.build_path, 'app', 'src', 'main', 'assets', 'icu'),
exist_ok=True)
shutil.copy2(pj(self.buildEnv.install_dir, 'share', 'icu', '58.2',
'icudt58l.dat'),
pj(self.build_path, 'app', 'src', 'main', 'assets',
'icu', 'icudt58l.dat'))
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
shutil.copy2(pj(kiwix_builder.buildEnv.install_dir, 'share', 'icu', '58.2',
'icudt58l.dat'),
pj(self.build_path, 'app', 'src', 'main', 'assets',
'icu', 'icudt58l.dat'))
break

View File

@ -13,7 +13,7 @@ class Kiwixlib(Dependency):
class Builder(MesonBuilder):
@classmethod
def get_dependencies(cls, platformInfo):
def get_dependencies(cls, platformInfo, allDeps):
base_dependencies = ["pugixml", "libzim", "zlib", "lzma", "libaria2", "icu4c"]
if (platformInfo.build != 'android' and
neutralEnv('distname') != 'Darwin'):

View File

@ -22,7 +22,7 @@ class LibMagic(Dependency):
class Builder(MakeBuilder):
@classmethod
def get_dependencies(cls, platformInfo):
def get_dependencies(cls, platformInfo, allDeps):
if platformInfo.build != 'native':
return [('native_static', 'libmagic')]
return []

View File

@ -21,7 +21,7 @@ class Xapian(Dependency):
'_format_CXXFLAGS': "-I{buildEnv.install_dir}/include"}
@classmethod
def get_dependencies(cls, platformInfo):
def get_dependencies(cls, platformInfo, allDeps):
deps = ['zlib', 'lzma']
if (platformInfo.build == 'win32'
or neutralEnv('distname') == 'Darwin'):

View File

@ -1,6 +1,6 @@
from .base import PlatformInfo, MetaPlatformInfo
from kiwixbuild.utils import pj
from kiwixbuild._global import get_target_step
from kiwixbuild._global import get_target_step, option
class AndroidPlatformInfo(PlatformInfo):
@ -118,9 +118,18 @@ class AndroidArm(AndroidPlatformInfo):
class Android(MetaPlatformInfo):
name = "android"
toolchain_names = ['android-sdk', 'gradle']
subPlatformNames = ['android_arm', 'android_arm64', 'android_mips', 'android_mips64', 'android_x86', 'android_x86_64']
compatible_hosts = ['fedora', 'debian']
@property
def subPlatformNames(self):
return ['android_{}'.format(arch) for arch in option('android_arch')]
def add_targets(self, targetName, targets):
if targetName != 'kiwix-android':
return super().add_targets(targetName, targets)
else:
return AndroidPlatformInfo.add_targets(self, targetName, targets)
def __str__(self):
return self.name

View File

@ -62,7 +62,7 @@ class PlatformInfo(metaclass=_MetaPlatform):
targetClass = Dependency.all_deps[targetName]
targets[('source', targetName)] = targetClass.Source
targets[(self.name, targetName)] = targetClass.Builder
for dep in targetClass.Builder.get_dependencies(self):
for dep in targetClass.Builder.get_dependencies(self, False):
try:
depPlatformName, depName = dep
except ValueError: