diff --git a/README.md b/README.md index b7011ad..60c93b0 100644 --- a/README.md +++ b/README.md @@ -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_`: + ``` -$ 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 diff --git a/kiwixbuild/__init__.py b/kiwixbuild/__init__.py index 1a194a5..0f7301c 100644 --- a/kiwixbuild/__init__.py +++ b/kiwixbuild/__init__.py @@ -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(): diff --git a/kiwixbuild/builder.py b/kiwixbuild/builder.py index 0734270..7b45126 100644 --- a/kiwixbuild/builder.py +++ b/kiwixbuild/builder.py @@ -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: diff --git a/kiwixbuild/dependencies/all_dependencies.py b/kiwixbuild/dependencies/all_dependencies.py index 096504b..eb91cab 100644 --- a/kiwixbuild/dependencies/all_dependencies.py +++ b/kiwixbuild/dependencies/all_dependencies.py @@ -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"] diff --git a/kiwixbuild/dependencies/base.py b/kiwixbuild/dependencies/base.py index 940a669..645aab9 100644 --- a/kiwixbuild/dependencies/base.py +++ b/kiwixbuild/dependencies/base.py @@ -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 diff --git a/kiwixbuild/dependencies/icu4c.py b/kiwixbuild/dependencies/icu4c.py index 1ac58e1..14dbf8e 100644 --- a/kiwixbuild/dependencies/icu4c.py +++ b/kiwixbuild/dependencies/icu4c.py @@ -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')] diff --git a/kiwixbuild/dependencies/kiwix_android.py b/kiwixbuild/dependencies/kiwix_android.py index 54a03a1..7c15a2c 100644 --- a/kiwixbuild/dependencies/kiwix_android.py +++ b/kiwixbuild/dependencies/kiwix_android.py @@ -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 diff --git a/kiwixbuild/dependencies/kiwix_lib.py b/kiwixbuild/dependencies/kiwix_lib.py index 8647264..a72e5fe 100644 --- a/kiwixbuild/dependencies/kiwix_lib.py +++ b/kiwixbuild/dependencies/kiwix_lib.py @@ -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'): diff --git a/kiwixbuild/dependencies/libmagic.py b/kiwixbuild/dependencies/libmagic.py index 8c4d53a..f25e9da 100644 --- a/kiwixbuild/dependencies/libmagic.py +++ b/kiwixbuild/dependencies/libmagic.py @@ -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 [] diff --git a/kiwixbuild/dependencies/xapian.py b/kiwixbuild/dependencies/xapian.py index 8fc49a0..3d76cbc 100644 --- a/kiwixbuild/dependencies/xapian.py +++ b/kiwixbuild/dependencies/xapian.py @@ -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'): diff --git a/kiwixbuild/platforms/android.py b/kiwixbuild/platforms/android.py index b0d650b..ce06276 100644 --- a/kiwixbuild/platforms/android.py +++ b/kiwixbuild/platforms/android.py @@ -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 diff --git a/kiwixbuild/platforms/base.py b/kiwixbuild/platforms/base.py index 94316ec..44af29b 100644 --- a/kiwixbuild/platforms/base.py +++ b/kiwixbuild/platforms/base.py @@ -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: