From 97666b0fc9a9e982e9d928610a0770cdd854d097 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Tue, 27 Mar 2018 16:03:33 +0200 Subject: [PATCH 1/3] Create a real module kiwixbuild and make it installable. Split files. Make kiwix-build installable using pip. Module is now called `kiwixbuild` because `kiwix-build` is not a valid python identifier. Also split toolchains in separated directory. --- MANIFEST.in | 4 + kiwix-build.py => kiwixbuild/__init__.py | 369 +----------------- kiwixbuild/__main__.py | 7 + dependencies.py => kiwixbuild/dependencies.py | 7 +- .../dependency_utils.py | 4 +- .../dependency_versions.py | 0 .../patches}/CTPP2SourceLoader.hpp.patch | 0 .../ctpp2_compile_ctpp2c_static.patch | 0 .../ctpp2_dll_export_VMExecutable.patch | 0 .../patches}/ctpp2_fix-static-libname.patch | 0 .../patches}/ctpp2_iconv_support.patch | 0 .../patches}/ctpp2_include.patch | 0 .../patches}/ctpp2_mingw32.patch | 0 .../patches}/ctpp2_no_src_modification.patch | 0 .../ctpp2_win_install_lib_in_lib_dir.patch | 0 .../icu4c_android_elf64_st_info.patch | 0 .../patches}/icu4c_custom_data.patch | 0 .../icu4c_fix_static_lib_name_mingw.patch | 0 .../patches}/icu4c_noxlocale.patch | 0 .../patches}/libaria2_android.patch | 0 .../patches}/pugixml_meson.patch | 0 .../patches}/zlib_std_libname.patch | 0 .../templates}/bash_wrapper.sh | 0 .../templates}/cmake_android_cross_file.txt | 0 .../templates}/cmake_cross_file.txt | 0 .../templates}/meson_android_cross_file.txt | 0 .../templates}/meson_cross_file.txt | 0 kiwixbuild/toolchains/__init__.py | 4 + kiwixbuild/toolchains/android_ndk.py | 133 +++++++ kiwixbuild/toolchains/android_sdk.py | 57 +++ kiwixbuild/toolchains/armhf.py | 66 ++++ kiwixbuild/toolchains/base_toolchain.py | 70 ++++ kiwixbuild/toolchains/ios.py | 4 + kiwixbuild/toolchains/mingw32.py | 51 +++ utils.py => kiwixbuild/utils.py | 9 + setup.py | 42 ++ 36 files changed, 459 insertions(+), 368 deletions(-) create mode 100644 MANIFEST.in rename kiwix-build.py => kiwixbuild/__init__.py (68%) mode change 100755 => 100644 create mode 100644 kiwixbuild/__main__.py rename dependencies.py => kiwixbuild/dependencies.py (99%) rename dependency_utils.py => kiwixbuild/dependency_utils.py (98%) rename dependency_versions.py => kiwixbuild/dependency_versions.py (100%) rename {patches => kiwixbuild/patches}/CTPP2SourceLoader.hpp.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_compile_ctpp2c_static.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_dll_export_VMExecutable.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_fix-static-libname.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_iconv_support.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_include.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_mingw32.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_no_src_modification.patch (100%) rename {patches => kiwixbuild/patches}/ctpp2_win_install_lib_in_lib_dir.patch (100%) rename {patches => kiwixbuild/patches}/icu4c_android_elf64_st_info.patch (100%) rename {patches => kiwixbuild/patches}/icu4c_custom_data.patch (100%) rename {patches => kiwixbuild/patches}/icu4c_fix_static_lib_name_mingw.patch (100%) rename {patches => kiwixbuild/patches}/icu4c_noxlocale.patch (100%) rename {patches => kiwixbuild/patches}/libaria2_android.patch (100%) rename {patches => kiwixbuild/patches}/pugixml_meson.patch (100%) rename {patches => kiwixbuild/patches}/zlib_std_libname.patch (100%) rename {templates => kiwixbuild/templates}/bash_wrapper.sh (100%) rename {templates => kiwixbuild/templates}/cmake_android_cross_file.txt (100%) rename {templates => kiwixbuild/templates}/cmake_cross_file.txt (100%) rename {templates => kiwixbuild/templates}/meson_android_cross_file.txt (100%) rename {templates => kiwixbuild/templates}/meson_cross_file.txt (100%) create mode 100644 kiwixbuild/toolchains/__init__.py create mode 100644 kiwixbuild/toolchains/android_ndk.py create mode 100644 kiwixbuild/toolchains/android_sdk.py create mode 100644 kiwixbuild/toolchains/armhf.py create mode 100644 kiwixbuild/toolchains/base_toolchain.py create mode 100644 kiwixbuild/toolchains/ios.py create mode 100644 kiwixbuild/toolchains/mingw32.py rename utils.py => kiwixbuild/utils.py (97%) create mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..ed2b8c9 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,4 @@ +include kiwixbuild/templates/cmake_cross_file.txt +include kiwixbuild/templates/meson_cross_file.txt +include kiwixbuild/templates/cmake_android_cross_file.txt +recursise-include kiwixbuild/patches *.patch diff --git a/kiwix-build.py b/kiwixbuild/__init__.py old mode 100755 new mode 100644 similarity index 68% rename from kiwix-build.py rename to kiwixbuild/__init__.py index 10ece26..32bbf51 --- a/kiwix-build.py +++ b/kiwixbuild/__init__.py @@ -8,9 +8,9 @@ import subprocess import platform from collections import OrderedDict -from dependencies import Dependency -from dependency_utils import ReleaseDownload, Builder, GitClone -from utils import ( +from .toolchains import Toolchain +from .dependencies import Dependency +from .utils import ( pj, remove_duplicates, add_execution_right, @@ -47,7 +47,7 @@ PACKAGE_NAME_MAPPERS = { 'gumbo' : ['gumbo-parser-devel'], }, 'fedora_native_static': { - 'COMMON': _fedora_common + ['glibc-static', 'libstdc++-static'], + 'COMMON': _fedora_common, 'zlib': ['zlib-devel', 'zlib-static'], 'lzma': ['xz-devel', 'xz-static'] # Either there is no packages, or no static or too old @@ -118,12 +118,6 @@ PACKAGE_NAME_MAPPERS = { } -def which(name): - command = "which {}".format(name) - output = subprocess.check_output(command, shell=True) - return output[:-1].decode() - - class TargetInfo: def __init__(self, build, static, toolchains, hosts=None): self.build = build @@ -536,355 +530,6 @@ class BuildEnv: with open(autoskip_file, 'w'): pass -class _MetaToolchain(type): - def __new__(cls, name, bases, dct): - _class = type.__new__(cls, name, bases, dct) - if name != 'Toolchain': - Toolchain.all_toolchains[name] = _class - return _class - - -class Toolchain(metaclass=_MetaToolchain): - all_toolchains = {} - configure_option = "" - cmake_option = "" - exec_wrapper_def = "" - Builder = None - Source = None - - def __init__(self, buildEnv): - self.buildEnv = buildEnv - self.source = self.Source(self) if self.Source else None - self.builder = self.Builder(self) if self.Builder else None - - @property - def full_name(self): - return "{name}-{version}".format( - name = self.name, - version = self.version) - - @property - def source_path(self): - return pj(self.buildEnv.source_dir, self.source.source_dir) - - @property - def _log_dir(self): - return self.buildEnv.log_dir - - def set_env(self, env): - pass - - def set_compiler(self, env): - pass - - def command(self, name, function, *args): - print(" {} {} : ".format(name, self.name), end="", flush=True) - log = pj(self._log_dir, 'cmd_{}_{}.log'.format(name, self.name)) - context = Context(name, log, True) - try: - ret = function(*args, context=context) - context._finalise() - print("OK") - return ret - except SkipCommand: - print("SKIP") - except subprocess.CalledProcessError: - print("ERROR") - try: - with open(log, 'r') as f: - print(f.read()) - except: - pass - raise StopBuild() - except: - print("ERROR") - raise - - -class mingw32_toolchain(Toolchain): - name = 'mingw32' - arch_full = 'i686-w64-mingw32' - - @property - def root_path(self): - return self.buildEnv.cross_config['root_path'] - - @property - def binaries(self): - return {k:which('{}-{}'.format(self.arch_full, v)) - for k, v in (('CC', 'gcc'), - ('CXX', 'g++'), - ('AR', 'ar'), - ('STRIP', 'strip'), - ('WINDRES', 'windres'), - ('RANLIB', 'ranlib')) - } - - @property - def exec_wrapper_def(self): - try: - which('wine') - except subprocess.CalledProcessError: - return "" - else: - return "exec_wrapper = 'wine'" - - - @property - def configure_option(self): - return '--host={}'.format(self.arch_full) - - def get_bin_dir(self): - return [pj(self.root_path, 'bin')] - - def set_env(self, env): - env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') - env['LIBS'] = " ".join(self.buildEnv.cross_config['extra_libs']) + " " +env['LIBS'] - - def set_compiler(self, env): - for k, v in self.binaries.items(): - env[k] = v - - -class android_ndk(Toolchain): - name = 'android-ndk' - version = 'r13b' - gccver = '4.9.x' - - @property - def api(self): - return '21' if self.arch in ('arm64', 'mips64', 'x86_64') else '14' - - @property - def platform(self): - return 'android-'+self.api - - @property - def arch(self): - return self.buildEnv.platform_info.arch - - @property - def arch_full(self): - return self.buildEnv.platform_info.arch_full - - @property - def toolchain(self): - return self.arch_full+"-4.9" - - @property - def root_path(self): - return pj(self.builder.install_path, 'sysroot') - - @property - def binaries(self): - binaries = ((k,'{}-{}'.format(self.arch_full, v)) - for k, v in (('CC', 'gcc'), - ('CXX', 'g++'), - ('AR', 'ar'), - ('STRIP', 'strip'), - ('WINDRES', 'windres'), - ('RANLIB', 'ranlib'), - ('LD', 'ld')) - ) - return {k:pj(self.builder.install_path, 'bin', v) - for k,v in binaries} - - @property - def configure_option(self): - return '--host={}'.format(self.arch_full) - - @property - def full_name(self): - return "{name}-{version}-{arch}-{api}".format( - name = self.name, - version = self.version, - arch = self.arch, - api = self.api) - - class Source(ReleaseDownload): - archive = Remotefile('android-ndk-r13b-linux-x86_64.zip', - '3524d7f8fca6dc0d8e7073a7ab7f76888780a22841a6641927123146c3ffd29c', - 'https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip') - - @property - def source_dir(self): - return "{}-{}".format( - self.target.name, - self.target.version) - - - class Builder(Builder): - - @property - def install_path(self): - return self.build_path - - def _build_platform(self, context): - context.try_skip(self.build_path) - script = pj(self.source_path, 'build/tools/make_standalone_toolchain.py') - add_execution_right(script) - command = '{script} --arch={arch} --api={api} --install-dir={install_dir} --force' - command = command.format( - script=script, - arch=self.target.arch, - api=self.target.api, - install_dir=self.install_path - ) - self.buildEnv.run_command(command, self.build_path, context) - - def _fix_permission_right(self, context): - context.try_skip(self.build_path) - bin_dirs = [pj(self.install_path, 'bin'), - pj(self.install_path, self.target.arch_full, 'bin'), - pj(self.install_path, 'libexec', 'gcc', self.target.arch_full, self.target.gccver) - ] - for root, dirs, files in os.walk(self.install_path): - if not root in bin_dirs: - continue - - for file_ in files: - file_path = pj(root, file_) - if os.path.islink(file_path): - continue - add_execution_right(file_path) - - def build(self): - self.command('build_platform', self._build_platform) - self.command('fix_permission_right', self._fix_permission_right) - - def get_bin_dir(self): - return [pj(self.builder.install_path, 'bin')] - - def set_env(self, env): - env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') - env['CFLAGS'] = '-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} '.format(self.root_path) + env['CFLAGS'] - env['CXXFLAGS'] = '-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} '.format(self.root_path) + env['CXXFLAGS'] - env['LDFLAGS'] = '--sysroot={} '.format(self.root_path) + env['LDFLAGS'] - #env['CFLAGS'] = ' -fPIC -D_FILE_OFFSET_BITS=64 -O3 '+env['CFLAGS'] - #env['CXXFLAGS'] = (' -D__OPTIMIZE__ -fno-strict-aliasing ' - # ' -DU_HAVE_NL_LANGINFO_CODESET=0 ' - # '-DU_STATIC_IMPLEMENTATION -O3 ' - # '-DU_HAVE_STD_STRING -DU_TIMEZONE=0 ')+env['CXXFLAGS'] - env['NDK_DEBUG'] = '0' - - def set_compiler(self, env): - env['CC'] = self.binaries['CC'] - env['CXX'] = self.binaries['CXX'] - - -class android_sdk(Toolchain): - name = 'android-sdk' - version = 'r25.2.3' - - class Source(ReleaseDownload): - archive = Remotefile('tools_r25.2.3-linux.zip', - '1b35bcb94e9a686dff6460c8bca903aa0281c6696001067f34ec00093145b560', - 'https://dl.google.com/android/repository/tools_r25.2.3-linux.zip') - - class Builder(Builder): - - @property - def install_path(self): - return pj(self.buildEnv.toolchain_dir, self.target.full_name) - - def _build_platform(self, context): - context.try_skip(self.install_path) - tools_dir = pj(self.install_path, 'tools') - shutil.copytree(self.source_path, tools_dir) - script = pj(tools_dir, 'android') - command = '{script} --verbose update sdk -a --no-ui --filter {packages}' - command = command.format( - script=script, - packages = ','.join(str(i) for i in [1,2,8,34,162]) - ) - # packages correspond to : - # - 1 : Android SDK Tools, revision 25.2.5 - # - 2 : Android SDK Platform-tools, revision 25.0.3 - # - 8 : Android SDK Build-tools, revision 24.0.1 - # - 34 : SDK Platform Android 7.0, API 24, revision 2 - # - 162 : Android Support Repository, revision 44 - self.buildEnv.run_command(command, self.install_path, context, input="y\n") - - def _fix_licenses(self, context): - context.try_skip(self.install_path) - os.makedirs(pj(self.install_path, 'licenses'), exist_ok=True) - with open(pj(self.install_path, 'licenses', 'android-sdk-license'), 'w') as f: - f.write("\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e") - - def build(self): - self.command('build_platform', self._build_platform) - self.command('fix_licenses', self._fix_licenses) - - def get_bin_dir(self): - return [] - - def set_env(self, env): - env['ANDROID_HOME'] = self.builder.install_path - - -class armhf_toolchain(Toolchain): - name = 'armhf' - arch_full = 'arm-linux-gnueabihf' - - class Source(GitClone): - git_remote = "https://github.com/raspberrypi/tools" - git_dir = "raspberrypi-tools" - - @property - def root_path(self): - return pj(self.source_path, 'arm-bcm2708', 'gcc-linaro-arm-linux-gnueabihf-raspbian-x64') - - @property - def binaries(self): - binaries = ((k,'{}-{}'.format(self.arch_full, v)) - for k, v in (('CC', 'gcc'), - ('CXX', 'g++'), - ('AR', 'ar'), - ('STRIP', 'strip'), - ('WINDRES', 'windres'), - ('RANLIB', 'ranlib'), - ('LD', 'ld')) - ) - return {k:pj(self.root_path, 'bin', v) - for k,v in binaries} - - @property - def exec_wrapper_def(self): - try: - which('qemu-arm') - except subprocess.CalledProcessError: - return "" - else: - return "exec_wrapper = 'qemu-arm'" - - @property - def configure_option(self): - return '--host={}'.format(self.arch_full) - - def get_bin_dir(self): - return [pj(self.root_path, 'bin')] - - def set_env(self, env): - env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') - env['CFLAGS'] = " -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CFLAGS'] - env['CXXFLAGS'] = " -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CXXFLAGS'] - env['LIBS'] = " ".join(self.buildEnv.cross_config['extra_libs']) + " " +env['LIBS'] - env['QEMU_LD_PREFIX'] = pj(self.root_path, "arm-linux-gnueabihf", "libc") - env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format( - ':'.join([ - pj(self.root_path, "arm-linux-gnueabihf", "lib"), - pj(self.buildEnv.install_dir, 'lib'), - pj(self.buildEnv.install_dir, self.buildEnv.libprefix) - ])) - - def set_compiler(self, env): - env['CC'] = self.binaries['CC'] - env['CXX'] = self.binaries['CXX'] - - -class iOS_sdk(Toolchain): - pass - class Builder: def __init__(self, options): @@ -897,7 +542,7 @@ class Builder: self.add_targets(targetDef, _targets) dependencies = self.order_dependencies(_targets, targetDef) dependencies = list(remove_duplicates(dependencies)) - + for dep in dependencies: if self.options.build_deps_only and dep == targetDef: continue @@ -1021,10 +666,10 @@ def parse_args(): sys.exit(1) return options - -if __name__ == "__main__": +def main(): options = parse_args() options.working_dir = os.path.abspath(options.working_dir) setup_print_progress(options.show_progress) builder = Builder(options) builder.run() + diff --git a/kiwixbuild/__main__.py b/kiwixbuild/__main__.py new file mode 100644 index 0000000..43b4ce7 --- /dev/null +++ b/kiwixbuild/__main__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +from . import main + + +if __name__ == "__main__": + main() diff --git a/dependencies.py b/kiwixbuild/dependencies.py similarity index 99% rename from dependencies.py rename to kiwixbuild/dependencies.py index 9fe541b..4b5cf6a 100644 --- a/dependencies.py +++ b/kiwixbuild/dependencies.py @@ -1,7 +1,7 @@ import shutil, os, json from urllib.parse import urlparse -from dependency_utils import ( +from kiwixbuild.dependency_utils import ( Dependency, ReleaseDownload, GitClone, @@ -14,7 +14,7 @@ from dependency_utils import ( NoopBuilder, Builder as BaseBuilder) -from utils import Remotefile, pj, SkipCommand, copy_tree, add_execution_right +from kiwixbuild.utils import Remotefile, pj, SkipCommand, copy_tree, add_execution_right # ************************************* # Missing dependencies @@ -22,7 +22,6 @@ from utils import Remotefile, pj, SkipCommand, copy_tree, add_execution_right # exist in your "distri" (linux/mac) ? # If not, we need to compile them here # ************************************* -# aria2 # Argtable # MSVirtual # Android @@ -415,7 +414,7 @@ class AllBaseDependencies(Dependency): @property def dependencies(self): - base_deps = ['zlib', 'lzma', 'xapian-core', 'gumbo', 'pugixml', 'libmicrohttpd', 'libaria2'] + base_deps = ['zlib', 'lzma', 'xapian-core', 'gumbo', 'pugixml', 'libmicrohttpd'] if self.buildEnv.platform_info.build != 'native': base_deps += ["icu4c_cross-compile"] else: diff --git a/dependency_utils.py b/kiwixbuild/dependency_utils.py similarity index 98% rename from dependency_utils.py rename to kiwixbuild/dependency_utils.py index 67661cf..0af71c7 100644 --- a/dependency_utils.py +++ b/kiwixbuild/dependency_utils.py @@ -2,8 +2,8 @@ import subprocess import os import shutil -from utils import pj, Context, SkipCommand, extract_archive, Defaultdict, StopBuild -from dependency_versions import main_project_versions, base_deps_versions +from kiwixbuild.utils import pj, Context, SkipCommand, extract_archive, Defaultdict, StopBuild +from kiwixbuild.dependency_versions import main_project_versions, base_deps_versions SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) diff --git a/dependency_versions.py b/kiwixbuild/dependency_versions.py similarity index 100% rename from dependency_versions.py rename to kiwixbuild/dependency_versions.py diff --git a/patches/CTPP2SourceLoader.hpp.patch b/kiwixbuild/patches/CTPP2SourceLoader.hpp.patch similarity index 100% rename from patches/CTPP2SourceLoader.hpp.patch rename to kiwixbuild/patches/CTPP2SourceLoader.hpp.patch diff --git a/patches/ctpp2_compile_ctpp2c_static.patch b/kiwixbuild/patches/ctpp2_compile_ctpp2c_static.patch similarity index 100% rename from patches/ctpp2_compile_ctpp2c_static.patch rename to kiwixbuild/patches/ctpp2_compile_ctpp2c_static.patch diff --git a/patches/ctpp2_dll_export_VMExecutable.patch b/kiwixbuild/patches/ctpp2_dll_export_VMExecutable.patch similarity index 100% rename from patches/ctpp2_dll_export_VMExecutable.patch rename to kiwixbuild/patches/ctpp2_dll_export_VMExecutable.patch diff --git a/patches/ctpp2_fix-static-libname.patch b/kiwixbuild/patches/ctpp2_fix-static-libname.patch similarity index 100% rename from patches/ctpp2_fix-static-libname.patch rename to kiwixbuild/patches/ctpp2_fix-static-libname.patch diff --git a/patches/ctpp2_iconv_support.patch b/kiwixbuild/patches/ctpp2_iconv_support.patch similarity index 100% rename from patches/ctpp2_iconv_support.patch rename to kiwixbuild/patches/ctpp2_iconv_support.patch diff --git a/patches/ctpp2_include.patch b/kiwixbuild/patches/ctpp2_include.patch similarity index 100% rename from patches/ctpp2_include.patch rename to kiwixbuild/patches/ctpp2_include.patch diff --git a/patches/ctpp2_mingw32.patch b/kiwixbuild/patches/ctpp2_mingw32.patch similarity index 100% rename from patches/ctpp2_mingw32.patch rename to kiwixbuild/patches/ctpp2_mingw32.patch diff --git a/patches/ctpp2_no_src_modification.patch b/kiwixbuild/patches/ctpp2_no_src_modification.patch similarity index 100% rename from patches/ctpp2_no_src_modification.patch rename to kiwixbuild/patches/ctpp2_no_src_modification.patch diff --git a/patches/ctpp2_win_install_lib_in_lib_dir.patch b/kiwixbuild/patches/ctpp2_win_install_lib_in_lib_dir.patch similarity index 100% rename from patches/ctpp2_win_install_lib_in_lib_dir.patch rename to kiwixbuild/patches/ctpp2_win_install_lib_in_lib_dir.patch diff --git a/patches/icu4c_android_elf64_st_info.patch b/kiwixbuild/patches/icu4c_android_elf64_st_info.patch similarity index 100% rename from patches/icu4c_android_elf64_st_info.patch rename to kiwixbuild/patches/icu4c_android_elf64_st_info.patch diff --git a/patches/icu4c_custom_data.patch b/kiwixbuild/patches/icu4c_custom_data.patch similarity index 100% rename from patches/icu4c_custom_data.patch rename to kiwixbuild/patches/icu4c_custom_data.patch diff --git a/patches/icu4c_fix_static_lib_name_mingw.patch b/kiwixbuild/patches/icu4c_fix_static_lib_name_mingw.patch similarity index 100% rename from patches/icu4c_fix_static_lib_name_mingw.patch rename to kiwixbuild/patches/icu4c_fix_static_lib_name_mingw.patch diff --git a/patches/icu4c_noxlocale.patch b/kiwixbuild/patches/icu4c_noxlocale.patch similarity index 100% rename from patches/icu4c_noxlocale.patch rename to kiwixbuild/patches/icu4c_noxlocale.patch diff --git a/patches/libaria2_android.patch b/kiwixbuild/patches/libaria2_android.patch similarity index 100% rename from patches/libaria2_android.patch rename to kiwixbuild/patches/libaria2_android.patch diff --git a/patches/pugixml_meson.patch b/kiwixbuild/patches/pugixml_meson.patch similarity index 100% rename from patches/pugixml_meson.patch rename to kiwixbuild/patches/pugixml_meson.patch diff --git a/patches/zlib_std_libname.patch b/kiwixbuild/patches/zlib_std_libname.patch similarity index 100% rename from patches/zlib_std_libname.patch rename to kiwixbuild/patches/zlib_std_libname.patch diff --git a/templates/bash_wrapper.sh b/kiwixbuild/templates/bash_wrapper.sh similarity index 100% rename from templates/bash_wrapper.sh rename to kiwixbuild/templates/bash_wrapper.sh diff --git a/templates/cmake_android_cross_file.txt b/kiwixbuild/templates/cmake_android_cross_file.txt similarity index 100% rename from templates/cmake_android_cross_file.txt rename to kiwixbuild/templates/cmake_android_cross_file.txt diff --git a/templates/cmake_cross_file.txt b/kiwixbuild/templates/cmake_cross_file.txt similarity index 100% rename from templates/cmake_cross_file.txt rename to kiwixbuild/templates/cmake_cross_file.txt diff --git a/templates/meson_android_cross_file.txt b/kiwixbuild/templates/meson_android_cross_file.txt similarity index 100% rename from templates/meson_android_cross_file.txt rename to kiwixbuild/templates/meson_android_cross_file.txt diff --git a/templates/meson_cross_file.txt b/kiwixbuild/templates/meson_cross_file.txt similarity index 100% rename from templates/meson_cross_file.txt rename to kiwixbuild/templates/meson_cross_file.txt diff --git a/kiwixbuild/toolchains/__init__.py b/kiwixbuild/toolchains/__init__.py new file mode 100644 index 0000000..fcfee2f --- /dev/null +++ b/kiwixbuild/toolchains/__init__.py @@ -0,0 +1,4 @@ + +from . import android_ndk, android_sdk, armhf, ios, mingw32 + +from .base_toolchain import Toolchain diff --git a/kiwixbuild/toolchains/android_ndk.py b/kiwixbuild/toolchains/android_ndk.py new file mode 100644 index 0000000..dfd8d28 --- /dev/null +++ b/kiwixbuild/toolchains/android_ndk.py @@ -0,0 +1,133 @@ +import os + +from .base_toolchain import Toolchain +from kiwixbuild.dependency_utils import ReleaseDownload, Builder +from kiwixbuild.utils import Remotefile, add_execution_right + +pj = os.path.join + +class android_ndk(Toolchain): + name = 'android-ndk' + version = 'r13b' + gccver = '4.9.x' + + @property + def api(self): + return '21' if self.arch in ('arm64', 'mips64', 'x86_64') else '14' + + @property + def platform(self): + return 'android-'+self.api + + @property + def arch(self): + return self.buildEnv.platform_info.arch + + @property + def arch_full(self): + return self.buildEnv.platform_info.arch_full + + @property + def toolchain(self): + return self.arch_full+"-4.9" + + @property + def root_path(self): + return pj(self.builder.install_path, 'sysroot') + + @property + def binaries(self): + binaries = ((k,'{}-{}'.format(self.arch_full, v)) + for k, v in (('CC', 'gcc'), + ('CXX', 'g++'), + ('AR', 'ar'), + ('STRIP', 'strip'), + ('WINDRES', 'windres'), + ('RANLIB', 'ranlib'), + ('LD', 'ld')) + ) + return {k:pj(self.builder.install_path, 'bin', v) + for k,v in binaries} + + @property + def configure_option(self): + return '--host={}'.format(self.arch_full) + + @property + def full_name(self): + return "{name}-{version}-{arch}-{api}".format( + name = self.name, + version = self.version, + arch = self.arch, + api = self.api) + + class Source(ReleaseDownload): + archive = Remotefile('android-ndk-r13b-linux-x86_64.zip', + '3524d7f8fca6dc0d8e7073a7ab7f76888780a22841a6641927123146c3ffd29c', + 'https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip') + + @property + def source_dir(self): + return "{}-{}".format( + self.target.name, + self.target.version) + + + class Builder(Builder): + + @property + def install_path(self): + return self.build_path + + def _build_platform(self, context): + context.try_skip(self.build_path) + script = pj(self.source_path, 'build/tools/make_standalone_toolchain.py') + add_execution_right(script) + command = '{script} --arch={arch} --api={api} --install-dir={install_dir} --force' + command = command.format( + script=script, + arch=self.target.arch, + api=self.target.api, + install_dir=self.install_path + ) + self.buildEnv.run_command(command, self.build_path, context) + + def _fix_permission_right(self, context): + context.try_skip(self.build_path) + bin_dirs = [pj(self.install_path, 'bin'), + pj(self.install_path, self.target.arch_full, 'bin'), + pj(self.install_path, 'libexec', 'gcc', self.target.arch_full, self.target.gccver) + ] + for root, dirs, files in os.walk(self.install_path): + if not root in bin_dirs: + continue + + for file_ in files: + file_path = pj(root, file_) + if os.path.islink(file_path): + continue + add_execution_right(file_path) + + def build(self): + self.command('build_platform', self._build_platform) + self.command('fix_permission_right', self._fix_permission_right) + + def get_bin_dir(self): + return [pj(self.builder.install_path, 'bin')] + + def set_env(self, env): + env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') + env['CFLAGS'] = '-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} '.format(self.root_path) + env['CFLAGS'] + env['CXXFLAGS'] = '-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} '.format(self.root_path) + env['CXXFLAGS'] + env['LDFLAGS'] = '--sysroot={} '.format(self.root_path) + env['LDFLAGS'] + #env['CFLAGS'] = ' -fPIC -D_FILE_OFFSET_BITS=64 -O3 '+env['CFLAGS'] + #env['CXXFLAGS'] = (' -D__OPTIMIZE__ -fno-strict-aliasing ' + # ' -DU_HAVE_NL_LANGINFO_CODESET=0 ' + # '-DU_STATIC_IMPLEMENTATION -O3 ' + # '-DU_HAVE_STD_STRING -DU_TIMEZONE=0 ')+env['CXXFLAGS'] + env['NDK_DEBUG'] = '0' + + def set_compiler(self, env): + env['CC'] = self.binaries['CC'] + env['CXX'] = self.binaries['CXX'] + diff --git a/kiwixbuild/toolchains/android_sdk.py b/kiwixbuild/toolchains/android_sdk.py new file mode 100644 index 0000000..d96fa40 --- /dev/null +++ b/kiwixbuild/toolchains/android_sdk.py @@ -0,0 +1,57 @@ +import os +import shutil + +from .base_toolchain import Toolchain +from kiwixbuild.dependency_utils import ReleaseDownload, Builder +from kiwixbuild.utils import Remotefile + +pj = os.path.join + +class android_sdk(Toolchain): + name = 'android-sdk' + version = 'r25.2.3' + + class Source(ReleaseDownload): + archive = Remotefile('tools_r25.2.3-linux.zip', + '1b35bcb94e9a686dff6460c8bca903aa0281c6696001067f34ec00093145b560', + 'https://dl.google.com/android/repository/tools_r25.2.3-linux.zip') + + class Builder(Builder): + + @property + def install_path(self): + return pj(self.buildEnv.toolchain_dir, self.target.full_name) + + def _build_platform(self, context): + context.try_skip(self.install_path) + tools_dir = pj(self.install_path, 'tools') + shutil.copytree(self.source_path, tools_dir) + script = pj(tools_dir, 'android') + command = '{script} --verbose update sdk -a --no-ui --filter {packages}' + command = command.format( + script=script, + packages = ','.join(str(i) for i in [1,2,8,34,162]) + ) + # packages correspond to : + # - 1 : Android SDK Tools, revision 25.2.5 + # - 2 : Android SDK Platform-tools, revision 25.0.3 + # - 8 : Android SDK Build-tools, revision 24.0.1 + # - 34 : SDK Platform Android 7.0, API 24, revision 2 + # - 162 : Android Support Repository, revision 44 + self.buildEnv.run_command(command, self.install_path, context, input="y\n") + + def _fix_licenses(self, context): + context.try_skip(self.install_path) + os.makedirs(pj(self.install_path, 'licenses'), exist_ok=True) + with open(pj(self.install_path, 'licenses', 'android-sdk-license'), 'w') as f: + f.write("\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e") + + def build(self): + self.command('build_platform', self._build_platform) + self.command('fix_licenses', self._fix_licenses) + + def get_bin_dir(self): + return [] + + def set_env(self, env): + env['ANDROID_HOME'] = self.builder.install_path diff --git a/kiwixbuild/toolchains/armhf.py b/kiwixbuild/toolchains/armhf.py new file mode 100644 index 0000000..e83a526 --- /dev/null +++ b/kiwixbuild/toolchains/armhf.py @@ -0,0 +1,66 @@ +import os +import subprocess + +from .base_toolchain import Toolchain +from kiwixbuild.dependency_utils import GitClone +from kiwixbuild.utils import Remotefile, which +pj = os.path.join + +class armhf_toolchain(Toolchain): + name = 'armhf' + arch_full = 'arm-linux-gnueabihf' + + class Source(GitClone): + git_remote = "https://github.com/raspberrypi/tools" + git_dir = "raspberrypi-tools" + + @property + def root_path(self): + return pj(self.source_path, 'arm-bcm2708', 'gcc-linaro-arm-linux-gnueabihf-raspbian-x64') + + @property + def binaries(self): + binaries = ((k,'{}-{}'.format(self.arch_full, v)) + for k, v in (('CC', 'gcc'), + ('CXX', 'g++'), + ('AR', 'ar'), + ('STRIP', 'strip'), + ('WINDRES', 'windres'), + ('RANLIB', 'ranlib'), + ('LD', 'ld')) + ) + return {k:pj(self.root_path, 'bin', v) + for k,v in binaries} + + @property + def exec_wrapper_def(self): + try: + which('qemu-arm') + except subprocess.CalledProcessError: + return "" + else: + return "exec_wrapper = 'qemu-arm'" + + @property + def configure_option(self): + return '--host={}'.format(self.arch_full) + + def get_bin_dir(self): + return [pj(self.root_path, 'bin')] + + def set_env(self, env): + env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') + env['CFLAGS'] = " -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CFLAGS'] + env['CXXFLAGS'] = " -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CXXFLAGS'] + env['LIBS'] = " ".join(self.buildEnv.cross_config['extra_libs']) + " " +env['LIBS'] + env['QEMU_LD_PREFIX'] = pj(self.root_path, "arm-linux-gnueabihf", "libc") + env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format( + ':'.join([ + pj(self.root_path, "arm-linux-gnueabihf", "lib"), + pj(self.buildEnv.install_dir, 'lib'), + pj(self.buildEnv.install_dir, self.buildEnv.libprefix) + ])) + + def set_compiler(self, env): + env['CC'] = self.binaries['CC'] + env['CXX'] = self.binaries['CXX'] diff --git a/kiwixbuild/toolchains/base_toolchain.py b/kiwixbuild/toolchains/base_toolchain.py new file mode 100644 index 0000000..0396a51 --- /dev/null +++ b/kiwixbuild/toolchains/base_toolchain.py @@ -0,0 +1,70 @@ +import os +import subprocess + +pj = os.path.join + +from kiwixbuild.utils import Context, SkipCommand, StopBuild + +class _MetaToolchain(type): + def __new__(cls, name, bases, dct): + _class = type.__new__(cls, name, bases, dct) + if name != 'Toolchain': + Toolchain.all_toolchains[name] = _class + return _class + + +class Toolchain(metaclass=_MetaToolchain): + all_toolchains = {} + configure_option = "" + cmake_option = "" + exec_wrapper_def = "" + Builder = None + Source = None + + def __init__(self, buildEnv): + self.buildEnv = buildEnv + self.source = self.Source(self) if self.Source else None + self.builder = self.Builder(self) if self.Builder else None + + @property + def full_name(self): + return "{name}-{version}".format( + name = self.name, + version = self.version) + + @property + def source_path(self): + return pj(self.buildEnv.source_dir, self.source.source_dir) + + @property + def _log_dir(self): + return self.buildEnv.log_dir + + def set_env(self, env): + pass + + def set_compiler(self, env): + pass + + def command(self, name, function, *args): + print(" {} {} : ".format(name, self.name), end="", flush=True) + log = pj(self._log_dir, 'cmd_{}_{}.log'.format(name, self.name)) + context = Context(name, log, True) + try: + ret = function(*args, context=context) + context._finalise() + print("OK") + return ret + except SkipCommand: + print("SKIP") + except subprocess.CalledProcessError: + print("ERROR") + try: + with open(log, 'r') as f: + print(f.read()) + except: + pass + raise StopBuild() + except: + print("ERROR") + raise diff --git a/kiwixbuild/toolchains/ios.py b/kiwixbuild/toolchains/ios.py new file mode 100644 index 0000000..16dd655 --- /dev/null +++ b/kiwixbuild/toolchains/ios.py @@ -0,0 +1,4 @@ +from .base_toolchain import Toolchain + +class iOS_sdk(Toolchain): + pass diff --git a/kiwixbuild/toolchains/mingw32.py b/kiwixbuild/toolchains/mingw32.py new file mode 100644 index 0000000..c27555c --- /dev/null +++ b/kiwixbuild/toolchains/mingw32.py @@ -0,0 +1,51 @@ +import os +import subprocess + +from .base_toolchain import Toolchain +from kiwixbuild.utils import which + +pj = os.path.join + +class mingw32_toolchain(Toolchain): + name = 'mingw32' + arch_full = 'i686-w64-mingw32' + + @property + def root_path(self): + return self.buildEnv.cross_config['root_path'] + + @property + def binaries(self): + return {k:which('{}-{}'.format(self.arch_full, v)) + for k, v in (('CC', 'gcc'), + ('CXX', 'g++'), + ('AR', 'ar'), + ('STRIP', 'strip'), + ('WINDRES', 'windres'), + ('RANLIB', 'ranlib')) + } + + @property + def exec_wrapper_def(self): + try: + which('wine') + except subprocess.CalledProcessError: + return "" + else: + return "exec_wrapper = 'wine'" + + + @property + def configure_option(self): + return '--host={}'.format(self.arch_full) + + def get_bin_dir(self): + return [pj(self.root_path, 'bin')] + + def set_env(self, env): + env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') + env['LIBS'] = " ".join(self.buildEnv.cross_config['extra_libs']) + " " +env['LIBS'] + + def set_compiler(self, env): + for k, v in self.binaries.items(): + env[k] = v diff --git a/utils.py b/kiwixbuild/utils.py similarity index 97% rename from utils.py rename to kiwixbuild/utils.py index e5e9718..6c7e6eb 100644 --- a/utils.py +++ b/kiwixbuild/utils.py @@ -6,6 +6,7 @@ import shutil import os, stat, sys import urllib import ssl +import subprocess from collections import namedtuple, defaultdict pj = os.path.join @@ -15,6 +16,12 @@ g_print_progress = True REMOTE_PREFIX = 'http://download.kiwix.org/dev/' +def which(name): + command = "which {}".format(name) + output = subprocess.check_output(command, shell=True) + return output[:-1].decode() + + def setup_print_progress(print_progress): global g_print_progress g_print_progress = print_progress @@ -63,6 +70,7 @@ def add_execution_right(file_path): current_permissions = stat.S_IMODE(os.lstat(file_path).st_mode) os.chmod(file_path, current_permissions | stat.S_IXUSR) + def copy_tree(src, dst, post_copy_function=None): os.makedirs(dst, exist_ok=True) for root, dirs, files in os.walk(src): @@ -152,6 +160,7 @@ class Context: def extract_archive(archive_path, dest_dir, topdir=None, name=None): is_zip_archive = archive_path.endswith('.zip') + archive = None try: if is_zip_archive: archive = zipfile.ZipFile(archive_path) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..514324a --- /dev/null +++ b/setup.py @@ -0,0 +1,42 @@ +from setuptools import setup, find_packages +from codecs import open # To use a consistent encoding +from os import path + +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the relevant file +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() + +# Doc: http://pythonhosted.org/setuptools/setuptools.html#including-data-files. +setup( + name='kiwix-build', + version="0.1", + description=('A tool to build kiwix and openzim projects.'), + long_description=long_description, + url='https://github.com/kiwix/kiwix-build/', + author='Matthieu Gautier', + author_email='mgautier@kymeria.fr', + license='GPLv3', + + # See https://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[ + 'Development Status :: 3 - Alpha', + + # Indicate who your project is intended for + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Build Tools', + + # Specify the Python versions you support here. In particular, ensure + # that you indicate whether you support Python 2, Python 3 or both. + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + ], + packages=find_packages(), + include_package_data=True, + entry_points={ + 'console_scripts': [ + 'kiwix-build = kiwixbuild:main' + ] + } +) From 6ebd96c05994123c8858a4593ed08eb2dd1213cc Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Wed, 4 Apr 2018 15:20:40 +0200 Subject: [PATCH 2/3] Adapte travis to new file architectures. - kiwix-build is installable, so let's install it in travisCI - Declare the dependency to meson in the setup.py - As kiwixbuild is installed, we don't need to change the `sys.path` --- setup.py | 3 +++ travis/compile_all.py | 5 ++--- travis/install_extra_deps.sh | 8 +++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 514324a..3c238ed 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,9 @@ setup( ], packages=find_packages(), include_package_data=True, + install_requires=[ + 'meson==0.43.0' + ], entry_points={ 'console_scripts': [ 'kiwix-build = kiwixbuild:main' diff --git a/travis/compile_all.py b/travis/compile_all.py index 6c809ac..047bfe4 100755 --- a/travis/compile_all.py +++ b/travis/compile_all.py @@ -11,8 +11,7 @@ import re from urllib.request import urlretrieve from urllib.error import URLError -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -import dependency_versions +from kiwixbuild import dependency_versions PLATFORM = environ['PLATFORM'] @@ -56,7 +55,7 @@ Generated at {date} def run_kiwix_build(target, platform, build_deps_only=False, make_release=False, make_dist=False): - command = [str(Path(environ['TRAVIS_BUILD_DIR'])/'kiwix-build.py')] + command = ['kiwix-build'] command.append(target) command.append('--hide-progress') command.extend(['--target-platform', platform]) diff --git a/travis/install_extra_deps.sh b/travis/install_extra_deps.sh index 107021a..f9e8489 100755 --- a/travis/install_extra_deps.sh +++ b/travis/install_extra_deps.sh @@ -2,15 +2,13 @@ set -e -orig_dir=$(pwd) - pip3 install --user --upgrade pip wheel -pip3 install --user pillow meson==0.43.0 +pip3 install --user pillow + +pip3 install --user . # ninja wget https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip unzip ninja-linux.zip ninja cp ninja $HOME/bin -cd $orig_dir - From 72002c8f34251a30780546380fae554146f71288 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Wed, 4 Apr 2018 18:06:36 +0200 Subject: [PATCH 3/3] Update README.md --- README.md | 71 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 7c41577..b7011ad 100644 --- a/README.md +++ b/README.md @@ -20,58 +20,62 @@ Before anything else you need to install Python3 related tools. On Debian based systems: ``` -sudo apt-get install python3-pip virtualenv +$ sudo apt-get install python3-pip virtualenv ``` -Then install Meson: +Create a virtual environment to install python module in it instead +of modifying the system. ``` -virtualenv -p python3 ./ # Create virtualenv -source bin/activate # Activate the virtualenv -pip3 install meson # Install Meson -hash -r # Refresh bash paths +$ virtualenv -p python3 ./ # Create virtualenv +$ source bin/activate # Activate the virtualenv ``` -Finally we need the Ninja tool (available in the $PATH). Here is a -solution to download, build and install it locally: +Then, download and install kiwix-build and its dependencies: +``` +$ git clone git://github.com/kiwix/kiwix-build.git +$ cd kiwix-build +$ pip install . +$ hash -r # Refresh bash paths +``` + +If your distribution doesn't provide ninja version > 1.6 you can get it +this way : ``` -git clone git://github.com/ninja-build/ninja.git -cd ninja -git checkout release -./configure.py --bootstrap -mkdir ../bin -cp ninja ../bin -cd .. +$ wget https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip +$ unzip ninja-linux.zip ninja -d $HOME/bin ``` # Compilation -The compilation is handled by `kiwix-build.py`. It will compile +The compilation is handled by the `kiwix-build` command. It will compile everything. If you are using a supported platform (Redhat or Debian based) it will install missing packages using `sudo`. You can get -`kiwix-build.py` usage like this: +`kiwix-build` usage like this: ``` -./kiwix-build.py -h +$ kiwix-build --help ``` ## Target -By default, `kiwix-build.py` will build `kiwix-tools`. If you want to -compile another target only (let's said kiwixlib), you can specify it: +You may want to compile a specific target so you will have to specify it on the +command line : ``` -./kiwix-build Kiwixlib +$ kiwix-build kiwix-lib # will build kiwix-build and its dependencies +$ kiwix-build zim-tools # will build zim-tools and its dependencies ``` +By default, `kiwix-build` will build `kiwix-tools` . + ## Target platform -By default, `kiwix-build.py` will build everything for the current (native) -platform using dynamic linkage (hence the `native_dyn` of the -BUILD_native_dyn directory). +By default, `kiwix-build` will build everything for the current (native) +platform using dynamic linkage (`native_dyn`). But you can select another target platform using the option -`target-platform`. For now, there is ten different supported +`--target-platform`. For now, there is ten different supported platforms : - native_dyn @@ -85,10 +89,15 @@ platforms : - android_x86 - android_x86_64 -So, if you want to compile for win32 using static linkage: +So, if you want to compile `kiwix-tools` for win32 using static linkage: ``` -./kiwix-build.py --target-platform win32_dyn +$ kiwix-build --target-platform win32_dyn +``` + +Or, android apk for android_arm : +``` +$ kiwix-build --target-platform android_arm kiwix-android ``` # Outputs @@ -96,9 +105,9 @@ So, if you want to compile for win32 using static linkage: Kiwix-build.py will create several directories: - `ARCHIVES`: All the downloaded archives go there. - `SOURCES`: All the sources (extracted from archives and patched) go there. -- `BUILD_native_dyn`: All the build files go there. -- `BUILD_native_dyn/INSTALL`: The installed files go there. -- `BUILD_native_dyn/LOGS`: The logs files of the build. +- `BUILD_`: All the build files go there. +- `BUILD_/INSTALL`: The installed files go there. +- `BUILD_/LOGS`: The logs files of the build. If you want to install all those directories elsewhere, you can pass the -`--working-dir` option to `kiwix-build.py`: +`--working-dir` option to `kiwix-build`: