Add ios_multi_arch fatlib.

Fix #113
This commit is contained in:
Matthieu Gautier 2018-05-31 15:17:24 +02:00
parent cfdf03c854
commit 369b805e59
7 changed files with 105 additions and 11 deletions

View File

@ -129,6 +129,27 @@ $ kiwix-build kiwix-android --android-arch arm # apk for arm architectures (equi
$ kiwix-build kiwix-anrdoid --android-arch arm --android-arch arm64 # apk for arm and arm64 architectures $ kiwix-build kiwix-anrdoid --android-arch arm --android-arch arm64 # apk for arm and arm64 architectures
``` ```
## IOS
When building for ios, we may want to compile a "fat library", a library
for several architectures.
To do so, you should directly use the target-platfrom `ios_multi`.
As for `android`, `kiwix-build` will build the library several times
(once for each platform) and then create the fat library.
```
$ kiwix-build --target-platform iOS_multi kiwix-lib
```
You can specify the supported architectures with the option `--ios-arch`:
```
$ kiwix-build --target-platform iOS_multi kiwix-lib # all architetures
$ kiwix-build --target-platform iOS_multi --ios-arch arm --ios-arch arm64 # arm and arm64 arch only
```
# Outputs # Outputs
Kiwix-build.py will create several directories: Kiwix-build.py will create several directories:

View File

@ -41,6 +41,10 @@ def parse_args():
help=("Specify the architecture to build for android application/libraries.\n" help=("Specify the architecture to build for android application/libraries.\n"
"Can be specified several times to build for several architectures.\n" "Can be specified several times to build for several architectures.\n"
"If not specified, all architectures will be build.")) "If not specified, all architectures will be build."))
subgroup.add_argument('--ios-arch', action='append',
help=("Specify the architecture to build for ios 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', subgroup = parser.add_argument_group('custom app',
description="Android custom app specific options") description="Android custom app specific options")
subgroup.add_argument('--android-custom-app', subgroup.add_argument('--android-custom-app',
@ -65,6 +69,9 @@ def parse_args():
sys.exit(1) sys.exit(1)
if not options.android_arch: if not options.android_arch:
options.android_arch = ['arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'] options.android_arch = ['arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64']
if not options.ios_arch:
options.ios_arch = ['armv7', 'arm64', 'i386', 'x86_64']
return options return options
def main(): def main():

View File

@ -24,6 +24,10 @@ class Builder:
else: else:
target_platform = 'native_dyn' target_platform = 'native_dyn'
platform = PlatformInfo.get_platform(target_platform, self._targets) platform = PlatformInfo.get_platform(target_platform, self._targets)
if neutralEnv('distname') not in platform.compatible_hosts:
print(('ERROR: The target platform {} cannot be build on host {}.\n'
'Select another target platform or change your host system.'
).format(platform.name, neutralEnv('distname')))
self.targetDefs = platform.add_targets(option('target'), self._targets) self.targetDefs = platform.add_targets(option('target'), self._targets)
def finalize_target_steps(self): def finalize_target_steps(self):

View File

@ -9,6 +9,7 @@ from . import (
gradle, gradle,
gumbo, gumbo,
icu4c, icu4c,
ios_fat_lib,
kiwix_android, kiwix_android,
kiwix_custom_app, kiwix_custom_app,
kiwix_lib, kiwix_lib,

View File

@ -0,0 +1,52 @@
import os
from kiwixbuild.platforms import PlatformInfo
from kiwixbuild.utils import pj, copy_tree, run_command
from kiwixbuild._global import option
from .base import (
Dependency,
NoopSource,
Builder as BaseBuilder)
class IOSFatLib(Dependency):
name = "_ios_fat_lib"
Source = NoopSource
class Builder(BaseBuilder):
@classmethod
def get_dependencies(self, platfomInfo, alldeps):
base_target = option('target')
return [('iOS_{}'.format(arch), base_target) for arch in option('ios_arch')]
def _copy_headers(self, context):
plt = PlatformInfo.get_platform('iOS_{}'.format(option('ios_arch')[0]))
include_src = pj(plt.buildEnv.install_dir, 'include')
include_dst = pj(self.buildEnv.install_dir, 'include')
copy_tree(include_src, include_dst)
def _merge_libs(self, context):
lib_dirs = []
for arch in option('ios_arch'):
plt = PlatformInfo.get_platform('iOS_{}'.format(arch))
lib_dirs.append(pj(plt.buildEnv.install_dir, 'lib'))
libs = []
for f in os.listdir(lib_dirs[0]):
if os.path.islink(pj(lib_dirs[0], f)):
continue
if f.endswith('.a') or f.endswith('.dylib'):
libs.append(f)
os.makedirs(pj(self.buildEnv.install_dir, 'lib'), exist_ok=True)
command_tmp = "lipo -create {input} -output {output}"
for l in libs:
command = command_tmp.format(
input=" ".join(pj(d, l) for d in lib_dirs),
output=pj(self.buildEnv.install_dir, 'lib', l))
run_command(command, self.buildEnv.install_dir, context)
def build(self):
self.command('copy_headers', self._copy_headers)
self.command('merge_libs', self._merge_libs)

View File

@ -32,16 +32,10 @@ class PlatformInfo(metaclass=_MetaPlatform):
print("Should not got there.") print("Should not got there.")
print(cls.all_running_platforms) print(cls.all_running_platforms)
raise KeyError(name) raise KeyError(name)
sys.exit(-1)
cls.all_running_platforms[name] = cls.all_platforms[name](targets) cls.all_running_platforms[name] = cls.all_platforms[name](targets)
return cls.all_running_platforms[name] return cls.all_running_platforms[name]
def __init__(self, targets): def __init__(self, targets):
if neutralEnv('distname') not in self.compatible_hosts:
print(('ERROR: The target platform {} cannot be build on host {}.\n'
'Select another target platform, or change your host system.'
).format(self.name, neutralEnv('distname')))
sys.exit(-1)
self.all_running_platforms[self.name] = self self.all_running_platforms[self.name] = self
self.buildEnv = BuildEnv(self) self.buildEnv = BuildEnv(self)
self.setup_toolchains(targets) self.setup_toolchains(targets)

View File

@ -1,9 +1,9 @@
import subprocess import subprocess
from .base import PlatformInfo from .base import PlatformInfo, MetaPlatformInfo
from kiwixbuild.utils import pj, xrun_find from kiwixbuild.utils import pj, xrun_find
from kiwixbuild._global import option
class iOSPlatformInfo(PlatformInfo): class iOSPlatformInfo(PlatformInfo):
build = 'iOS' build = 'iOS'
@ -84,17 +84,32 @@ class iOSArmv7(iOSPlatformInfo):
class iOSArm64(iOSPlatformInfo): class iOSArm64(iOSPlatformInfo):
name = 'iOS_arm64' name = 'iOS_arm64'
arch = cpu = 'arm64' arch = cpu = 'arm64'
arch_full = 'arm-apple-darwin' arch_full = 'aarch64-apple-darwin'
sdk_name = 'iphoneos' sdk_name = 'iphoneos'
class iOSi386(iOSPlatformInfo): class iOSi386(iOSPlatformInfo):
name = 'iOS_i386' name = 'iOS_i386'
arch = cpu = 'i386' arch = cpu = 'i386'
arch_full = '' arch_full = 'i386-apple-darwin'
sdk_name = 'iphonesimulator' sdk_name = 'iphonesimulator'
class iOSx64(iOSPlatformInfo): class iOSx64(iOSPlatformInfo):
name = 'iOS_x86_64' name = 'iOS_x86_64'
arch = cpu = 'x86_64' arch = cpu = 'x86_64'
arch_full = '' arch_full = 'x86_64-apple-darwin'
sdk_name = 'iphonesimulator' sdk_name = 'iphonesimulator'
class IOS(MetaPlatformInfo):
name = "iOS_multi"
compatible_hosts = ['Darwin']
@property
def subPlatformNames(self):
return ['iOS_{}'.format(arch) for arch in option('ios_arch')]
def add_targets(self, targetName, targets):
super().add_targets(targetName, targets)
return PlatformInfo.add_targets(self, '_ios_fat_lib', targets)
def __str__(self):
return self.name