Format our code with black

This commit is contained in:
Matthieu Gautier 2024-02-05 11:41:09 +01:00
parent 939f323709
commit 5a1175cf2d
51 changed files with 1916 additions and 1518 deletions

View File

@ -9,76 +9,141 @@ from .builder import Builder
from .flatpak_builder import FlatpakBuilder from .flatpak_builder import FlatpakBuilder
from . import _global from . import _global
def parse_args(): def parse_args():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('target', default='kiwix-tools', nargs='?', metavar='TARGET', parser.add_argument(
choices=Dependency.all_deps.keys()) "target",
parser.add_argument('--working-dir', default=".", default="kiwix-tools",
help=("Directory where kiwix-build puts all its files " nargs="?",
"(source, archive and build)\n" metavar="TARGET",
"working-dir can be absolute path or a relative (to cwd) one.")) choices=Dependency.all_deps.keys(),
parser.add_argument('--build-dir', default=".", )
help=("Directory where kiwix-build puts all build files.\n" parser.add_argument(
"build-dir can be absolute path or a relative (to working-dir) one.")) "--working-dir",
parser.add_argument('--libprefix', default=None) default=".",
parser.add_argument('--target-platform', choices=PlatformInfo.all_platforms) help=(
parser.add_argument('--verbose', '-v', action="store_true", "Directory where kiwix-build puts all its files "
help=("Print all logs on stdout instead of in specific" "(source, archive and build)\n"
" log files per commands")) "working-dir can be absolute path or a relative (to cwd) one."
parser.add_argument('--hide-progress', action='store_false', dest='show_progress', ),
help="Hide intermediate progress information.") )
parser.add_argument('--skip-source-prepare', action='store_true', parser.add_argument(
help="Skip the source download part") "--build-dir",
parser.add_argument('--build-deps-only', action='store_true', default=".",
help="Build only the dependencies of the specified target.") help=(
parser.add_argument('--build-nodeps', action='store_true', "Directory where kiwix-build puts all build files.\n"
help="Build only the target, not its dependencies.") "build-dir can be absolute path or a relative (to working-dir) one."
parser.add_argument('--make-dist', action='store_true', ),
help="Build distrubution (dist) source archive") )
parser.add_argument('--make-release', action='store_true', parser.add_argument("--libprefix", default=None)
help="Build a release version") parser.add_argument("--target-platform", choices=PlatformInfo.all_platforms)
subgroup = parser.add_argument_group('advanced') parser.add_argument(
subgroup.add_argument('--no-cert-check', action='store_true', "--verbose",
help="Skip SSL certificate verification during download") "-v",
subgroup.add_argument('--clean-at-end', action='store_true', action="store_true",
help="Clean all intermediate files after the (successfull) build") help=(
subgroup.add_argument('--dont-install-packages', action='store_true', "Print all logs on stdout instead of in specific" " log files per commands"
help="Do not try to install packages before compiling") ),
subgroup.add_argument('--assume-packages-installed', action='store_true', )
help="Assume the package to install to be aleady installed") parser.add_argument(
subgroup.add_argument('--android-arch', action='append', "--hide-progress",
help=("Specify the architecture to build for android application/libraries.\n" action="store_false",
"Can be specified several times to build for several architectures.\n" dest="show_progress",
"If not specified, all architectures will be build.")) help="Hide intermediate progress information.",
subgroup.add_argument('--ios-arch', action='append', )
help=("Specify the architecture to build for ios application/libraries.\n" parser.add_argument(
"Can be specified several times to build for several architectures.\n" "--skip-source-prepare",
"If not specified, all architectures will be build.")) action="store_true",
subgroup.add_argument('--fast-clone', action='store_true', help="Skip the source download part",
help=("Do not clone the whole repository.\n" )
"This is useful for one shot build but it is not recommended if you want " parser.add_argument(
"to develop with the cloned sources.")) "--build-deps-only",
action="store_true",
help="Build only the dependencies of the specified target.",
)
parser.add_argument(
"--build-nodeps",
action="store_true",
help="Build only the target, not its dependencies.",
)
parser.add_argument(
"--make-dist",
action="store_true",
help="Build distrubution (dist) source archive",
)
parser.add_argument(
"--make-release", action="store_true", help="Build a release version"
)
subgroup = parser.add_argument_group("advanced")
subgroup.add_argument(
"--no-cert-check",
action="store_true",
help="Skip SSL certificate verification during download",
)
subgroup.add_argument(
"--clean-at-end",
action="store_true",
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(
"--assume-packages-installed",
action="store_true",
help="Assume the package to install to be aleady installed",
)
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.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.add_argument(
"--fast-clone",
action="store_true",
help=(
"Do not clone the whole repository.\n"
"This is useful for one shot build but it is not recommended if you want "
"to develop with the cloned sources."
),
)
options = parser.parse_args() options = parser.parse_args()
if not options.android_arch: if not options.android_arch:
options.android_arch = ['arm', 'arm64', 'x86', 'x86_64'] options.android_arch = ["arm", "arm64", "x86", "x86_64"]
if not options.ios_arch: if not options.ios_arch:
options.ios_arch = ['arm64', 'x86_64'] options.ios_arch = ["arm64", "x86_64"]
if not options.target_platform: if not options.target_platform:
options.target_platform = 'native_dyn' options.target_platform = "native_dyn"
return options return options
def main(): def main():
options = parse_args() options = parse_args()
options.working_dir = os.path.abspath(options.working_dir) options.working_dir = os.path.abspath(options.working_dir)
_global.set_options(options) _global.set_options(options)
neutralEnv = buildenv.PlatformNeutralEnv() neutralEnv = buildenv.PlatformNeutralEnv()
_global.set_neutralEnv(neutralEnv) _global.set_neutralEnv(neutralEnv)
if options.target_platform == 'flatpak': if options.target_platform == "flatpak":
builder = FlatpakBuilder() builder = FlatpakBuilder()
else: else:
builder = Builder() builder = Builder()
builder.run() builder.run()

View File

@ -5,23 +5,29 @@ _neutralEnv = None
_options = None _options = None
_target_steps = _OrderedDict() _target_steps = _OrderedDict()
def set_neutralEnv(env): def set_neutralEnv(env):
global _neutralEnv global _neutralEnv
_neutralEnv = env _neutralEnv = env
def neutralEnv(what): def neutralEnv(what):
return getattr(_neutralEnv, what) return getattr(_neutralEnv, what)
def set_options(options): def set_options(options):
global _options global _options
_options = options _options = options
def option(what): def option(what):
return getattr(_options, what) return getattr(_options, what)
def add_target_step(key, what): def add_target_step(key, what):
_target_steps[key] = what _target_steps[key] = what
def get_target_step(key, default_context=None): def get_target_step(key, default_context=None):
if isinstance(key, tuple): if isinstance(key, tuple):
context, target = key context, target = key
@ -29,6 +35,7 @@ def get_target_step(key, default_context=None):
context, target = default_context, key context, target = default_context, key
return _target_steps[(context, target)] return _target_steps[(context, target)]
def target_steps(): def target_steps():
return _target_steps return _target_steps
@ -39,14 +46,15 @@ def backend():
return _backend return _backend
_platform = platform.system() _platform = platform.system()
if _platform == 'Windows': if _platform == "Windows":
print('ERROR: kiwix-build is not intented to run on Windows platform.\n' print(
'There is no backend for Windows, so we can\'t launch any commands.') "ERROR: kiwix-build is not intented to run on Windows platform.\n"
"There is no backend for Windows, so we can't launch any commands."
)
sys.exit(0) sys.exit(0)
if _platform == 'Linux': if _platform == "Linux":
_platform, _, _ = platform.linux_distribution() _platform, _, _ = platform.linux_distribution()
_platform = _platform.lower() _platform = _platform.lower()
_backend = backends.Linux() _backend = backends.Linux()
return _backend return _backend

View File

@ -1,4 +1,3 @@
import os, sys, shutil import os, sys, shutil
import subprocess import subprocess
import platform import platform
@ -10,60 +9,58 @@ from ._global import neutralEnv, option
class PlatformNeutralEnv: class PlatformNeutralEnv:
def __init__(self): def __init__(self):
self.working_dir = option('working_dir') self.working_dir = option("working_dir")
self.source_dir = pj(self.working_dir, "SOURCE") self.source_dir = pj(self.working_dir, "SOURCE")
self.archive_dir = pj(self.working_dir, "ARCHIVE") self.archive_dir = pj(self.working_dir, "ARCHIVE")
self.toolchain_dir = pj(self.working_dir, "TOOLCHAINS") self.toolchain_dir = pj(self.working_dir, "TOOLCHAINS")
self.log_dir = pj(self.working_dir, 'LOGS') self.log_dir = pj(self.working_dir, "LOGS")
for d in (self.source_dir, for d in (self.source_dir, self.archive_dir, self.toolchain_dir, self.log_dir):
self.archive_dir,
self.toolchain_dir,
self.log_dir):
os.makedirs(d, exist_ok=True) os.makedirs(d, exist_ok=True)
self.detect_platform() self.detect_platform()
self.ninja_command = self._detect_command( self.ninja_command = self._detect_command(
'ninja', "ninja", default=[["ninja"], ["ninja-build"]]
default=[['ninja'], ['ninja-build']]) )
self.meson_command = self._detect_command( self.meson_command = self._detect_command(
'meson', "meson", default=[["meson.py"], ["meson"]]
default= [['meson.py'], ['meson']]) )
self.mesontest_command = [*self.meson_command, "test"] self.mesontest_command = [*self.meson_command, "test"]
self.patch_command = self._detect_command('patch') self.patch_command = self._detect_command("patch")
self.git_command = self._detect_command('git') self.git_command = self._detect_command("git")
self.make_command = self._detect_command('make') self.make_command = self._detect_command("make")
self.cmake_command = self._detect_command('cmake') self.cmake_command = self._detect_command("cmake")
self.qmake_command = self._detect_command('qmake', required=False) self.qmake_command = self._detect_command("qmake", required=False)
def detect_platform(self): def detect_platform(self):
_platform = platform.system() _platform = platform.system()
self.distname = _platform self.distname = _platform
if _platform == 'Windows': if _platform == "Windows":
print('ERROR: kiwix-build is not intented to run on Windows platform.\n' print(
'It should probably not work, but well, you still can have a try.') "ERROR: kiwix-build is not intented to run on Windows platform.\n"
cont = input('Do you want to continue ? [y/N]') "It should probably not work, but well, you still can have a try."
if cont.lower() != 'y': )
cont = input("Do you want to continue ? [y/N]")
if cont.lower() != "y":
sys.exit(0) sys.exit(0)
if _platform == 'Linux': if _platform == "Linux":
self.distname = distro.id() self.distname = distro.id()
if self.distname == 'ubuntu': if self.distname == "ubuntu":
self.distname = 'debian' self.distname = "debian"
def download(self, what, where=None): def download(self, what, where=None):
where = where or self.archive_dir where = where or self.archive_dir
download_remote(what, where) download_remote(what, where)
def _detect_command(self, name, default=None, options=["--version"], required=True):
def _detect_command(self, name, default=None, options=['--version'], required=True):
if default is None: if default is None:
default = [[name]] default = [[name]]
env_key = 'KBUILD_{}_COMMAND'.format(name.upper()) env_key = "KBUILD_{}_COMMAND".format(name.upper())
if env_key in os.environ: if env_key in os.environ:
default = [os.environ[env_key].split()] + default default = [os.environ[env_key].split()] + default
for command in default: for command in default:
try: try:
retcode = subprocess.check_call(command + options, retcode = subprocess.check_call(
stdout=subprocess.DEVNULL) command + options, stdout=subprocess.DEVNULL
)
except (FileNotFoundError, PermissionError, OSError): except (FileNotFoundError, PermissionError, OSError):
# Doesn't exist in PATH or isn't executable # Doesn't exist in PATH or isn't executable
continue continue
@ -76,22 +73,20 @@ class PlatformNeutralEnv:
print("WARNING: {} command not found".format(name)) print("WARNING: {} command not found".format(name))
return ["{}_NOT_FOUND".format(name.upper())] return ["{}_NOT_FOUND".format(name.upper())]
class BuildEnv: class BuildEnv:
def __init__(self, platformInfo): def __init__(self, platformInfo):
build_dir = "BUILD_{}".format(platformInfo.name) build_dir = "BUILD_{}".format(platformInfo.name)
self.platformInfo = platformInfo self.platformInfo = platformInfo
self.base_build_dir = pj(option('working_dir'), option('build_dir')) self.base_build_dir = pj(option("working_dir"), option("build_dir"))
self.build_dir = pj(self.base_build_dir, build_dir) self.build_dir = pj(self.base_build_dir, build_dir)
self.install_dir = pj(self.build_dir, "INSTALL") self.install_dir = pj(self.build_dir, "INSTALL")
self.toolchain_dir = pj(self.build_dir, "TOOLCHAINS") self.toolchain_dir = pj(self.build_dir, "TOOLCHAINS")
self.log_dir = pj(self.build_dir, 'LOGS') self.log_dir = pj(self.build_dir, "LOGS")
for d in (self.build_dir, for d in (self.build_dir, self.install_dir, self.toolchain_dir, self.log_dir):
self.install_dir,
self.toolchain_dir,
self.log_dir):
os.makedirs(d, exist_ok=True) os.makedirs(d, exist_ok=True)
self.libprefix = option('libprefix') or self._detect_libdir() self.libprefix = option("libprefix") or self._detect_libdir()
def clean_intermediate_directories(self): def clean_intermediate_directories(self):
for subdir in os.listdir(self.build_dir): for subdir in os.listdir(self.build_dir):
@ -104,69 +99,72 @@ class BuildEnv:
os.remove(subpath) os.remove(subpath)
def _is_debianlike(self): def _is_debianlike(self):
return os.path.isfile('/etc/debian_version') return os.path.isfile("/etc/debian_version")
def _detect_libdir(self): def _detect_libdir(self):
if self.platformInfo.libdir is not None: if self.platformInfo.libdir is not None:
return self.platformInfo.libdir return self.platformInfo.libdir
if self._is_debianlike(): if self._is_debianlike():
try: try:
pc = subprocess.Popen(['dpkg-architecture', '-qDEB_HOST_MULTIARCH'], pc = subprocess.Popen(
stdout=subprocess.PIPE, ["dpkg-architecture", "-qDEB_HOST_MULTIARCH"],
stderr=subprocess.DEVNULL) stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
)
(stdo, _) = pc.communicate() (stdo, _) = pc.communicate()
if pc.returncode == 0: if pc.returncode == 0:
archpath = stdo.decode().strip() archpath = stdo.decode().strip()
return 'lib/' + archpath return "lib/" + archpath
except Exception: except Exception:
pass pass
if os.path.isdir('/usr/lib64') and not os.path.islink('/usr/lib64'): if os.path.isdir("/usr/lib64") and not os.path.islink("/usr/lib64"):
return 'lib64' return "lib64"
return 'lib' return "lib"
def get_env(self, *, cross_comp_flags, cross_compilers, cross_path): def get_env(self, *, cross_comp_flags, cross_compilers, cross_path):
env = self.platformInfo.get_env() env = self.platformInfo.get_env()
pkgconfig_path = pj(self.install_dir, self.libprefix, 'pkgconfig') pkgconfig_path = pj(self.install_dir, self.libprefix, "pkgconfig")
env['PKG_CONFIG_PATH'] = ':'.join([env['PKG_CONFIG_PATH'], pkgconfig_path]) env["PKG_CONFIG_PATH"] = ":".join([env["PKG_CONFIG_PATH"], pkgconfig_path])
env['PATH'] = ':'.join([ env["PATH"] = ":".join([escape_path(pj(self.install_dir, "bin")), env["PATH"]])
escape_path(pj(self.install_dir, 'bin')),
env['PATH']
])
env['LD_LIBRARY_PATH'] = ':'.join([env['LD_LIBRARY_PATH'], env["LD_LIBRARY_PATH"] = ":".join(
pj(self.install_dir, 'lib'), [
pj(self.install_dir, self.libprefix) env["LD_LIBRARY_PATH"],
]) pj(self.install_dir, "lib"),
pj(self.install_dir, self.libprefix),
]
)
env['QMAKE_CXXFLAGS'] = " ".join([ env["QMAKE_CXXFLAGS"] = " ".join(
escape_path('-I'+pj(self.install_dir, 'include')), [escape_path("-I" + pj(self.install_dir, "include")), env["QMAKE_CXXFLAGS"]]
env['QMAKE_CXXFLAGS'] )
]) env["CPPFLAGS"] = " ".join(
env['CPPFLAGS'] = " ".join([ [escape_path("-I" + pj(self.install_dir, "include")), env["CPPFLAGS"]]
escape_path('-I'+pj(self.install_dir, 'include')), )
env['CPPFLAGS'] env["QMAKE_LFLAGS"] = " ".join(
]) [
env['QMAKE_LFLAGS'] = " ".join([ escape_path("-L" + pj(self.install_dir, "lib")),
escape_path('-L'+pj(self.install_dir, 'lib')), escape_path("-L" + pj(self.install_dir, self.libprefix)),
escape_path('-L'+pj(self.install_dir, self.libprefix)), env["QMAKE_LFLAGS"],
env['QMAKE_LFLAGS'] ]
]) )
env['LDFLAGS'] = " ".join([ env["LDFLAGS"] = " ".join(
escape_path('-L'+pj(self.install_dir, 'lib')), [
escape_path('-L'+pj(self.install_dir, self.libprefix)), escape_path("-L" + pj(self.install_dir, "lib")),
env['LDFLAGS'] escape_path("-L" + pj(self.install_dir, self.libprefix)),
]) env["LDFLAGS"],
]
)
if cross_comp_flags: if cross_comp_flags:
self.platformInfo.set_comp_flags(env) self.platformInfo.set_comp_flags(env)
if cross_compilers: if cross_compilers:
self.platformInfo.set_compiler(env) self.platformInfo.set_compiler(env)
if cross_path: if cross_path:
env['PATH'] = ':'.join(self.platformInfo.get_bin_dir() + [env['PATH']]) env["PATH"] = ":".join(self.platformInfo.get_bin_dir() + [env["PATH"]])
return env return env
@property @property
def configure_wrapper(self): def configure_wrapper(self):
try: try:

View File

@ -1,4 +1,3 @@
import sys import sys
from collections import OrderedDict from collections import OrderedDict
from .buildenv import * from .buildenv import *
@ -8,23 +7,32 @@ from .utils import remove_duplicates, StopBuild, colorize
from .dependencies import Dependency from .dependencies import Dependency
from .packages import PACKAGE_NAME_MAPPERS from .packages import PACKAGE_NAME_MAPPERS
from ._global import ( from ._global import (
neutralEnv, option, neutralEnv,
add_target_step, get_target_step, target_steps, option,
backend) add_target_step,
get_target_step,
target_steps,
backend,
)
from . import _global from . import _global
class Builder: class Builder:
def __init__(self): def __init__(self):
self._targets = {} self._targets = {}
PlatformInfo.get_platform('neutral', self._targets) PlatformInfo.get_platform("neutral", self._targets)
target_platform = option('target_platform') target_platform = option("target_platform")
platform = PlatformInfo.get_platform(target_platform, self._targets) platform = PlatformInfo.get_platform(target_platform, self._targets)
if neutralEnv('distname') not in platform.compatible_hosts: if neutralEnv("distname") not in platform.compatible_hosts:
print((colorize('ERROR')+': The target platform {} cannot be build on host {}.\n' print(
'Select another target platform or change your host system.' (
).format(platform.name, neutralEnv('distname'))) colorize("ERROR")
self.targetDefs = platform.add_targets(option('target'), self._targets) + ": 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)
def finalize_target_steps(self): def finalize_target_steps(self):
steps = [] steps = []
@ -32,19 +40,19 @@ class Builder:
steps += self.order_steps(targetDef) steps += self.order_steps(targetDef)
steps = list(remove_duplicates(steps)) steps = list(remove_duplicates(steps))
if option('build_nodeps'): if option("build_nodeps"):
# add all platform steps # add all platform steps
for dep in steps: for dep in steps:
stepClass = Dependency.all_deps[dep[1]] stepClass = Dependency.all_deps[dep[1]]
if stepClass.dont_skip: if stepClass.dont_skip:
add_target_step(dep, self._targets[dep]) add_target_step(dep, self._targets[dep])
src_targetDef = ('source', targetDef[1]) src_targetDef = ("source", targetDef[1])
add_target_step(src_targetDef, self._targets[src_targetDef]) add_target_step(src_targetDef, self._targets[src_targetDef])
add_target_step(targetDef, self._targets[targetDef]) add_target_step(targetDef, self._targets[targetDef])
else: else:
for dep in steps: for dep in steps:
if option('build_deps_only') and dep[1] == targetDef[1]: if option("build_deps_only") and dep[1] == targetDef[1]:
continue continue
add_target_step(dep, self._targets[dep]) add_target_step(dep, self._targets[dep])
self.instanciate_steps() self.instanciate_steps()
@ -54,14 +62,14 @@ class Builder:
plt = PlatformInfo.all_platforms[pltName] plt = PlatformInfo.all_platforms[pltName]
for tlcName in plt.toolchain_names: for tlcName in plt.toolchain_names:
tlc = Dependency.all_deps[tlcName] tlc = Dependency.all_deps[tlcName]
yield('source', tlcName) yield ("source", tlcName)
yield('neutral' if tlc.neutral else pltName, tlcName) yield ("neutral" if tlc.neutral else pltName, tlcName)
_targets =dict(self._targets) _targets = dict(self._targets)
yield from self.order_dependencies(targetDef, _targets) yield from self.order_dependencies(targetDef, _targets)
def order_dependencies(self, targetDef, targets): def order_dependencies(self, targetDef, targets):
targetPlatformName, targetName = targetDef targetPlatformName, targetName = targetDef
if targetPlatformName == 'source': if targetPlatformName == "source":
# Do not try to order sources, they will be added as dep by the # Do not try to order sources, they will be added as dep by the
# build step two lines later. # build step two lines later.
return return
@ -75,38 +83,40 @@ class Builder:
depPlatform, depName = targetPlatform.get_fully_qualified_dep(dep) depPlatform, depName = targetPlatform.get_fully_qualified_dep(dep)
if (depPlatform, depName) in targets: if (depPlatform, depName) in targets:
yield from self.order_dependencies((depPlatform, depName), targets) yield from self.order_dependencies((depPlatform, depName), targets)
yield ('source', targetName) yield ("source", targetName)
yield targetDef yield targetDef
def instanciate_steps(self): def instanciate_steps(self):
for stepDef in list(target_steps()): for stepDef in list(target_steps()):
stepPlatform, stepName = stepDef stepPlatform, stepName = stepDef
stepClass = Dependency.all_deps[stepName] stepClass = Dependency.all_deps[stepName]
if stepPlatform == 'source': if stepPlatform == "source":
source = get_target_step(stepDef)(stepClass) source = get_target_step(stepDef)(stepClass)
add_target_step(stepDef, source) add_target_step(stepDef, source)
else: else:
source = get_target_step(stepName, 'source') source = get_target_step(stepName, "source")
env = PlatformInfo.get_platform(stepPlatform).buildEnv env = PlatformInfo.get_platform(stepPlatform).buildEnv
builder = get_target_step(stepDef)(stepClass, source, env) builder = get_target_step(stepDef)(stepClass, source, env)
add_target_step(stepDef, builder) add_target_step(stepDef, builder)
def prepare_sources(self): def prepare_sources(self):
if option('skip_source_prepare'): if option("skip_source_prepare"):
print(colorize("SKIP")) print(colorize("SKIP"))
return return
sourceDefs = remove_duplicates(tDef for tDef in target_steps() if tDef[0]=='source') sourceDefs = remove_duplicates(
tDef for tDef in target_steps() if tDef[0] == "source"
)
for sourceDef in sourceDefs: for sourceDef in sourceDefs:
print("prepare sources {} :".format(sourceDef[1])) print("prepare sources {} :".format(sourceDef[1]))
source = get_target_step(sourceDef) source = get_target_step(sourceDef)
source.prepare() source.prepare()
def build(self): def build(self):
builderDefs = (tDef for tDef in target_steps() if tDef[0] != 'source') builderDefs = (tDef for tDef in target_steps() if tDef[0] != "source")
for builderDef in builderDefs: for builderDef in builderDefs:
builder = get_target_step(builderDef) builder = get_target_step(builderDef)
if option('make_dist') and builderDef[1] == option('target'): if option("make_dist") and builderDef[1] == option("target"):
print("make dist {} ({}):".format(builder.name, builderDef[0])) print("make dist {} ({}):".format(builder.name, builderDef[0]))
builder.make_dist() builder.make_dist()
continue continue
@ -118,17 +128,17 @@ class Builder:
packages_list = [] packages_list = []
for platform in PlatformInfo.all_running_platforms.values(): for platform in PlatformInfo.all_running_platforms.values():
mapper_name = "{host}_{target}".format( mapper_name = "{host}_{target}".format(
host=neutralEnv('distname'), host=neutralEnv("distname"), target=platform
target=platform) )
package_name_mapper = PACKAGE_NAME_MAPPERS.get(mapper_name, {}) package_name_mapper = PACKAGE_NAME_MAPPERS.get(mapper_name, {})
packages_list += package_name_mapper.get('COMMON', []) packages_list += package_name_mapper.get("COMMON", [])
to_drop = [] to_drop = []
for builderDef in self._targets: for builderDef in self._targets:
platformName, builderName = builderDef platformName, builderName = builderDef
mapper_name = "{host}_{target}".format( mapper_name = "{host}_{target}".format(
host=neutralEnv('distname'), host=neutralEnv("distname"), target=platformName
target=platformName) )
package_name_mapper = PACKAGE_NAME_MAPPERS.get(mapper_name, {}) package_name_mapper = PACKAGE_NAME_MAPPERS.get(mapper_name, {})
packages = package_name_mapper.get(builderName) packages = package_name_mapper.get(builderName)
if packages: if packages:
@ -144,20 +154,20 @@ class Builder:
packages_to_have = self._get_packages() packages_to_have = self._get_packages()
packages_to_have = remove_duplicates(packages_to_have) packages_to_have = remove_duplicates(packages_to_have)
if option('assume_packages_installed'): if option("assume_packages_installed"):
print(colorize("SKIP") + ", Assume package installed") print(colorize("SKIP") + ", Assume package installed")
return return
distname = neutralEnv('distname') distname = neutralEnv("distname")
if distname in ('fedora', 'redhat', 'centos'): if distname in ("fedora", "redhat", "centos"):
package_installer = 'sudo dnf install {}' package_installer = "sudo dnf install {}"
package_checker = 'rpm -q --quiet {}' package_checker = "rpm -q --quiet {}"
elif distname in ('debian', 'Ubuntu'): elif distname in ("debian", "Ubuntu"):
package_installer = 'sudo apt-get install {}' package_installer = "sudo apt-get install {}"
package_checker = 'LANG=C dpkg -s {} 2>&1 | grep Status | grep "ok installed" 1>/dev/null 2>&1' package_checker = 'LANG=C dpkg -s {} 2>&1 | grep Status | grep "ok installed" 1>/dev/null 2>&1'
elif distname == 'Darwin': elif distname == "Darwin":
package_installer = 'brew install {}' package_installer = "brew install {}"
package_checker = 'brew ls --version {} > /dev/null' package_checker = "brew ls --version {} > /dev/null"
packages_to_install = [] packages_to_install = []
for package in packages_to_have: for package in packages_to_have:
@ -176,12 +186,12 @@ class Builder:
print(command) print(command)
subprocess.check_call(command, shell=True) subprocess.check_call(command, shell=True)
else: else:
print(colorize("SKIP")+ ", No package to install.") print(colorize("SKIP") + ", No package to install.")
def run(self): def run(self):
try: try:
print("[INSTALL PACKAGES]") print("[INSTALL PACKAGES]")
if option('dont_install_packages'): if option("dont_install_packages"):
print(colorize("SKIP")) print(colorize("SKIP"))
else: else:
self.install_packages() self.install_packages()
@ -195,7 +205,7 @@ class Builder:
self.build() self.build()
# No error, clean intermediate file at end of build if needed. # No error, clean intermediate file at end of build if needed.
print("[CLEAN]") print("[CLEAN]")
if option('clean_at_end'): if option("clean_at_end"):
for platform in PlatformInfo.all_running_platforms.values(): for platform in PlatformInfo.all_running_platforms.values():
platform.clean_intermediate_directories() platform.clean_intermediate_directories()
else: else:
@ -203,4 +213,3 @@ class Builder:
except StopBuild as e: except StopBuild as e:
print(e) print(e)
sys.exit("Stopping build due to errors") sys.exit("Stopping build due to errors")

View File

@ -1,4 +1,3 @@
from .base import * from .base import *
from . import ( from . import (
all_dependencies, all_dependencies,
@ -28,5 +27,5 @@ from . import (
zim_tools, zim_tools,
zim_testing_suite, zim_testing_suite,
zlib, zlib,
zstd zstd,
) )

View File

@ -1,32 +1,45 @@
from os import environ from os import environ
from .base import ( from .base import Dependency, NoopSource, NoopBuilder
Dependency,
NoopSource,
NoopBuilder)
from kiwixbuild._global import neutralEnv from kiwixbuild._global import neutralEnv
class AllBaseDependencies(Dependency): class AllBaseDependencies(Dependency):
name = "alldependencies" name = "alldependencies"
Source = NoopSource Source = NoopSource
class Builder(NoopBuilder): class Builder(NoopBuilder):
@classmethod @classmethod
def get_dependencies(cls, platformInfo, allDeps): def get_dependencies(cls, platformInfo, allDeps):
if platformInfo.build == "wasm" or environ.get('OS_NAME') == 'bionic': if platformInfo.build == "wasm" or environ.get("OS_NAME") == "bionic":
return ['zlib', 'lzma', 'zstd', 'icu4c', 'xapian-core'] return ["zlib", "lzma", "zstd", "icu4c", "xapian-core"]
base_deps = ['zlib', 'lzma', 'zstd', 'xapian-core', 'pugixml', 'libcurl', 'icu4c', 'mustache', 'libmicrohttpd', 'zim-testing-suite'] base_deps = [
"zlib",
"lzma",
"zstd",
"xapian-core",
"pugixml",
"libcurl",
"icu4c",
"mustache",
"libmicrohttpd",
"zim-testing-suite",
]
# Add specific dependencies depending of the platform # Add specific dependencies depending of the platform
if platformInfo.build not in ('android', 'iOS'): if platformInfo.build not in ("android", "iOS"):
# For zimtools # For zimtools
base_deps += ['docoptcpp'] base_deps += ["docoptcpp"]
if platformInfo.build != 'win32': if platformInfo.build != "win32":
# zimwriterfs # zimwriterfs
base_deps += ['libmagic', 'gumbo'] base_deps += ["libmagic", "gumbo"]
if platformInfo.build == 'native' and neutralEnv('distname') != 'Darwin': if (
platformInfo.build == "native"
and neutralEnv("distname") != "Darwin"
):
# We compile kiwix-desktop only on native and not on `Darwin` # We compile kiwix-desktop only on native and not on `Darwin`
# So we need aria2 only there # So we need aria2 only there
base_deps += ['aria2'] base_deps += ["aria2"]
return base_deps return base_deps

View File

@ -1,18 +1,17 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder
)
from kiwixbuild.utils import Remotefile, run_command from kiwixbuild.utils import Remotefile, run_command
class Aria2(Dependency): class Aria2(Dependency):
name = "aria2" name = "aria2"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('aria2-1.37.0.tar.xz', archive = Remotefile(
'60a420ad7085eb616cb6e2bdf0a7206d68ff3d37fb5a956dc44242eb2f79b66b', "aria2-1.37.0.tar.xz",
'https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0.tar.xz') "60a420ad7085eb616cb6e2bdf0a7206d68ff3d37fb5a956dc44242eb2f79b66b",
"https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0.tar.xz",
)
def _post_prepare_script(self, context): def _post_prepare_script(self, context):
context.try_skip(self.extract_path) context.try_skip(self.extract_path)
@ -20,5 +19,9 @@ class Aria2(Dependency):
run_command(command, self.extract_path, context) run_command(command, self.extract_path, context)
class Builder(MakeBuilder): class Builder(MakeBuilder):
dependencies = ['zlib'] dependencies = ["zlib"]
configure_options = ["--disable-libaria2", "--disable-websocket", "--without-sqlite3"] configure_options = [
"--disable-libaria2",
"--disable-websocket",
"--without-sqlite3",
]

View File

@ -3,7 +3,17 @@ import os
import shutil import shutil
import time import time
from kiwixbuild.utils import pj, Context, SkipCommand, WarningMessage, extract_archive, StopBuild, run_command, colorize, copy_tree from kiwixbuild.utils import (
pj,
Context,
SkipCommand,
WarningMessage,
extract_archive,
StopBuild,
run_command,
colorize,
copy_tree,
)
from kiwixbuild.versions import main_project_versions, base_deps_versions from kiwixbuild.versions import main_project_versions, base_deps_versions
from kiwixbuild._global import neutralEnv, option, get_target_step from kiwixbuild._global import neutralEnv, option, get_target_step
@ -13,8 +23,8 @@ SCRIPT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
class _MetaDependency(type): class _MetaDependency(type):
def __new__(cls, name, bases, dct): def __new__(cls, name, bases, dct):
_class = type.__new__(cls, name, bases, dct) _class = type.__new__(cls, name, bases, dct)
if name != 'Dependency': if name != "Dependency":
dep_name = dct['name'] dep_name = dct["name"]
Dependency.all_deps[dep_name] = _class Dependency.all_deps[dep_name] = _class
return _class return _class
@ -29,7 +39,7 @@ class Dependency(metaclass=_MetaDependency):
def version(cls): def version(cls):
if cls.name in base_deps_versions: if cls.name in base_deps_versions:
return base_deps_versions[cls.name] return base_deps_versions[cls.name]
elif option('make_release'): elif option("make_release"):
return main_project_versions.get(cls.name, None) return main_project_versions.get(cls.name, None)
return None return None
@ -42,8 +52,9 @@ class Dependency(metaclass=_MetaDependency):
class Source: class Source:
"""Base Class to the real preparator """Base Class to the real preparator
A source preparator must install source in the self.source_dir attribute A source preparator must install source in the self.source_dir attribute
inside the neutralEnv.source_dir.""" inside the neutralEnv.source_dir."""
def __init__(self, target): def __init__(self, target):
self.target = target self.target = target
@ -61,22 +72,22 @@ class Source:
@property @property
def source_path(self): def source_path(self):
return pj(neutralEnv('source_dir'), self.source_dir) return pj(neutralEnv("source_dir"), self.source_dir)
@property @property
def _log_dir(self): def _log_dir(self):
return neutralEnv('log_dir') return neutralEnv("log_dir")
def _patch(self, context): def _patch(self, context):
context.try_skip(self.source_path) context.try_skip(self.source_path)
for p in self.patches: for p in self.patches:
patch_file_path = pj(SCRIPT_DIR, 'patches', p) patch_file_path = pj(SCRIPT_DIR, "patches", p)
patch_command = [*neutralEnv('patch_command'), "-p1", "-i", patch_file_path] patch_command = [*neutralEnv("patch_command"), "-p1", "-i", patch_file_path]
run_command(patch_command, self.source_path, context) run_command(patch_command, self.source_path, context)
def command(self, name, function, *args): def command(self, name, function, *args):
print(" {} {} : ".format(name, self.name), end="", flush=True) print(" {} {} : ".format(name, self.name), end="", flush=True)
log = pj(self._log_dir, 'cmd_{}_{}.log'.format(name, self.name)) log = pj(self._log_dir, "cmd_{}_{}.log".format(name, self.name))
context = Context(name, log, True) context = Context(name, log, True)
try: try:
start_time = time.time() start_time = time.time()
@ -92,7 +103,7 @@ class Source:
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
print(colorize("ERROR")) print(colorize("ERROR"))
try: try:
with open(log, 'r') as f: with open(log, "r") as f:
print(f.read()) print(f.read())
except: except:
pass pass
@ -112,34 +123,36 @@ class ReleaseDownload(Source):
@property @property
def archives(self): def archives(self):
return (self.archive, ) return (self.archive,)
@property @property
def extract_path(self): def extract_path(self):
return pj(neutralEnv('source_dir'), self.source_dir) return pj(neutralEnv("source_dir"), self.source_dir)
def _download(self, context): def _download(self, context):
context.try_skip(neutralEnv('archive_dir'), self.full_name) context.try_skip(neutralEnv("archive_dir"), self.full_name)
for archive in self.archives: for archive in self.archives:
neutralEnv('download')(archive) neutralEnv("download")(archive)
def _extract(self, context): def _extract(self, context):
context.try_skip(self.extract_path) context.try_skip(self.extract_path)
if os.path.exists(self.extract_path): if os.path.exists(self.extract_path):
shutil.rmtree(self.extract_path) shutil.rmtree(self.extract_path)
for archive in self.archives: for archive in self.archives:
extract_archive(pj(neutralEnv('archive_dir'), archive.name), extract_archive(
neutralEnv('source_dir'), pj(neutralEnv("archive_dir"), archive.name),
topdir=self.archive_top_dir, neutralEnv("source_dir"),
name=self.source_dir) topdir=self.archive_top_dir,
name=self.source_dir,
)
def prepare(self): def prepare(self):
self.command('download', self._download) self.command("download", self._download)
self.command('extract', self._extract) self.command("extract", self._extract)
if hasattr(self, 'patches'): if hasattr(self, "patches"):
self.command('patch', self._patch) self.command("patch", self._patch)
if hasattr(self, '_post_prepare_script'): if hasattr(self, "_post_prepare_script"):
self.command('post_prepare_script', self._post_prepare_script) self.command("post_prepare_script", self._post_prepare_script)
class GitClone(Source): class GitClone(Source):
@ -152,48 +165,66 @@ class GitClone(Source):
@property @property
def source_dir(self): def source_dir(self):
if option('make_release'): if option("make_release"):
return "{}_release".format(self.git_dir) return "{}_release".format(self.git_dir)
else: else:
return self.git_dir return self.git_dir
@property @property
def git_path(self): def git_path(self):
return pj(neutralEnv('source_dir'), self.source_dir) return pj(neutralEnv("source_dir"), self.source_dir)
@property @property
def git_ref(self): def git_ref(self):
if option('make_release'): if option("make_release"):
return self.release_git_ref return self.release_git_ref
else: else:
return self.base_git_ref return self.base_git_ref
def _git_init(self, context): def _git_init(self, context):
if option('fast_clone') and self.force_full_clone == False: if option("fast_clone") and self.force_full_clone == False:
command = [*neutralEnv('git_command'), "clone" , "--depth=1", "--branch", self.git_ref, self.git_remote, self.source_dir] command = [
run_command(command, neutralEnv('source_dir'), context) *neutralEnv("git_command"),
"clone",
"--depth=1",
"--branch",
self.git_ref,
self.git_remote,
self.source_dir,
]
run_command(command, neutralEnv("source_dir"), context)
else: else:
command = [*neutralEnv('git_command'), "clone", self.git_remote, self.source_dir] command = [
run_command(command, neutralEnv('source_dir'), context) *neutralEnv("git_command"),
command = [*neutralEnv('git_command'), "checkout", self.git_ref] "clone",
self.git_remote,
self.source_dir,
]
run_command(command, neutralEnv("source_dir"), context)
command = [*neutralEnv("git_command"), "checkout", self.git_ref]
run_command(command, self.git_path, context) run_command(command, self.git_path, context)
def _git_update(self, context): def _git_update(self, context):
command = [*neutralEnv('git_command'), "fetch", "origin", self.git_ref] command = [*neutralEnv("git_command"), "fetch", "origin", self.git_ref]
run_command(command, self.git_path, context) run_command(command, self.git_path, context)
try: try:
command = [*neutralEnv('git_command'), "merge", "--ff-only", f"origin/{self.git_ref}"] command = [
*neutralEnv("git_command"),
"merge",
"--ff-only",
f"origin/{self.git_ref}",
]
run_command(command, self.git_path, context) run_command(command, self.git_path, context)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
raise WarningMessage("Cannot update, please check log for information") raise WarningMessage("Cannot update, please check log for information")
def prepare(self): def prepare(self):
if not os.path.exists(self.git_path): if not os.path.exists(self.git_path):
self.command('gitinit', self._git_init) self.command("gitinit", self._git_init)
else: else:
self.command('gitupdate', self._git_update) self.command("gitupdate", self._git_update)
if hasattr(self, '_post_prepare_script'): if hasattr(self, "_post_prepare_script"):
self.command('post_prepare_script', self._post_prepare_script) self.command("post_prepare_script", self._post_prepare_script)
class Builder: class Builder:
@ -230,7 +261,7 @@ class Builder:
def command(self, name, function, *args): def command(self, name, function, *args):
print(" {} {} : ".format(name, self.name), end="", flush=True) print(" {} {} : ".format(name, self.name), end="", flush=True)
log = pj(self._log_dir, 'cmd_{}_{}.log'.format(name, self.name)) log = pj(self._log_dir, "cmd_{}_{}.log".format(name, self.name))
context = Context(name, log, self.target.force_native_build) context = Context(name, log, self.target.force_native_build)
if self.target.force_build: if self.target.force_build:
context.no_skip = True context.no_skip = True
@ -248,7 +279,7 @@ class Builder:
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
print(colorize("ERROR")) print(colorize("ERROR"))
try: try:
with open(log, 'r') as f: with open(log, "r") as f:
print(f.read()) print(f.read())
except: except:
pass pass
@ -258,36 +289,40 @@ class Builder:
raise raise
def build(self): def build(self):
if hasattr(self, '_pre_build_script'): if hasattr(self, "_pre_build_script"):
self.command('pre_build_script', self._pre_build_script) self.command("pre_build_script", self._pre_build_script)
self.command('configure', self._configure) self.command("configure", self._configure)
if hasattr(self, '_post_configure_script'): if hasattr(self, "_post_configure_script"):
self.command('post_configure_script', self._post_configure_script) self.command("post_configure_script", self._post_configure_script)
self.command('compile', self._compile) self.command("compile", self._compile)
if hasattr(self, '_test'): if hasattr(self, "_test"):
self.command('test', self._test) self.command("test", self._test)
self.command('install', self._install) self.command("install", self._install)
if hasattr(self, '_post_build_script'): if hasattr(self, "_post_build_script"):
self.command('post_build_script', self._post_build_script) self.command("post_build_script", self._post_build_script)
def make_dist(self): def make_dist(self):
if hasattr(self, '_pre_build_script'): if hasattr(self, "_pre_build_script"):
self.command('pre_build_script', self._pre_build_script) self.command("pre_build_script", self._pre_build_script)
self.command('configure', self._configure) self.command("configure", self._configure)
self.command('make_dist', self._make_dist) self.command("make_dist", self._make_dist)
def set_flatpak_buildsystem(self, module): def set_flatpak_buildsystem(self, module):
if getattr(self, 'flatpak_buildsystem', None): if getattr(self, "flatpak_buildsystem", None):
module['buildsystem'] = self.flatpak_buildsystem module["buildsystem"] = self.flatpak_buildsystem
if getattr(self, 'subsource_dir', None): if getattr(self, "subsource_dir", None):
module['subdir'] = self.subsource_dir module["subdir"] = self.subsource_dir
if getattr(self, 'flatpack_build_options', None): if getattr(self, "flatpack_build_options", None):
module['build-options'] = self.flatpack_build_options module["build-options"] = self.flatpack_build_options
if getattr(self, 'configure_option', ''): if getattr(self, "configure_option", ""):
module['config-opts'] = self.configure_option.split(' ') module["config-opts"] = self.configure_option.split(" ")
def get_env(self, *, cross_comp_flags, cross_compilers, cross_path): def get_env(self, *, cross_comp_flags, cross_compilers, cross_path):
env = self.buildEnv.get_env(cross_comp_flags=cross_comp_flags, cross_compilers=cross_compilers, cross_path=cross_path) env = self.buildEnv.get_env(
cross_comp_flags=cross_comp_flags,
cross_compilers=cross_compilers,
cross_path=cross_path,
)
for dep in self.get_dependencies(self.buildEnv.platformInfo, False): for dep in self.get_dependencies(self.buildEnv.platformInfo, False):
try: try:
builder = get_target_step(dep, self.buildEnv.platformInfo.name) builder = get_target_step(dep, self.buildEnv.platformInfo.name)
@ -317,7 +352,7 @@ class TcCopyBuilder(Builder):
return pj(self.buildEnv.toolchain_dir, self.target.full_name()) return pj(self.buildEnv.toolchain_dir, self.target.full_name())
def build(self): def build(self):
self.command('copy', self._copy) self.command("copy", self._copy)
def _copy(self, context): def _copy(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
@ -339,18 +374,18 @@ class MakeBuilder(Builder):
install_options = [] install_options = []
configure_script = "configure" configure_script = "configure"
configure_env = { configure_env = {
'_format_CFLAGS' : '{env[CFLAGS]} -O3', "_format_CFLAGS": "{env[CFLAGS]} -O3",
'_format_CXXFLAGS': '{env[CXXFLAGS]} -O3' "_format_CXXFLAGS": "{env[CXXFLAGS]} -O3",
} }
make_targets = [] make_targets = []
flatpak_buildsystem = None flatpak_buildsystem = None
@property @property
def make_install_targets(self): def make_install_targets(self):
if self.buildEnv.platformInfo.build in ('iOS', "wasm"): if self.buildEnv.platformInfo.build in ("iOS", "wasm"):
yield 'install' yield "install"
else: else:
yield 'install-strip' yield "install-strip"
@property @property
def all_configure_options(self): def all_configure_options(self):
@ -361,27 +396,26 @@ class MakeBuilder(Builder):
yield from self.dynamic_configure_options yield from self.dynamic_configure_options
if not self.target.force_native_build: if not self.target.force_native_build:
yield from self.buildEnv.platformInfo.configure_options yield from self.buildEnv.platformInfo.configure_options
yield from ('--prefix', self.buildEnv.install_dir) yield from ("--prefix", self.buildEnv.install_dir)
yield from ('--libdir', pj(self.buildEnv.install_dir, self.buildEnv.libprefix)) yield from ("--libdir", pj(self.buildEnv.install_dir, self.buildEnv.libprefix))
def set_configure_env(self, env): def set_configure_env(self, env):
dep_conf_env = self.configure_env dep_conf_env = self.configure_env
if not dep_conf_env: if not dep_conf_env:
return return
for k, v in dep_conf_env.items(): for k, v in dep_conf_env.items():
if k.startswith('_format_'): if k.startswith("_format_"):
v = v.format(buildEnv=self.buildEnv, env=env) v = v.format(buildEnv=self.buildEnv, env=env)
env[k[8:]] = v env[k[8:]] = v
else: else:
env[k] = v env[k] = v
def _configure(self, context): def _configure(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [ command = [
*self.buildEnv.configure_wrapper, *self.buildEnv.configure_wrapper,
pj(self.source_path, self.configure_script), pj(self.source_path, self.configure_script),
*self.all_configure_options *self.all_configure_options,
] ]
env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True) env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True)
self.set_configure_env(env) self.set_configure_env(env)
@ -391,10 +425,10 @@ class MakeBuilder(Builder):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [ command = [
*self.buildEnv.make_wrapper, *self.buildEnv.make_wrapper,
*neutralEnv('make_command'), *neutralEnv("make_command"),
"-j4", "-j4",
*self.make_targets, *self.make_targets,
*self.make_options *self.make_options,
] ]
env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True) env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
@ -403,26 +437,22 @@ class MakeBuilder(Builder):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [ command = [
*self.buildEnv.make_wrapper, *self.buildEnv.make_wrapper,
*neutralEnv('make_command'), *neutralEnv("make_command"),
*self.make_install_targets, *self.make_install_targets,
*self.make_options *self.make_options,
] ]
env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True) env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def _make_dist(self, context): def _make_dist(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [ command = [*self.buildEnv.make_wrapper, *neutralEnv("make_command"), "dist"]
*self.buildEnv.make_wrapper,
*neutralEnv('make_command'),
"dist"
]
env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True) env = self.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
class CMakeBuilder(MakeBuilder): class CMakeBuilder(MakeBuilder):
flatpak_buildsystem = 'cmake' flatpak_buildsystem = "cmake"
def _configure(self, context): def _configure(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
@ -430,74 +460,79 @@ class CMakeBuilder(MakeBuilder):
if not self.target.force_native_build and self.buildEnv.cmake_crossfile: if not self.target.force_native_build and self.buildEnv.cmake_crossfile:
cross_options += [f"-DCMAKE_TOOLCHAIN_FILE={self.buildEnv.cmake_crossfile}"] cross_options += [f"-DCMAKE_TOOLCHAIN_FILE={self.buildEnv.cmake_crossfile}"]
command = [ command = [
*neutralEnv('cmake_command'), *neutralEnv("cmake_command"),
*self.configure_options, *self.configure_options,
"-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON", "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON",
f"-DCMAKE_INSTALL_PREFIX={self.buildEnv.install_dir}", f"-DCMAKE_INSTALL_PREFIX={self.buildEnv.install_dir}",
f"-DCMAKE_INSTALL_LIBDIR={self.buildEnv.libprefix}", f"-DCMAKE_INSTALL_LIBDIR={self.buildEnv.libprefix}",
self.source_path, self.source_path,
*cross_options *cross_options,
] ]
env = self.get_env(cross_comp_flags=True, cross_compilers=False, cross_path=True) env = self.get_env(
cross_comp_flags=True, cross_compilers=False, cross_path=True
)
self.set_configure_env(env) self.set_configure_env(env)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def set_flatpak_buildsystem(self, module): def set_flatpak_buildsystem(self, module):
super().set_flatpak_buildsystem( module) super().set_flatpak_buildsystem(module)
module['buildir'] = True module["buildir"] = True
class QMakeBuilder(MakeBuilder): class QMakeBuilder(MakeBuilder):
qmake_targets = [] qmake_targets = []
flatpak_buildsystem = 'qmake' flatpak_buildsystem = "qmake"
@property @property
def env_options(self): def env_options(self):
if 'QMAKE_CC' in os.environ: if "QMAKE_CC" in os.environ:
yield f"QMAKE_CC={os.environ['QMAKE_CC']}" yield f"QMAKE_CC={os.environ['QMAKE_CC']}"
if 'QMAKE_CXX' in os.environ: if "QMAKE_CXX" in os.environ:
yield f"QMAKE_CXX={os.environ['QMAKE_CXX']}" yield f"QMAKE_CXX={os.environ['QMAKE_CXX']}"
def _configure(self, context): def _configure(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [ command = [
"qmake", "qmake",
*self.configure_options, *self.configure_options,
*self.env_options, *self.env_options,
self.source_path self.source_path,
] ]
env = self.get_env(cross_comp_flags=True, cross_compilers=False, cross_path=True) env = self.get_env(
cross_comp_flags=True, cross_compilers=False, cross_path=True
)
self.set_configure_env(env) self.set_configure_env(env)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def _make_dist(self, context): def _make_dist(self, context):
command = [ command = [
*neutralEnv('git_command'), "archive", *neutralEnv("git_command"),
"-o", f"{self.build_path}/{self.target_full_name()}.tar.gz", "archive",
"-o",
f"{self.build_path}/{self.target_full_name()}.tar.gz",
f"--prefix={self.target_full_name()}/", f"--prefix={self.target_full_name()}/",
"HEAD" "HEAD",
] ]
run_command(command, self.source_path, context) run_command(command, self.source_path, context)
class MesonBuilder(Builder): class MesonBuilder(Builder):
configure_options = [] configure_options = []
test_options = [] test_options = []
flatpak_buildsystem = 'meson' flatpak_buildsystem = "meson"
@property @property
def build_type(self): def build_type(self):
return 'release' if option('make_release') else 'debug' return "release" if option("make_release") else "debug"
@property @property
def strip_options(self): def strip_options(self):
if option('make_release'): if option("make_release"):
yield '--strip' yield "--strip"
@property @property
def library_type(self): def library_type(self):
return 'static' if self.buildEnv.platformInfo.static else 'shared' return "static" if self.buildEnv.platformInfo.static else "shared"
def _configure(self, context): def _configure(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
@ -508,47 +543,54 @@ class MesonBuilder(Builder):
if not self.target.force_native_build and self.buildEnv.meson_crossfile: if not self.target.force_native_build and self.buildEnv.meson_crossfile:
cross_options += ["--cross-file", self.buildEnv.meson_crossfile] cross_options += ["--cross-file", self.buildEnv.meson_crossfile]
command = [ command = [
*neutralEnv('meson_command'), *neutralEnv("meson_command"),
'.', self.build_path, ".",
f'--buildtype={self.build_type}', self.build_path,
f"--buildtype={self.build_type}",
*self.strip_options, *self.strip_options,
f'--default-library={self.library_type}', f"--default-library={self.library_type}",
*self.configure_options, *self.configure_options,
f'--prefix={self.buildEnv.install_dir}', f"--prefix={self.buildEnv.install_dir}",
f'--libdir={self.buildEnv.libprefix}', f"--libdir={self.buildEnv.libprefix}",
*cross_options *cross_options,
] ]
env = self.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=True) env = self.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=True
)
run_command(command, self.source_path, context, env=env) run_command(command, self.source_path, context, env=env)
def _compile(self, context): def _compile(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [*neutralEnv('ninja_command'), "-v"] command = [*neutralEnv("ninja_command"), "-v"]
env = self.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=True) env = self.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=True
)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def _test(self, context): def _test(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
if ( self.buildEnv.platformInfo.build == 'android' if self.buildEnv.platformInfo.build == "android" or (
or (self.buildEnv.platformInfo.build != 'native' self.buildEnv.platformInfo.build != "native"
and not self.buildEnv.platformInfo.static) and not self.buildEnv.platformInfo.static
): ):
raise SkipCommand() raise SkipCommand()
command = [ command = [*neutralEnv("mesontest_command"), "--verbose", *self.test_options]
*neutralEnv('mesontest_command'), env = self.get_env(
'--verbose', cross_comp_flags=False, cross_compilers=False, cross_path=True
*self.test_options )
]
env = self.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=True)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def _install(self, context): def _install(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [*neutralEnv('ninja_command'), '-v', 'install'] command = [*neutralEnv("ninja_command"), "-v", "install"]
env = self.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=True) env = self.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=True
)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def _make_dist(self, context): def _make_dist(self, context):
command = [*neutralEnv('ninja_command'), "-v", "dist"] command = [*neutralEnv("ninja_command"), "-v", "dist"]
env = self.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=True) env = self.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=True
)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)

View File

@ -1,14 +1,10 @@
from .base import ( from .base import Dependency, GitClone, CMakeBuilder
Dependency,
GitClone,
CMakeBuilder)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class docoptcpp(Dependency): class docoptcpp(Dependency):
name = 'docoptcpp' name = "docoptcpp"
class Source(GitClone): class Source(GitClone):
git_remote = "https://github.com/docopt/docopt.cpp.git" git_remote = "https://github.com/docopt/docopt.cpp.git"
@ -17,5 +13,4 @@ class docoptcpp(Dependency):
git_ref = "3dd23e3280f213bacefdf5fcb04857bf52e90917" git_ref = "3dd23e3280f213bacefdf5fcb04857bf52e90917"
class Builder(CMakeBuilder): class Builder(CMakeBuilder):
make_install_targets = ['install'] make_install_targets = ["install"]

View File

@ -1,8 +1,4 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder
)
from kiwixbuild.utils import Remotefile, run_command from kiwixbuild.utils import Remotefile, run_command
@ -11,9 +7,11 @@ class Gumbo(Dependency):
name = "gumbo" name = "gumbo"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('gumbo-0.10.1.tar.gz', archive = Remotefile(
'28463053d44a5dfbc4b77bcf49c8cee119338ffa636cc17fc3378421d714efad', "gumbo-0.10.1.tar.gz",
'https://github.com/google/gumbo-parser/archive/v0.10.1.tar.gz') "28463053d44a5dfbc4b77bcf49c8cee119338ffa636cc17fc3378421d714efad",
"https://github.com/google/gumbo-parser/archive/v0.10.1.tar.gz",
)
def _post_prepare_script(self, context): def _post_prepare_script(self, context):
context.try_skip(self.extract_path) context.try_skip(self.extract_path)

View File

@ -1,25 +1,25 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder
)
from kiwixbuild.utils import pj, SkipCommand, Remotefile, extract_archive from kiwixbuild.utils import pj, SkipCommand, Remotefile, extract_archive
from kiwixbuild._global import get_target_step, neutralEnv from kiwixbuild._global import get_target_step, neutralEnv
import os, shutil import os, shutil
import fileinput import fileinput
class Icu(Dependency): class Icu(Dependency):
name = "icu4c" name = "icu4c"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive_src = Remotefile('icu4c-73_2-src.tgz', archive_src = Remotefile(
'818a80712ed3caacd9b652305e01afc7fa167e6f2e94996da44b90c2ab604ce1', "icu4c-73_2-src.tgz",
'https://github.com/unicode-org/icu/releases/download/release-73-2/icu4c-73_2-src.tgz') "818a80712ed3caacd9b652305e01afc7fa167e6f2e94996da44b90c2ab604ce1",
archive_data = Remotefile('icu4c-73_2-data.zip', "https://github.com/unicode-org/icu/releases/download/release-73-2/icu4c-73_2-src.tgz",
'ca1ee076163b438461e484421a7679fc33a64cd0a54f9d4b401893fa1eb42701', )
'https://github.com/unicode-org/icu/releases/download/release-73-2/icu4c-73_2-data.zip') archive_data = Remotefile(
"icu4c-73_2-data.zip",
"ca1ee076163b438461e484421a7679fc33a64cd0a54f9d4b401893fa1eb42701",
"https://github.com/unicode-org/icu/releases/download/release-73-2/icu4c-73_2-data.zip",
)
archives = [archive_src, archive_data] archives = [archive_src, archive_data]
@ -28,28 +28,30 @@ class Icu(Dependency):
if os.path.exists(self.extract_path): if os.path.exists(self.extract_path):
shutil.rmtree(self.extract_path) shutil.rmtree(self.extract_path)
extract_archive( extract_archive(
pj(neutralEnv('archive_dir'), self.archive_src.name), pj(neutralEnv("archive_dir"), self.archive_src.name),
neutralEnv('source_dir'), neutralEnv("source_dir"),
topdir=None, topdir=None,
name=self.source_dir) name=self.source_dir,
shutil.rmtree(pj(neutralEnv('source_dir'), self.source_dir, 'source', 'data')) )
shutil.rmtree(
pj(neutralEnv("source_dir"), self.source_dir, "source", "data")
)
extract_archive( extract_archive(
pj(neutralEnv('archive_dir'), self.archive_data.name), pj(neutralEnv("archive_dir"), self.archive_data.name),
pj(neutralEnv('source_dir'), self.source_dir, 'source'), pj(neutralEnv("source_dir"), self.source_dir, "source"),
topdir='data', topdir="data",
name='data' name="data",
) )
patches = [ patches = [
"icu4c_fix_static_lib_name_mingw.patch", "icu4c_fix_static_lib_name_mingw.patch",
# "icu4c_android_elf64_st_info.patch", # "icu4c_android_elf64_st_info.patch",
# "icu4c_custom_data.patch", # "icu4c_custom_data.patch",
# "icu4c_noxlocale.patch", # "icu4c_noxlocale.patch",
"icu4c_rpath.patch", "icu4c_rpath.patch",
# "icu4c_build_config.patch", # "icu4c_build_config.patch",
"icu4c_wasm.patch" "icu4c_wasm.patch",
] ]
class Builder(MakeBuilder): class Builder(MakeBuilder):
subsource_dir = "source" subsource_dir = "source"
@ -57,8 +59,8 @@ class Icu(Dependency):
@classmethod @classmethod
def get_dependencies(cls, platformInfo, allDeps): def get_dependencies(cls, platformInfo, allDeps):
plt = 'native_static' if platformInfo.static else 'native_dyn' plt = "native_static" if platformInfo.static else "native_dyn"
return [(plt, 'icu4c')] return [(plt, "icu4c")]
@property @property
def configure_options(self): def configure_options(self):
@ -70,23 +72,25 @@ class Icu(Dependency):
yield "--disable-icuio" yield "--disable-icuio"
yield "--disable-layoutex" yield "--disable-layoutex"
platformInfo = self.buildEnv.platformInfo platformInfo = self.buildEnv.platformInfo
if platformInfo.build != 'native': if platformInfo.build != "native":
icu_native_builder = get_target_step( icu_native_builder = get_target_step(
'icu4c', "icu4c", "native_static" if platformInfo.static else "native_dyn"
'native_static' if platformInfo.static else 'native_dyn') )
yield f"--with-cross-build={icu_native_builder.build_path}" yield f"--with-cross-build={icu_native_builder.build_path}"
yield "--disable-tools" yield "--disable-tools"
if platformInfo.build in ('android', 'wasm'): if platformInfo.build in ("android", "wasm"):
yield "--with-data-packaging=archive" yield "--with-data-packaging=archive"
def set_env(self, env): def set_env(self, env):
env['ICU_DATA_FILTER_FILE'] = pj(os.path.dirname(os.path.realpath(__file__)), "icu4c_data_filter.json") env["ICU_DATA_FILTER_FILE"] = pj(
os.path.dirname(os.path.realpath(__file__)), "icu4c_data_filter.json"
)
def _post_configure_script(self, context): def _post_configure_script(self, context):
if self.buildEnv.platformInfo.build != "wasm": if self.buildEnv.platformInfo.build != "wasm":
context.skip() context.skip()
context.try_skip(self.build_path) context.try_skip(self.build_path)
for line in fileinput.input(pj(self.build_path, 'Makefile'), inplace=True): for line in fileinput.input(pj(self.build_path, "Makefile"), inplace=True):
if line == "#DATASUBDIR = data\n": if line == "#DATASUBDIR = data\n":
print("DATASUBDIR = data") print("DATASUBDIR = data")
else: else:

View File

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

View File

@ -1,7 +1,5 @@
from .base import ( from .base import Dependency, GitClone, QMakeBuilder
Dependency,
GitClone,
QMakeBuilder)
class KiwixDesktop(Dependency): class KiwixDesktop(Dependency):
name = "kiwix-desktop" name = "kiwix-desktop"
@ -13,22 +11,18 @@ class KiwixDesktop(Dependency):
class Builder(QMakeBuilder): class Builder(QMakeBuilder):
dependencies = ["qt", "qtwebengine", "libkiwix", "aria2"] dependencies = ["qt", "qtwebengine", "libkiwix", "aria2"]
make_install_targets = ['install'] make_install_targets = ["install"]
configure_env = None configure_env = None
flatpack_build_options = { flatpack_build_options = {"env": ["QMAKEPATH=/app/lib"]}
"env": [
"QMAKEPATH=/app/lib"
]
}
@property @property
def configure_options(self): def configure_options(self):
if self.buildEnv.platformInfo.name == 'flatpak': if self.buildEnv.platformInfo.name == "flatpak":
yield 'QMAKE_INCDIR+=/app/include/QtWebEngine' yield "QMAKE_INCDIR+=/app/include/QtWebEngine"
yield 'QMAKE_INCDIR+=/app/include/QtWebEngineCore' yield "QMAKE_INCDIR+=/app/include/QtWebEngineCore"
yield 'QMAKE_INCDIR+=/app/include/QtWebEngineWidgets' yield "QMAKE_INCDIR+=/app/include/QtWebEngineWidgets"
else: else:
yield f"PREFIX={self.buildEnv.install_dir}" yield f"PREFIX={self.buildEnv.install_dir}"
if self.buildEnv.platformInfo.static: if self.buildEnv.platformInfo.static:
yield 'CONFIG+=static' yield "CONFIG+=static"

View File

@ -1,7 +1,5 @@
from .base import ( from .base import Dependency, GitClone, MesonBuilder
Dependency,
GitClone,
MesonBuilder)
class KiwixTools(Dependency): class KiwixTools(Dependency):
name = "kiwix-tools" name = "kiwix-tools"

View File

@ -9,22 +9,50 @@ from .base import (
from kiwixbuild.utils import Remotefile, pj, Defaultdict, SkipCommand, run_command from kiwixbuild.utils import Remotefile, pj, Defaultdict, SkipCommand, run_command
from kiwixbuild._global import get_target_step from kiwixbuild._global import get_target_step
class LibCurl(Dependency): class LibCurl(Dependency):
name = "libcurl" name = "libcurl"
class Source(ReleaseDownload): class Source(ReleaseDownload):
name = "libcurl" name = "libcurl"
archive = Remotefile('curl-7.67.0.tar.xz', archive = Remotefile(
'f5d2e7320379338c3952dcc7566a140abb49edb575f9f99272455785c40e536c', "curl-7.67.0.tar.xz",
'https://curl.haxx.se/download/curl-7.67.0.tar.xz') "f5d2e7320379338c3952dcc7566a140abb49edb575f9f99272455785c40e536c",
"https://curl.haxx.se/download/curl-7.67.0.tar.xz",
)
class Builder(MakeBuilder): class Builder(MakeBuilder):
dependencies = ['zlib'] dependencies = ["zlib"]
configure_options = [ configure_options = [
*[f"--without-{p}" for p in *[
('libssh2', 'ssl', 'libmetalink', 'librtmp', 'nghttp2', 'libidn2', 'brotli') f"--without-{p}"
], for p in (
*[f"--disable-{p}" for p in "libssh2",
('ftp', 'file', 'ldap', 'ldaps', 'rtsp', 'dict', 'telnet', "ssl",
'tftp', 'pop3', 'imap', 'smb', 'smtp', 'gopher', 'manual')] "libmetalink",
"librtmp",
"nghttp2",
"libidn2",
"brotli",
)
],
*[
f"--disable-{p}"
for p in (
"ftp",
"file",
"ldap",
"ldaps",
"rtsp",
"dict",
"telnet",
"tftp",
"pop3",
"imap",
"smb",
"smtp",
"gopher",
"manual",
)
],
] ]

View File

@ -1,12 +1,10 @@
import shutil, os import shutil, os
from .base import ( from .base import Dependency, GitClone, MesonBuilder
Dependency,
GitClone,
MesonBuilder)
from kiwixbuild.utils import pj, copy_tree from kiwixbuild.utils import pj, copy_tree
from kiwixbuild._global import option, get_target_step, neutralEnv from kiwixbuild._global import option, get_target_step, neutralEnv
class Libkiwix(Dependency): class Libkiwix(Dependency):
name = "libkiwix" name = "libkiwix"
force_build = True force_build = True
@ -16,7 +14,17 @@ class Libkiwix(Dependency):
git_dir = "libkiwix" git_dir = "libkiwix"
class Builder(MesonBuilder): class Builder(MesonBuilder):
dependencies = ["pugixml", "libzim", "zlib", "lzma", "libcurl", "libmicrohttpd", "icu4c", "mustache", "xapian-core"] dependencies = [
"pugixml",
"libzim",
"zlib",
"lzma",
"libcurl",
"libmicrohttpd",
"icu4c",
"mustache",
"xapian-core",
]
strip_options = [] strip_options = []
@property @property
@ -28,18 +36,18 @@ class Libkiwix(Dependency):
@property @property
def configure_options(self): def configure_options(self):
platformInfo = self.buildEnv.platformInfo platformInfo = self.buildEnv.platformInfo
if platformInfo.build == 'android': if platformInfo.build == "android":
yield '-Dstatic-linkage=true' yield "-Dstatic-linkage=true"
yield '-Dwerror=false' yield "-Dwerror=false"
if platformInfo.build == 'iOS': if platformInfo.build == "iOS":
yield '-Db_bitcode=true' yield "-Db_bitcode=true"
if platformInfo.name == 'flatpak': if platformInfo.name == "flatpak":
yield '--wrap-mode=nodownload' yield "--wrap-mode=nodownload"
if platformInfo.mixed and option('target') == 'libkiwix': if platformInfo.mixed and option("target") == "libkiwix":
yield "-Dstatic-linkage=true" yield "-Dstatic-linkage=true"
@property @property
def library_type(self): def library_type(self):
if self.buildEnv.platformInfo.build == 'android': if self.buildEnv.platformInfo.build == "android":
return 'shared' return "shared"
return super().library_type return super().library_type

View File

@ -9,15 +9,18 @@ from .base import (
from kiwixbuild.utils import Remotefile, pj, SkipCommand, run_command from kiwixbuild.utils import Remotefile, pj, SkipCommand, run_command
from kiwixbuild._global import get_target_step from kiwixbuild._global import get_target_step
class LibMagic(Dependency): class LibMagic(Dependency):
name = "libmagic" name = "libmagic"
class Source(ReleaseDownload): class Source(ReleaseDownload):
name = "libmagic" name = "libmagic"
source_dir = "libmagic" source_dir = "libmagic"
archive_top_dir = 'file-5.44' archive_top_dir = "file-5.44"
archive = Remotefile('file-5.44.tar.gz', archive = Remotefile(
'3751c7fba8dbc831cb8d7cc8aff21035459b8ce5155ef8b0880a27d028475f3b') "file-5.44.tar.gz",
"3751c7fba8dbc831cb8d7cc8aff21035459b8ce5155ef8b0880a27d028475f3b",
)
class Builder(MakeBuilder): class Builder(MakeBuilder):
@property @property
@ -29,22 +32,21 @@ class LibMagic(Dependency):
@classmethod @classmethod
def get_dependencies(cls, platformInfo, allDeps): def get_dependencies(cls, platformInfo, allDeps):
if platformInfo.build != 'native': if platformInfo.build != "native":
return [('native_static', 'libmagic')] return [("native_static", "libmagic")]
return [] return []
def _compile(self, context): def _compile(self, context):
platformInfo = self.buildEnv.platformInfo platformInfo = self.buildEnv.platformInfo
if platformInfo.build == 'native': if platformInfo.build == "native":
return super()._compile(context) return super()._compile(context)
context.try_skip(self.build_path) context.try_skip(self.build_path)
command = [ command = ["make", "-j4", *self.make_targets, *self.make_options]
"make", env = self.buildEnv.get_env(
"-j4", cross_comp_flags=True, cross_compilers=True, cross_path=True
*self.make_targets, )
*self.make_options libmagic_native_builder = get_target_step("libmagic", "native_static")
] env["PATH"] = ":".join(
env = self.buildEnv.get_env(cross_comp_flags=True, cross_compilers=True, cross_path=True) [pj(libmagic_native_builder.build_path, "src"), env["PATH"]]
libmagic_native_builder = get_target_step('libmagic', 'native_static') )
env['PATH'] = ':'.join([pj(libmagic_native_builder.build_path, 'src'), env['PATH']])
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)

View File

@ -1,17 +1,23 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class MicroHttpd(Dependency): class MicroHttpd(Dependency):
name = "libmicrohttpd" name = "libmicrohttpd"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('libmicrohttpd-0.9.76.tar.gz', archive = Remotefile(
'f0b1547b5a42a6c0f724e8e1c1cb5ce9c4c35fb495e7d780b9930d35011ceb4c', "libmicrohttpd-0.9.76.tar.gz",
'https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.76.tar.gz') "f0b1547b5a42a6c0f724e8e1c1cb5ce9c4c35fb495e7d780b9930d35011ceb4c",
"https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.76.tar.gz",
)
class Builder(MakeBuilder): class Builder(MakeBuilder):
configure_options = ["--disable-https", "--without-libgcrypt", "--without-libcurl", "--disable-doc", "--disable-examples"] configure_options = [
"--disable-https",
"--without-libgcrypt",
"--without-libcurl",
"--disable-doc",
"--disable-examples",
]

View File

@ -1,9 +1,7 @@
from .base import ( from .base import Dependency, GitClone, MesonBuilder
Dependency,
GitClone,
MesonBuilder)
from kiwixbuild._global import option, get_target_step from kiwixbuild._global import option, get_target_step
class Libzim(Dependency): class Libzim(Dependency):
name = "libzim" name = "libzim"
force_build = True force_build = True
@ -24,18 +22,18 @@ class Libzim(Dependency):
@classmethod @classmethod
def get_dependencies(cls, platformInfo, allDeps): def get_dependencies(cls, platformInfo, allDeps):
deps = ['lzma', 'zstd', 'xapian-core', 'icu4c'] deps = ["lzma", "zstd", "xapian-core", "icu4c"]
if platformInfo.name not in ('flatpak', 'wasm'): if platformInfo.name not in ("flatpak", "wasm"):
deps.append('zim-testing-suite') deps.append("zim-testing-suite")
return deps return deps
@property @property
def configure_options(self): def configure_options(self):
platformInfo = self.buildEnv.platformInfo platformInfo = self.buildEnv.platformInfo
if platformInfo.build == 'android': if platformInfo.build == "android":
yield "-DUSE_BUFFER_HEADER=false" yield "-DUSE_BUFFER_HEADER=false"
yield "-Dstatic-linkage=true" yield "-Dstatic-linkage=true"
if platformInfo.mixed and option('target') == 'libzim': if platformInfo.mixed and option("target") == "libzim":
yield "-Dstatic-linkage=true" yield "-Dstatic-linkage=true"
if platformInfo.name == "flatpak": if platformInfo.name == "flatpak":
yield "--wrap-mode=nodownload" yield "--wrap-mode=nodownload"
@ -44,11 +42,11 @@ class Libzim(Dependency):
yield "-Dexamples=false" yield "-Dexamples=false"
yield "-DUSE_MMAP=false" yield "-DUSE_MMAP=false"
if platformInfo.name not in ("flatpak", "wasm"): if platformInfo.name not in ("flatpak", "wasm"):
zim_testing_suite = get_target_step('zim-testing-suite', 'source') zim_testing_suite = get_target_step("zim-testing-suite", "source")
yield '-Dtest_data_dir={}'.format(zim_testing_suite.source_path) yield "-Dtest_data_dir={}".format(zim_testing_suite.source_path)
@property @property
def library_type(self): def library_type(self):
if self.buildEnv.platformInfo.build == 'android': if self.buildEnv.platformInfo.build == "android":
return 'shared' return "shared"
return super().library_type return super().library_type

View File

@ -1,28 +1,28 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class lzma(Dependency): class lzma(Dependency):
name = 'lzma' name = "lzma"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('xz-5.2.6.tar.gz', archive = Remotefile(
'a2105abee17bcd2ebd15ced31b4f5eda6e17efd6b10f921a01cda4a44c91b3a0', "xz-5.2.6.tar.gz",
'https://altushost-swe.dl.sourceforge.net/project/lzmautils/xz-5.2.6.tar.gz' "a2105abee17bcd2ebd15ced31b4f5eda6e17efd6b10f921a01cda4a44c91b3a0",
) "https://altushost-swe.dl.sourceforge.net/project/lzmautils/xz-5.2.6.tar.gz",
)
class Builder(MakeBuilder): class Builder(MakeBuilder):
@property @property
def configure_options(self): def configure_options(self):
return ["--disable-xz", return [
"--disable-xzdec", "--disable-xz",
"--disable-lzmadec", "--disable-xzdec",
"--disable-lzmainfo", "--disable-lzmadec",
"--disable-lzma-links", "--disable-lzmainfo",
"--disable-scripts", "--disable-lzma-links",
"--disable-doc", "--disable-scripts",
# "--disable-symbol-versions" "--disable-doc",
] # "--disable-symbol-versions"
]

View File

@ -1,28 +1,30 @@
from .base import ( from .base import Dependency, ReleaseDownload, Builder as BaseBuilder
Dependency,
ReleaseDownload,
Builder as BaseBuilder)
from kiwixbuild.utils import Remotefile, pj from kiwixbuild.utils import Remotefile, pj
from shutil import copy2 from shutil import copy2
class Mustache(Dependency): class Mustache(Dependency):
name = "mustache" name = "mustache"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('Mustache-4.1.tar.gz', archive = Remotefile(
'acd66359feb4318b421f9574cfc5a511133a77d916d0b13c7caa3783c0bfe167', "Mustache-4.1.tar.gz",
'https://github.com/kainjow/Mustache/archive/v4.1.tar.gz') "acd66359feb4318b421f9574cfc5a511133a77d916d0b13c7caa3783c0bfe167",
"https://github.com/kainjow/Mustache/archive/v4.1.tar.gz",
)
class Builder(BaseBuilder): class Builder(BaseBuilder):
def build(self): def build(self):
self.command('copy_header', self._copy_header) self.command("copy_header", self._copy_header)
def _copy_header(self, context): def _copy_header(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
copy2(pj(self.source_path, 'mustache.hpp'), copy2(
pj(self.buildEnv.install_dir, 'include')) pj(self.source_path, "mustache.hpp"),
pj(self.buildEnv.install_dir, "include"),
)
def set_flatpak_buildsystem(self, module): def set_flatpak_buildsystem(self, module):
module['buildsystem'] = 'simple' module["buildsystem"] = "simple"
module['build-commands'] = ['cp mustache.hpp /app/include'] module["build-commands"] = ["cp mustache.hpp /app/include"]

View File

@ -1,19 +1,19 @@
from .base import ( from .base import Dependency, ReleaseDownload, MesonBuilder
Dependency,
ReleaseDownload,
MesonBuilder)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class Pugixml(Dependency): class Pugixml(Dependency):
name = "pugixml" name = "pugixml"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('pugixml-1.2.tar.gz', archive = Remotefile(
'0f422dad86da0a2e56a37fb2a88376aae6e931f22cc8b956978460c9db06136b') "pugixml-1.2.tar.gz",
"0f422dad86da0a2e56a37fb2a88376aae6e931f22cc8b956978460c9db06136b",
)
patches = ["pugixml_meson.patch"] patches = ["pugixml_meson.patch"]
flatpak_dest = "src" flatpak_dest = "src"
class Builder(MesonBuilder): class Builder(MesonBuilder):
build_type = 'release' build_type = "release"
strip_options = [] strip_options = []

View File

@ -1,26 +1,24 @@
import shutil import shutil
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder, QMakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder,
QMakeBuilder)
from kiwixbuild.utils import Remotefile, pj, SkipCommand from kiwixbuild.utils import Remotefile, pj, SkipCommand
class Qt(Dependency): class Qt(Dependency):
name = 'qt' name = "qt"
class Source(ReleaseDownload): class Source(ReleaseDownload):
name = "qt" name = "qt"
source_dir = "qt-5.10.1" source_dir = "qt-5.10.1"
archive = Remotefile('qt-everywhere-src-5.10.1.tar.xz', archive = Remotefile(
'', "qt-everywhere-src-5.10.1.tar.xz",
'http://ftp.oregonstate.edu/.1/blfs/conglomeration/qt5/qt-everywhere-src-5.10.1.tar.xz') "",
"http://ftp.oregonstate.edu/.1/blfs/conglomeration/qt5/qt-everywhere-src-5.10.1.tar.xz",
)
class Builder(MakeBuilder): class Builder(MakeBuilder):
dependencies = ['icu4c', 'zlib'] dependencies = ["icu4c", "zlib"]
dynamic_configure_options = ["-shared"] dynamic_configure_options = ["-shared"]
static_configure_options = ["-static"] static_configure_options = ["-static"]
@ -33,47 +31,50 @@ class Qt(Dependency):
yield from self.dynamic_configure_options yield from self.dynamic_configure_options
if not self.target.force_native_build: if not self.target.force_native_build:
yield from self.buildEnv.platformInfo.configure_options yield from self.buildEnv.platformInfo.configure_options
yield from ('-prefix', self.buildEnv.install_dir) yield from ("-prefix", self.buildEnv.install_dir)
yield from ('-libdir', pj(self.buildEnv.install_dir, self.buildEnv.libprefix)) yield from (
"-libdir",
pj(self.buildEnv.install_dir, self.buildEnv.libprefix),
)
@property @property
def configure_options(self): def configure_options(self):
skip_modules = [ skip_modules = [
'qt3d', "qt3d",
'qtcanvas3d', "qtcanvas3d",
'qtcharts', "qtcharts",
'qtconnectivity', "qtconnectivity",
'qtdatavis3d', "qtdatavis3d",
# 'qtdeclarative', # 'qtdeclarative',
'qtdoc', "qtdoc",
'qtgamepad', "qtgamepad",
'qtgraphicaleffects', "qtgraphicaleffects",
'qtlocation', "qtlocation",
'qtmultimedia', "qtmultimedia",
'qtnetworkauth', "qtnetworkauth",
'qtpurchasing', "qtpurchasing",
# 'qtquickcontrols', # 'qtquickcontrols',
'qtquickcontrols2', "qtquickcontrols2",
'qtremoteobjects', "qtremoteobjects",
'qtscript', "qtscript",
'qtscxml', "qtscxml",
'qtsensors', "qtsensors",
'qtserialbus', "qtserialbus",
'qtserialport', "qtserialport",
'qtspeech', "qtspeech",
'qtvirtualkeyboard', "qtvirtualkeyboard",
'qtwayland', "qtwayland",
'qtwebglplugin', "qtwebglplugin",
'qtwebsockets', "qtwebsockets",
# 'qtwebview', # 'qtwebview',
] ]
yield '-recheck' yield "-recheck"
yield '-opensource' yield "-opensource"
yield '-confirm-license' yield "-confirm-license"
yield '-ccache' yield "-ccache"
yield from ('-make', 'libs') yield from ("-make", "libs")
for module in skip_modules: for module in skip_modules:
yield from ('-skip', module) yield from ("-skip", module)
class QtWebEngine(Dependency): class QtWebEngine(Dependency):
@ -82,5 +83,5 @@ class QtWebEngine(Dependency):
Source = Qt.Source Source = Qt.Source
class Builder(QMakeBuilder): class Builder(QMakeBuilder):
dependencies = ['qt'] dependencies = ["qt"]
subsource_dir = "qtwebengine" subsource_dir = "qtwebengine"

View File

@ -5,23 +5,25 @@ from kiwixbuild.utils import Remotefile, add_execution_right, run_command
pj = os.path.join pj = os.path.join
class android_ndk(Dependency): class android_ndk(Dependency):
dont_skip = True dont_skip = True
neutral = False neutral = False
name = 'android-ndk' name = "android-ndk"
gccver = '4.9.x' gccver = "4.9.x"
api = '24' api = "24"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('android-ndk-r21e-linux-x86_64.zip', archive = Remotefile(
'ad7ce5467e18d40050dc51b8e7affc3e635c85bd8c59be62de32352328ed467e', "android-ndk-r21e-linux-x86_64.zip",
'https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip') "ad7ce5467e18d40050dc51b8e7affc3e635c85bd8c59be62de32352328ed467e",
"https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip",
)
@property @property
def source_dir(self): def source_dir(self):
return self.target.full_name() return self.target.full_name()
class Builder(Builder): class Builder(Builder):
@property @property
def install_path(self): def install_path(self):
@ -33,7 +35,7 @@ class android_ndk(Dependency):
@property @property
def platform(self): def platform(self):
return 'android-'+self.api return "android-" + self.api
@property @property
def arch(self): def arch(self):
@ -45,24 +47,33 @@ class android_ndk(Dependency):
def _build_platform(self, context): def _build_platform(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
script = pj(self.source_path, 'build/tools/make_standalone_toolchain.py') script = pj(self.source_path, "build/tools/make_standalone_toolchain.py")
add_execution_right(script) add_execution_right(script)
command = [ command = [
script, script,
f'--arch={self.arch}', f"--arch={self.arch}",
f'--api={self.api}', f"--api={self.api}",
f'--install-dir={self.install_path}', f"--install-dir={self.install_path}",
'--force' "--force",
] ]
env = self.buildEnv.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=False) env = self.buildEnv.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=False
)
run_command(command, self.build_path, context, env=env) run_command(command, self.build_path, context, env=env)
def _fix_permission_right(self, context): def _fix_permission_right(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
bin_dirs = [pj(self.install_path, 'bin'), bin_dirs = [
pj(self.install_path, self.arch_full, 'bin'), pj(self.install_path, "bin"),
pj(self.install_path, 'libexec', 'gcc', self.arch_full, self.target.gccver) pj(self.install_path, self.arch_full, "bin"),
] pj(
self.install_path,
"libexec",
"gcc",
self.arch_full,
self.target.gccver,
),
]
for root, dirs, files in os.walk(self.install_path): for root, dirs, files in os.walk(self.install_path):
if not root in bin_dirs: if not root in bin_dirs:
continue continue
@ -74,6 +85,5 @@ class android_ndk(Dependency):
add_execution_right(file_path) add_execution_right(file_path)
def build(self): def build(self):
self.command('build_platform', self._build_platform) self.command("build_platform", self._build_platform)
self.command('fix_permission_right', self._fix_permission_right) self.command("fix_permission_right", self._fix_permission_right)

View File

@ -4,21 +4,25 @@ from kiwixbuild.utils import Remotefile
# The arm toolchains # The arm toolchains
# This is based on toolchains published here : https://github.com/tttapa/docker-arm-cross-toolchain # This is based on toolchains published here : https://github.com/tttapa/docker-arm-cross-toolchain
base_url = "https://github.com/tttapa/docker-arm-cross-toolchain/releases/download/0.1.0/" base_url = (
"https://github.com/tttapa/docker-arm-cross-toolchain/releases/download/0.1.0/"
)
aarch_base_url = 'https://master.dl.sourceforge.net/project/raspberry-pi-cross-compilers/Bonus%20Raspberry%20Pi%20GCC%2064-Bit%20Toolchains/Raspberry%20Pi%20GCC%2064-Bit%20Cross-Compiler%20Toolchains/Stretch/GCC%206.3.0/' aarch_base_url = "https://master.dl.sourceforge.net/project/raspberry-pi-cross-compilers/Bonus%20Raspberry%20Pi%20GCC%2064-Bit%20Toolchains/Raspberry%20Pi%20GCC%2064-Bit%20Cross-Compiler%20Toolchains/Stretch/GCC%206.3.0/"
class armv6_toolchain(Dependency): class armv6_toolchain(Dependency):
dont_skip = True dont_skip = True
neutral = True neutral = True
name = 'armv6' name = "armv6"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('x-tools-armv6-rpi-linux-gnueabihf.tar.xz', archive = Remotefile(
'4c371c4c5b55ebd1f3d7dd26b14703632d9ba47423f901bcd9303d83ad444434', "x-tools-armv6-rpi-linux-gnueabihf.tar.xz",
base_url + 'x-tools-armv6-rpi-linux-gnueabihf.tar.xz') "4c371c4c5b55ebd1f3d7dd26b14703632d9ba47423f901bcd9303d83ad444434",
base_url + "x-tools-armv6-rpi-linux-gnueabihf.tar.xz",
)
class Builder(TcCopyBuilder): class Builder(TcCopyBuilder):
src_subdir = "armv6-rpi-linux-gnueabihf" src_subdir = "armv6-rpi-linux-gnueabihf"
@ -27,24 +31,29 @@ class armv6_toolchain(Dependency):
class armv8_toolchain(Dependency): class armv8_toolchain(Dependency):
dont_skip = True dont_skip = True
neutral = True neutral = True
name = 'armv8' name = "armv8"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('x-tools-armv8-rpi-linux-gnueabihf.tar.xz', archive = Remotefile(
'cc28f5c3f6a3e7d9985f98779c4e72224b4eb5a7e4dc2bcdefd90cb241fb94a5', "x-tools-armv8-rpi-linux-gnueabihf.tar.xz",
base_url + 'x-tools-armv8-rpi3-linux-gnueabihf.tar.xz') "cc28f5c3f6a3e7d9985f98779c4e72224b4eb5a7e4dc2bcdefd90cb241fb94a5",
base_url + "x-tools-armv8-rpi3-linux-gnueabihf.tar.xz",
)
class Builder(TcCopyBuilder): class Builder(TcCopyBuilder):
src_subdir = "armv8-rpi3-linux-gnueabihf" src_subdir = "armv8-rpi3-linux-gnueabihf"
class aarch64_toolchain(Dependency): class aarch64_toolchain(Dependency):
dont_skip = True dont_skip = True
neutral = True neutral = True
name = "aarch64" name = "aarch64"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('cross-gcc-6.3.0-pi_64.tar.gz', archive = Remotefile(
'1b048bb8886ad63d21797cd9129fc37b9ea0dfaac7e3c36f888aa16fbec1d320', "cross-gcc-6.3.0-pi_64.tar.gz",
aarch_base_url + 'cross-gcc-6.3.0-pi_64.tar.gz') "1b048bb8886ad63d21797cd9129fc37b9ea0dfaac7e3c36f888aa16fbec1d320",
aarch_base_url + "cross-gcc-6.3.0-pi_64.tar.gz",
)
Builder = TcCopyBuilder Builder = TcCopyBuilder

View File

@ -5,21 +5,23 @@ from kiwixbuild.utils import Remotefile, run_command, copy_tree
pj = os.path.join pj = os.path.join
class emsdk(Dependency): class emsdk(Dependency):
dont_skip = True dont_skip = True
neutral = False neutral = False
name = 'emsdk' name = "emsdk"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('emsdk-3.1.41.tar.gz', archive = Remotefile(
'147a2d72df34227bdb4ffedc587a8cb674a42269c40458f3f69ae37e8966cdc6', "emsdk-3.1.41.tar.gz",
'https://codeload.github.com/emscripten-core/emsdk/tar.gz/refs/tags/3.1.41') "147a2d72df34227bdb4ffedc587a8cb674a42269c40458f3f69ae37e8966cdc6",
"https://codeload.github.com/emscripten-core/emsdk/tar.gz/refs/tags/3.1.41",
)
@property @property
def source_dir(self): def source_dir(self):
return self.target.full_name() return self.target.full_name()
class Builder(Builder): class Builder(Builder):
@property @property
def install_path(self): def install_path(self):
@ -39,9 +41,7 @@ class emsdk(Dependency):
command = ["./emsdk", "activate", "3.1.24"] command = ["./emsdk", "activate", "3.1.24"]
run_command(command, self.install_path, context) run_command(command, self.install_path, context)
def build(self): def build(self):
self.command('copy_source', self._copy_source) self.command("copy_source", self._copy_source)
self.command('install', self._install) self.command("install", self._install)
self.command('activate', self._activate) self.command("activate", self._activate)

View File

@ -5,9 +5,10 @@ from kiwixbuild.utils import Remotefile, add_execution_right, run_command
pj = os.path.join pj = os.path.join
class org_kde(Dependency): class org_kde(Dependency):
neutral = False neutral = False
name = 'org.kde' name = "org.kde"
Source = NoopSource Source = NoopSource
@ -15,32 +16,42 @@ class org_kde(Dependency):
def _setup_remote(self, context): def _setup_remote(self, context):
command = [ command = [
"flatpak", "flatpak",
"--user", "remote-add", "--if-not-exists", "--user",
"remote-add",
"--if-not-exists",
"flathub", "flathub",
"https://flathub.org/repo/flathub.flatpakrepo" "https://flathub.org/repo/flathub.flatpakrepo",
] ]
env = self.buildEnv.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=False) env = self.buildEnv.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=False
)
run_command(command, self.buildEnv.build_dir, context, env=env) run_command(command, self.buildEnv.build_dir, context, env=env)
def _install_sdk(self, context): def _install_sdk(self, context):
command = [ command = [
"flatpak", "flatpak",
"--user", "install", "--noninteractive", "--verbose", "-y", "--user",
"install",
"--noninteractive",
"--verbose",
"-y",
"flathub", "flathub",
f"{self.target.name}.Sdk//{self.target.version()}", f"{self.target.name}.Sdk//{self.target.version()}",
f"{self.target.name}.Platform//{self.target.version()}" f"{self.target.name}.Platform//{self.target.version()}",
] ]
env = self.buildEnv.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=False) env = self.buildEnv.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=False
)
run_command(command, self.buildEnv.build_dir, context, env=env) run_command(command, self.buildEnv.build_dir, context, env=env)
def build(self): def build(self):
self.command('setup_remote', self._setup_remote) self.command("setup_remote", self._setup_remote)
self.command('install_sdk', self._install_sdk) self.command("install_sdk", self._install_sdk)
class io_qt_qtwebengine(Dependency): class io_qt_qtwebengine(Dependency):
neutral = False neutral = False
name = 'io.qt.qtwebengine' name = "io.qt.qtwebengine"
Source = NoopSource Source = NoopSource
@ -48,23 +59,31 @@ class io_qt_qtwebengine(Dependency):
def _setup_remote(self, context): def _setup_remote(self, context):
command = [ command = [
"flatpak", "flatpak",
"--user", "remote-add", "--if-not-exists", "--user",
"remote-add",
"--if-not-exists",
"flathub", "flathub",
"https://flathub.org/repo/flathub.flatpakrepo" "https://flathub.org/repo/flathub.flatpakrepo",
] ]
env = self.buildEnv.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=False) env = self.buildEnv.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=False
)
run_command(command, self.buildEnv.build_dir, context, env=env) run_command(command, self.buildEnv.build_dir, context, env=env)
def _install_sdk(self, context): def _install_sdk(self, context):
command = [ command = [
"flatpak", "flatpak",
"--user", "install", "-y", "--user",
"install",
"-y",
"flathub", "flathub",
f"{self.target.name}.BaseApp//{self.target.version()}" f"{self.target.name}.BaseApp//{self.target.version()}",
] ]
env = self.buildEnv.get_env(cross_comp_flags=False, cross_compilers=False, cross_path=False) env = self.buildEnv.get_env(
cross_comp_flags=False, cross_compilers=False, cross_path=False
)
run_command(command, self.buildEnv.build_dir, context, env=env) run_command(command, self.buildEnv.build_dir, context, env=env)
def build(self): def build(self):
self.command('setup_remote', self._setup_remote) self.command("setup_remote", self._setup_remote)
self.command('install_sdk', self._install_sdk) self.command("install_sdk", self._install_sdk)

View File

@ -1,15 +1,18 @@
from .base import Dependency, ReleaseDownload, TcCopyBuilder from .base import Dependency, ReleaseDownload, TcCopyBuilder
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class aarch64_musl_toolchain(Dependency): class aarch64_musl_toolchain(Dependency):
dont_skip = True dont_skip = True
neutral = True neutral = True
name = "aarch64_musl" name = "aarch64_musl"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('aarch64-linux-musl-cross.tgz', archive = Remotefile(
'0f18a885b161815520bbb5757a4b4ab40d0898c29bebee58d0cddd6112e59cc6', "aarch64-linux-musl-cross.tgz",
'https://more.musl.cc/10/x86_64-linux-musl/aarch64-linux-musl-cross.tgz') "0f18a885b161815520bbb5757a4b4ab40d0898c29bebee58d0cddd6112e59cc6",
"https://more.musl.cc/10/x86_64-linux-musl/aarch64-linux-musl-cross.tgz",
)
Builder = TcCopyBuilder Builder = TcCopyBuilder
@ -20,8 +23,10 @@ class x86_64_musl_toolchain(Dependency):
name = "x86-64_musl" name = "x86-64_musl"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('x86_64-linux-musl-cross.tgz', archive = Remotefile(
'a3d55de8105739fcfb8b10eaa72cdb5d779319726bacff24149388d7608d1ed8', "x86_64-linux-musl-cross.tgz",
'https://more.musl.cc/10/x86_64-linux-musl/x86_64-linux-musl-cross.tgz') "a3d55de8105739fcfb8b10eaa72cdb5d779319726bacff24149388d7608d1ed8",
"https://more.musl.cc/10/x86_64-linux-musl/x86_64-linux-musl-cross.tgz",
)
Builder = TcCopyBuilder Builder = TcCopyBuilder

View File

@ -1,30 +1,30 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder
)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class UUID(Dependency): class UUID(Dependency):
name = 'uuid' name = "uuid"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('e2fsprogs-libs-1.43.4.tar.gz', archive = Remotefile(
'eed4516325768255c9745e7b82c9d7d0393abce302520a5b2cde693204b0e419', "e2fsprogs-libs-1.43.4.tar.gz",
'https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v1.43.4/e2fsprogs-libs-1.43.4.tar.gz') "eed4516325768255c9745e7b82c9d7d0393abce302520a5b2cde693204b0e419",
extract_dir = 'e2fsprogs-libs-1.43.4' "https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v1.43.4/e2fsprogs-libs-1.43.4.tar.gz",
)
extract_dir = "e2fsprogs-libs-1.43.4"
class Builder(MakeBuilder): class Builder(MakeBuilder):
configure_options = ["--enable-libuuid", configure_options = [
"--disable-debugfs", "--enable-libuuid",
"--disable-imager", "--disable-debugfs",
"--disable-resizer", "--disable-imager",
"--disable-defrag", "--disable-resizer",
"--enable-fsck", "--disable-defrag",
"--disable-uuidd"] "--enable-fsck",
configure_env = {'_format_CFLAGS': "{env.CFLAGS} -O3 -fPIC"} "--disable-uuidd",
]
configure_env = {"_format_CFLAGS": "{env.CFLAGS} -O3 -fPIC"}
static_configure_options = dynamic_configure_options = [] static_configure_options = dynamic_configure_options = []
make_targets = ['libs'] make_targets = ["libs"]
make_install_targets = ['install-libs'] make_install_targets = ["install-libs"]

View File

@ -1,8 +1,4 @@
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder
)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
from kiwixbuild._global import neutralEnv from kiwixbuild._global import neutralEnv
@ -12,23 +8,29 @@ class Xapian(Dependency):
name = "xapian-core" name = "xapian-core"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('xapian-core-1.4.23.tar.xz', archive = Remotefile(
'30d3518172084f310dab86d262b512718a7f9a13635aaa1a188e61dc26b2288c') "xapian-core-1.4.23.tar.xz",
"30d3518172084f310dab86d262b512718a7f9a13635aaa1a188e61dc26b2288c",
)
class Builder(MakeBuilder): class Builder(MakeBuilder):
configure_options = [ configure_options = [
"--disable-sse", "--disable-sse",
"--disable-backend-chert", "--disable-backend-chert",
"--disable-backend-remote", "--disable-backend-remote",
"--disable-documentation"] "--disable-documentation",
configure_env = {'_format_LDFLAGS': "{env.LDFLAGS} -L{buildEnv.install_dir}/{buildEnv.libprefix}", ]
'_format_CXXFLAGS': "{env.CXXFLAGS} -O3 -I{buildEnv.install_dir}/include"} configure_env = {
"_format_LDFLAGS": "{env.LDFLAGS} -L{buildEnv.install_dir}/{buildEnv.libprefix}",
"_format_CXXFLAGS": "{env.CXXFLAGS} -O3 -I{buildEnv.install_dir}/include",
}
@classmethod @classmethod
def get_dependencies(cls, platformInfo, allDeps): def get_dependencies(cls, platformInfo, allDeps):
deps = ['zlib', 'lzma'] deps = ["zlib", "lzma"]
if (platformInfo.build in ('win32', 'wasm') if (
or neutralEnv('distname') == 'Darwin'): platformInfo.build in ("win32", "wasm")
or neutralEnv("distname") == "Darwin"
):
return deps return deps
return deps + ['uuid'] return deps + ["uuid"]

View File

@ -1,8 +1,4 @@
from .base import ( from .base import Dependency, ReleaseDownload, NoopBuilder
Dependency,
ReleaseDownload,
NoopBuilder
)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
@ -12,8 +8,10 @@ class ZimTestingSuite(Dependency):
dont_skip = True dont_skip = True
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('zim-testing-suite-0.3.tar.gz', archive = Remotefile(
'cd7d1ccc48af3783af9156cb6bf3c18d9a3319a73fdeefe65f0b4cae402d3d66', "zim-testing-suite-0.3.tar.gz",
'https://github.com/openzim/zim-testing-suite/releases/download/v0.3/zim-testing-suite-0.3.tar.gz') "cd7d1ccc48af3783af9156cb6bf3c18d9a3319a73fdeefe65f0b4cae402d3d66",
"https://github.com/openzim/zim-testing-suite/releases/download/v0.3/zim-testing-suite-0.3.tar.gz",
)
Builder = NoopBuilder Builder = NoopBuilder

View File

@ -1,7 +1,5 @@
from .base import ( from .base import Dependency, GitClone, MesonBuilder
Dependency,
GitClone,
MesonBuilder)
class ZimTools(Dependency): class ZimTools(Dependency):
name = "zim-tools" name = "zim-tools"
@ -14,15 +12,15 @@ class ZimTools(Dependency):
class Builder(MesonBuilder): class Builder(MesonBuilder):
@classmethod @classmethod
def get_dependencies(cls, platformInfo, allDeps): def get_dependencies(cls, platformInfo, allDeps):
base_deps = ['libzim', 'docoptcpp', 'mustache'] base_deps = ["libzim", "docoptcpp", "mustache"]
if platformInfo.build != 'win32': if platformInfo.build != "win32":
base_deps += ['libmagic', 'gumbo'] base_deps += ["libmagic", "gumbo"]
return base_deps return base_deps
@property @property
def configure_options(self): def configure_options(self):
# We don't build zimwriterfs on win32, and so we don't have magic # We don't build zimwriterfs on win32, and so we don't have magic
if self.buildEnv.platformInfo.build != 'win32': if self.buildEnv.platformInfo.build != "win32":
yield f"-Dmagic-install-prefix={self.buildEnv.install_dir}" yield f"-Dmagic-install-prefix={self.buildEnv.install_dir}"
if self.buildEnv.platformInfo.static: if self.buildEnv.platformInfo.static:
yield "-Dstatic-linkage=true" yield "-Dstatic-linkage=true"

View File

@ -1,34 +1,31 @@
import shutil import shutil
from .base import ( from .base import Dependency, ReleaseDownload, MakeBuilder
Dependency,
ReleaseDownload,
MakeBuilder)
from kiwixbuild.utils import Remotefile, pj, SkipCommand from kiwixbuild.utils import Remotefile, pj, SkipCommand
class zlib(Dependency): class zlib(Dependency):
name = 'zlib' name = "zlib"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('zlib-1.2.12.tar.gz', archive = Remotefile(
'91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9') "zlib-1.2.12.tar.gz",
patches = ['zlib_std_libname.patch'] "91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9",
)
patches = ["zlib_std_libname.patch"]
class Builder(MakeBuilder): class Builder(MakeBuilder):
dynamic_configure_options = ["--shared"] dynamic_configure_options = ["--shared"]
static_configure_options = ["--static"] static_configure_options = ["--static"]
make_install_targets = ['install'] make_install_targets = ["install"]
def _pre_build_script(self, context): def _pre_build_script(self, context):
context.try_skip(self.build_path) context.try_skip(self.build_path)
shutil.copytree(self.source_path, self.build_path) shutil.copytree(self.source_path, self.build_path)
def _configure(self, context): def _configure(self, context):
if self.buildEnv.platformInfo.build == 'win32': if self.buildEnv.platformInfo.build == "win32":
raise SkipCommand() raise SkipCommand()
return super()._configure(context) return super()._configure(context)
@ -36,20 +33,27 @@ class zlib(Dependency):
def all_configure_options(self): def all_configure_options(self):
yield from self.configure_options yield from self.configure_options
yield from self.static_configure_options if self.buildEnv.platformInfo.static else self.dynamic_configure_options yield from self.static_configure_options if self.buildEnv.platformInfo.static else self.dynamic_configure_options
yield from ('--prefix', self.buildEnv.install_dir) yield from ("--prefix", self.buildEnv.install_dir)
yield from ('--libdir', pj(self.buildEnv.install_dir, self.buildEnv.libprefix)) yield from (
"--libdir",
pj(self.buildEnv.install_dir, self.buildEnv.libprefix),
)
@property @property
def make_options(self): def make_options(self):
if self.buildEnv.platformInfo.build != 'win32': if self.buildEnv.platformInfo.build != "win32":
return return
yield "--makefile" yield "--makefile"
yield "win32/Makefile.gcc" yield "win32/Makefile.gcc"
yield "PREFIX=i686-w64-mingw32-", yield "PREFIX=i686-w64-mingw32-",
yield "SHARED_MODE={}".format("0" if self.buildEnv.platformInfo.static else "1"), yield "SHARED_MODE={}".format(
yield "INCLUDE_PATH={}".format(pj(self.buildEnv.install_dir, 'include')), "0" if self.buildEnv.platformInfo.static else "1"
yield "LIBRARY_PATH={}".format(pj(self.buildEnv.install_dir, self.buildEnv.libprefix)), ),
yield "BINARY_PATH={}".format(pj(self.buildEnv.install_dir, 'bin')) yield "INCLUDE_PATH={}".format(pj(self.buildEnv.install_dir, "include")),
yield "LIBRARY_PATH={}".format(
pj(self.buildEnv.install_dir, self.buildEnv.libprefix)
),
yield "BINARY_PATH={}".format(pj(self.buildEnv.install_dir, "bin"))
@property @property
def make_targets(self): def make_targets(self):

View File

@ -1,22 +1,20 @@
from .base import ( from .base import Dependency, ReleaseDownload, MesonBuilder
Dependency,
ReleaseDownload,
MesonBuilder)
from kiwixbuild.utils import Remotefile from kiwixbuild.utils import Remotefile
class zstd(Dependency): class zstd(Dependency):
name = 'zstd' name = "zstd"
class Source(ReleaseDownload): class Source(ReleaseDownload):
archive = Remotefile('zstd-1.5.2.tar.gz', archive = Remotefile(
'f7de13462f7a82c29ab865820149e778cbfe01087b3a55b5332707abf9db4a6e', "zstd-1.5.2.tar.gz",
'https://github.com/facebook/zstd/archive/refs/tags/v1.5.2.tar.gz') "f7de13462f7a82c29ab865820149e778cbfe01087b3a55b5332707abf9db4a6e",
"https://github.com/facebook/zstd/archive/refs/tags/v1.5.2.tar.gz",
)
class Builder(MesonBuilder): class Builder(MesonBuilder):
subsource_dir = 'build/meson' subsource_dir = "build/meson"
build_type = 'release' build_type = "release"
strip_options = [] strip_options = []
configure_options = ['-Dbin_programs=false', '-Dbin_contrib=false'] configure_options = ["-Dbin_programs=false", "-Dbin_contrib=false"]

View File

@ -1,4 +1,3 @@
import sys import sys
from collections import OrderedDict from collections import OrderedDict
from .buildenv import * from .buildenv import *
@ -9,9 +8,13 @@ from .dependencies import Dependency
from .packages import PACKAGE_NAME_MAPPERS from .packages import PACKAGE_NAME_MAPPERS
from .versions import base_deps_versions from .versions import base_deps_versions
from ._global import ( from ._global import (
neutralEnv, option, neutralEnv,
add_target_step, get_target_step, target_steps, option,
backend) add_target_step,
get_target_step,
target_steps,
backend,
)
from . import _global from . import _global
from .dependencies.base import ( from .dependencies.base import (
Source, Source,
@ -22,7 +25,8 @@ from .dependencies.base import (
CMakeBuilder, CMakeBuilder,
QMakeBuilder, QMakeBuilder,
MakeBuilder, MakeBuilder,
SCRIPT_DIR) SCRIPT_DIR,
)
import json import json
from shutil import copyfile from shutil import copyfile
from urllib.parse import urlparse from urllib.parse import urlparse
@ -30,54 +34,60 @@ from urllib.request import urlopen
import json import json
MANIFEST = { MANIFEST = {
'app-id': 'org.kiwix.desktop', "app-id": "org.kiwix.desktop",
'runtime': 'org.kde.Platform', "runtime": "org.kde.Platform",
'runtime-version': base_deps_versions['org.kde'], "runtime-version": base_deps_versions["org.kde"],
'base': 'io.qt.qtwebengine.BaseApp', "base": "io.qt.qtwebengine.BaseApp",
'base-version': base_deps_versions['org.kde'], # keep BaseApp (qwebengine) in sync with org.kde "base-version": base_deps_versions[
'sdk': 'org.kde.Sdk', "org.kde"
'command': 'kiwix-desktop', ], # keep BaseApp (qwebengine) in sync with org.kde
'rename-icon': 'kiwix-desktop', "sdk": "org.kde.Sdk",
'finish-args': [ "command": "kiwix-desktop",
'--socket=wayland', "rename-icon": "kiwix-desktop",
'--socket=x11', "finish-args": [
'--share=network', "--socket=wayland",
'--share=ipc', "--socket=x11",
'--device=dri', "--share=network",
'--socket=pulseaudio', "--share=ipc",
"--device=dri",
"--socket=pulseaudio",
],
"cleanup": [
"/include",
"/lib/pkgconfig",
"/lib/cmake",
"/lib/*.la",
"/bin/curl",
"/bin/copydatabase",
"/bin/kiwix-compile-resources",
"/bin/kiwix-manage",
"/bin/kiwix-read",
"/bin/kiwix-search",
"/bin/quest",
"/bin/simple*",
"/bin/xapian-*",
"/share/aclocal",
"/share/doc",
"/share/man",
], ],
'cleanup': [
'/include',
'/lib/pkgconfig',
'/lib/cmake',
'/lib/*.la',
'/bin/curl',
'/bin/copydatabase',
'/bin/kiwix-compile-resources',
'/bin/kiwix-manage',
'/bin/kiwix-read',
'/bin/kiwix-search',
'/bin/quest',
'/bin/simple*',
'/bin/xapian-*',
'/share/aclocal',
'/share/doc',
'/share/man'
]
} }
GET_REF_URL_API_TEMPLATE = 'https://api.github.com/repos{repo}/git/refs/tags/{ref}' GET_REF_URL_API_TEMPLATE = "https://api.github.com/repos{repo}/git/refs/tags/{ref}"
class FlatpakBuilder: class FlatpakBuilder:
def __init__(self): def __init__(self):
self._targets = {} self._targets = {}
PlatformInfo.get_platform('neutral', self._targets) PlatformInfo.get_platform("neutral", self._targets)
self.platform = PlatformInfo.get_platform('flatpak', self._targets) self.platform = PlatformInfo.get_platform("flatpak", self._targets)
if neutralEnv('distname') not in self.platform.compatible_hosts: if neutralEnv("distname") not in self.platform.compatible_hosts:
print(('ERROR: The target platform {} cannot be build on host {}.\n' print(
'Select another target platform or change your host system.' (
).format(self.platform.name, neutralEnv('distname'))) "ERROR: The target platform {} cannot be build on host {}.\n"
self.targetDefs = self.platform.add_targets(option('target'), self._targets) "Select another target platform or change your host system."
).format(self.platform.name, neutralEnv("distname"))
)
self.targetDefs = self.platform.add_targets(option("target"), self._targets)
def finalize_target_steps(self): def finalize_target_steps(self):
steps = [] steps = []
@ -89,9 +99,9 @@ class FlatpakBuilder:
plt = PlatformInfo.all_platforms[pltName] plt = PlatformInfo.all_platforms[pltName]
for tlcName in plt.toolchain_names: for tlcName in plt.toolchain_names:
tlc = Dependency.all_deps[tlcName] tlc = Dependency.all_deps[tlcName]
src_plt_step = ('source', tlcName) src_plt_step = ("source", tlcName)
add_target_step(src_plt_step, self._targets[src_plt_step]) add_target_step(src_plt_step, self._targets[src_plt_step])
blt_plt_step = ('neutral' if tlc.neutral else pltName, tlcName) blt_plt_step = ("neutral" if tlc.neutral else pltName, tlcName)
add_target_step(blt_plt_step, self._targets[blt_plt_step]) add_target_step(blt_plt_step, self._targets[blt_plt_step])
for dep in steps: for dep in steps:
@ -104,7 +114,7 @@ class FlatpakBuilder:
def order_dependencies(self, targetDef, targets): def order_dependencies(self, targetDef, targets):
targetPlatformName, targetName = targetDef targetPlatformName, targetName = targetDef
if targetPlatformName == 'source': if targetPlatformName == "source":
# Do not try to order sources, they will be added as dep by the # Do not try to order sources, they will be added as dep by the
# build step two lines later. # build step two lines later.
return return
@ -121,18 +131,18 @@ class FlatpakBuilder:
depPlatform, depName = targetPlatformName, dep depPlatform, depName = targetPlatformName, dep
if (depPlatform, depName) in targets: if (depPlatform, depName) in targets:
yield from self.order_dependencies((depPlatform, depName), targets) yield from self.order_dependencies((depPlatform, depName), targets)
yield ('source', targetName) yield ("source", targetName)
yield targetDef yield targetDef
def instanciate_steps(self): def instanciate_steps(self):
for stepDef in list(target_steps()): for stepDef in list(target_steps()):
stepPlatform, stepName = stepDef stepPlatform, stepName = stepDef
stepClass = Dependency.all_deps[stepName] stepClass = Dependency.all_deps[stepName]
if stepPlatform == 'source': if stepPlatform == "source":
source = get_target_step(stepDef)(stepClass) source = get_target_step(stepDef)(stepClass)
add_target_step(stepDef, source) add_target_step(stepDef, source)
else: else:
source = get_target_step(stepName, 'source') source = get_target_step(stepName, "source")
env = PlatformInfo.get_platform(stepPlatform).buildEnv env = PlatformInfo.get_platform(stepPlatform).buildEnv
builder = get_target_step(stepDef)(stepClass, source, env) builder = get_target_step(stepDef)(stepClass, source, env)
add_target_step(stepDef, builder) add_target_step(stepDef, builder)
@ -142,121 +152,126 @@ class FlatpakBuilder:
modules = OrderedDict() modules = OrderedDict()
for stepDef in steps: for stepDef in steps:
module = modules.setdefault(stepDef[1], {}) module = modules.setdefault(stepDef[1], {})
module['name'] = stepDef[1] module["name"] = stepDef[1]
if stepDef[0] == 'source': if stepDef[0] == "source":
source = get_target_step(stepDef) source = get_target_step(stepDef)
if getattr(source, 'flatpak_no_autogen', False): if getattr(source, "flatpak_no_autogen", False):
module['no-autogen'] = True module["no-autogen"] = True
module_sources = module.setdefault('sources', []) module_sources = module.setdefault("sources", [])
if isinstance(source, ReleaseDownload): if isinstance(source, ReleaseDownload):
src = { src = {
'type': 'archive', "type": "archive",
'sha256': source.archive.sha256, "sha256": source.archive.sha256,
'url': source.archive.url "url": source.archive.url,
} }
if hasattr(source, 'flatpak_dest'): if hasattr(source, "flatpak_dest"):
src['dest'] = source.flatpak_dest src["dest"] = source.flatpak_dest
module_sources.append(src) module_sources.append(src)
elif isinstance(source, GitClone): elif isinstance(source, GitClone):
src = { src = {
'type': 'git', "type": "git",
'url': source.git_remote, "url": source.git_remote,
'tag': source.git_ref "tag": source.git_ref,
} }
try: try:
parsed = urlparse(source.git_remote) parsed = urlparse(source.git_remote)
if parsed.hostname == 'github.com': if parsed.hostname == "github.com":
repo = parsed.path[:-4] repo = parsed.path[:-4]
api_url = GET_REF_URL_API_TEMPLATE.format( api_url = GET_REF_URL_API_TEMPLATE.format(
repo = repo, repo=repo, ref=source.git_ref
ref = source.git_ref) )
with urlopen(api_url) as r: with urlopen(api_url) as r:
ret = json.loads(r.read()) ret = json.loads(r.read())
src['commit'] = ret['object']['sha'] src["commit"] = ret["object"]["sha"]
except: except:
pass pass
module_sources.append(src) module_sources.append(src)
for p in getattr(source, 'patches', []): for p in getattr(source, "patches", []):
patch = { patch = {"type": "patch", "path": "patches/" + p}
'type': 'patch',
'path': 'patches/' + p
}
module_sources.append(patch) module_sources.append(patch)
if hasattr(source, 'flatpak_command'): if hasattr(source, "flatpak_command"):
command = { command = {"type": "shell", "commands": [source.flatpak_command]}
'type': 'shell',
'commands': [source.flatpak_command]
}
module_sources.append(command) module_sources.append(command)
else: else:
builder = get_target_step(stepDef) builder = get_target_step(stepDef)
builder.set_flatpak_buildsystem(module) builder.set_flatpak_buildsystem(module)
print(module['name']) print(module["name"])
manifest = MANIFEST.copy() manifest = MANIFEST.copy()
modules = [m for m in modules.values() if m.get('sources')] modules = [m for m in modules.values() if m.get("sources")]
for m in modules: for m in modules:
temp = m['sources'] temp = m["sources"]
del m['sources'] del m["sources"]
m['sources'] = temp m["sources"] = temp
manifest['modules'] = modules manifest["modules"] = modules
manifest_name = "{}.json".format(MANIFEST['app-id']) manifest_name = "{}.json".format(MANIFEST["app-id"])
manifest_path = pj(self.platform.buildEnv.build_dir, manifest_name) manifest_path = pj(self.platform.buildEnv.build_dir, manifest_name)
with open(manifest_path, 'w') as f: with open(manifest_path, "w") as f:
f.write(json.dumps(manifest, indent=4)) f.write(json.dumps(manifest, indent=4))
def copy_patches(self): def copy_patches(self):
sourceDefs = (tDef for tDef in target_steps() if tDef[0] == 'source') sourceDefs = (tDef for tDef in target_steps() if tDef[0] == "source")
for sourceDef in sourceDefs: for sourceDef in sourceDefs:
source = get_target_step(sourceDef) source = get_target_step(sourceDef)
if not hasattr(source, 'patches'): if not hasattr(source, "patches"):
continue continue
for p in source.patches: for p in source.patches:
path = pj(SCRIPT_DIR, 'patches', p) path = pj(SCRIPT_DIR, "patches", p)
os.makedirs(pj(self.platform.buildEnv.build_dir, 'patches'), exist_ok=True) os.makedirs(
dest = pj(self.platform.buildEnv.build_dir, 'patches', p) pj(self.platform.buildEnv.build_dir, "patches"), exist_ok=True
)
dest = pj(self.platform.buildEnv.build_dir, "patches", p)
copyfile(path, dest) copyfile(path, dest)
def build(self): def build(self):
log = pj(self.platform.buildEnv.log_dir, 'cmd_build_flatpak.log') log = pj(self.platform.buildEnv.log_dir, "cmd_build_flatpak.log")
context = Context('build', log, False) context = Context("build", log, False)
command = [ command = [
"flatpak-builder", "flatpak-builder",
"--user", "--ccache", "--force-clean", "--keep-build-dirs", "--user",
"--disable-rofiles-fuse", "--repo=repo", "builddir", "--ccache",
f"{MANIFEST['app-id']}.json" "--force-clean",
"--keep-build-dirs",
"--disable-rofiles-fuse",
"--repo=repo",
"builddir",
f"{MANIFEST['app-id']}.json",
] ]
try: try:
run_command(command, self.platform.buildEnv.build_dir, context, env=self.platform.get_env()) run_command(
command,
self.platform.buildEnv.build_dir,
context,
env=self.platform.get_env(),
)
context._finalise() context._finalise()
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
with open(log, 'r') as f: with open(log, "r") as f:
print(f.read()) print(f.read())
raise StopBuild() raise StopBuild()
def bundle(self): def bundle(self):
log = pj(self.platform.buildEnv.log_dir, 'cmd_bundle_flatpak.log') log = pj(self.platform.buildEnv.log_dir, "cmd_bundle_flatpak.log")
context = Context('bundle', log, False) context = Context("bundle", log, False)
app_id = MANIFEST['app-id'] app_id = MANIFEST["app-id"]
command = [ command = ["flatpak", "build-bundle", "repo", f"{app_id}.flatpak", app_id]
"flatpak", "build-bundle", "repo",
f"{app_id}.flatpak",
app_id
]
try: try:
run_command(command, self.platform.buildEnv.build_dir, context, env=self.platform.get_env()) run_command(
command,
self.platform.buildEnv.build_dir,
context,
env=self.platform.get_env(),
)
context._finalise() context._finalise()
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
with open(log, 'r') as f: with open(log, "r") as f:
print(f.read()) print(f.read())
raise StopBuild() raise StopBuild()
def _get_packages(self): def _get_packages(self):
package_name_mapper = PACKAGE_NAME_MAPPERS.get('flatpak', {}) package_name_mapper = PACKAGE_NAME_MAPPERS.get("flatpak", {})
to_drop = [] to_drop = []
for builderDef in self._targets: for builderDef in self._targets:
@ -295,11 +310,10 @@ class FlatpakBuilder:
self.bundle() self.bundle()
# No error, clean intermediate file at end of build if needed. # No error, clean intermediate file at end of build if needed.
print("[CLEAN]") print("[CLEAN]")
if option('clean_at_end'): if option("clean_at_end"):
for platform in PlatformInfo.all_running_platforms.values(): for platform in PlatformInfo.all_running_platforms.values():
platform.clean_intermediate_directories() platform.clean_intermediate_directories()
else: else:
print("SKIP") print("SKIP")
except StopBuild: except StopBuild:
sys.exit("Stopping build due to errors") sys.exit("Stopping build due to errors")

View File

@ -1,107 +1,147 @@
_fedora_common = [
"automake",
_fedora_common = ['automake', 'libtool', 'cmake', 'git', 'subversion', 'ccache', 'pkgconf-pkg-config', 'gcc-c++', 'gettext-devel'] "libtool",
_debian_common = ['automake', 'libtool', 'cmake', 'git', 'subversion', 'ccache', 'pkg-config', 'gcc', 'autopoint'] "cmake",
"git",
"subversion",
"ccache",
"pkgconf-pkg-config",
"gcc-c++",
"gettext-devel",
]
_debian_common = [
"automake",
"libtool",
"cmake",
"git",
"subversion",
"ccache",
"pkg-config",
"gcc",
"autopoint",
]
PACKAGE_NAME_MAPPERS = { PACKAGE_NAME_MAPPERS = {
'flatpak': { "flatpak": {
'zlib': True, "zlib": True,
'lzma': True, "lzma": True,
'icu4c': True, "icu4c": True,
'qt': True, "qt": True,
'qtwebengine': True, "qtwebengine": True,
'uuid': True, "uuid": True,
'libxml2': True, "libxml2": True,
'libssl': True, "libssl": True,
'libcurl': True, "libcurl": True,
}, },
'fedora_native_dyn': { "fedora_native_dyn": {
'COMMON': _fedora_common, "COMMON": _fedora_common,
'uuid': ['libuuid-devel'], "uuid": ["libuuid-devel"],
'xapian-core': None, # Not the right version on fedora 25 "xapian-core": None, # Not the right version on fedora 25
'pugixml': None, # ['pugixml-devel'] but package doesn't provide pkg-config file "pugixml": None, # ['pugixml-devel'] but package doesn't provide pkg-config file
'libmicrohttpd': ['libmicrohttpd-devel'], "libmicrohttpd": ["libmicrohttpd-devel"],
'zlib': ['zlib-devel'], "zlib": ["zlib-devel"],
'lzma': ['xz-devel'], "lzma": ["xz-devel"],
'icu4c': None, "icu4c": None,
'zimlib': None, "zimlib": None,
'file' : ['file-devel'], "file": ["file-devel"],
'gumbo' : ['gumbo-parser-devel'], "gumbo": ["gumbo-parser-devel"],
'aria2': ['aria2'], "aria2": ["aria2"],
'qt': ['qt5-qtbase-devel', 'qt5-qtsvg'], "qt": ["qt5-qtbase-devel", "qt5-qtsvg"],
'qtwebengine': ['qt5-qtwebengine-devel'] "qtwebengine": ["qt5-qtwebengine-devel"],
}, },
'fedora_native_static': { "fedora_native_static": {
'COMMON': _fedora_common + ['glibc-static', 'libstdc++-static'], "COMMON": _fedora_common + ["glibc-static", "libstdc++-static"],
'lzma': ['xz-devel', 'xz-static'] "lzma": ["xz-devel", "xz-static"]
# Either there is no packages, or no static or too old # Either there is no packages, or no static or too old
}, },
'fedora_i586_dyn': { "fedora_i586_dyn": {
'COMMON': _fedora_common + ['glibc-devel.i686', 'libstdc++-devel.i686'], "COMMON": _fedora_common + ["glibc-devel.i686", "libstdc++-devel.i686"],
}, },
'fedora_i586_static': { "fedora_i586_static": {
'COMMON': _fedora_common + ['glibc-devel.i686'], "COMMON": _fedora_common + ["glibc-devel.i686"],
}, },
'fedora_win32_dyn': { "fedora_win32_dyn": {
'COMMON': _fedora_common + ['mingw32-gcc-c++', 'mingw32-bzip2', 'mingw32-win-iconv', 'mingw32-winpthreads', 'wine'], "COMMON": _fedora_common
'zlib': ['mingw32-zlib'], + [
'lzma': ['mingw32-xz-libs'], "mingw32-gcc-c++",
'libmicrohttpd': ['mingw32-libmicrohttpd'], "mingw32-bzip2",
"mingw32-win-iconv",
"mingw32-winpthreads",
"wine",
],
"zlib": ["mingw32-zlib"],
"lzma": ["mingw32-xz-libs"],
"libmicrohttpd": ["mingw32-libmicrohttpd"],
}, },
'fedora_win32_static': { "fedora_win32_static": {
'COMMON': _fedora_common + ['mingw32-gcc-c++', 'mingw32-bzip2-static', 'mingw32-win-iconv-static', 'mingw32-winpthreads-static', 'wine'], "COMMON": _fedora_common
'zlib': ['mingw32-zlib-static'], + [
'lzma': ['mingw32-xz-libs-static'], "mingw32-gcc-c++",
'libmicrohttpd': None, # ['mingw32-libmicrohttpd-static'] packaging dependecy seems buggy, and some static lib are name libfoo.dll.a and "mingw32-bzip2-static",
# gcc cannot found them. "mingw32-win-iconv-static",
"mingw32-winpthreads-static",
"wine",
],
"zlib": ["mingw32-zlib-static"],
"lzma": ["mingw32-xz-libs-static"],
"libmicrohttpd": None, # ['mingw32-libmicrohttpd-static'] packaging dependecy seems buggy, and some static lib are name libfoo.dll.a and
# gcc cannot found them.
}, },
'fedora_armhf_static': { "fedora_armhf_static": {"COMMON": _fedora_common},
'COMMON': _fedora_common "fedora_armhf_dyn": {"COMMON": _fedora_common},
"fedora_android": {"COMMON": _fedora_common},
"debian_native_dyn": {
"COMMON": _debian_common + ["libbz2-dev", "libmagic-dev"],
"zlib": ["zlib1g-dev"],
"uuid": ["uuid-dev"],
"libmicrohttpd": ["libmicrohttpd-dev", "ccache"],
"qt": ["libqt5gui5", "qtbase5-dev", "qt5-default"],
"qtwebengine": ["qtwebengine5-dev"],
"aria2": ["aria2"],
}, },
'fedora_armhf_dyn': { "debian_native_static": {
'COMMON': _fedora_common "COMMON": _debian_common + ["libbz2-dev", "libmagic-dev"],
}, },
'fedora_android': { "debian_i586_dyn": {
'COMMON': _fedora_common "COMMON": _debian_common
+ ["libc6-dev-i386", "lib32stdc++6", "gcc-multilib", "g++-multilib"],
}, },
'debian_native_dyn': { "debian_i586_static": {
'COMMON': _debian_common + ['libbz2-dev', 'libmagic-dev'], "COMMON": _debian_common
'zlib': ['zlib1g-dev'], + ["libc6-dev-i386", "lib32stdc++6", "gcc-multilib", "g++-multilib"],
'uuid': ['uuid-dev'],
'libmicrohttpd': ['libmicrohttpd-dev', 'ccache'],
'qt' : ['libqt5gui5', 'qtbase5-dev', 'qt5-default'],
'qtwebengine' : ['qtwebengine5-dev'],
'aria2': ['aria2'],
}, },
'debian_native_static': { "debian_win32_dyn": {
'COMMON': _debian_common + ['libbz2-dev', 'libmagic-dev'], "COMMON": _debian_common
+ [
"g++-mingw-w64-i686",
"gcc-mingw-w64-i686",
"gcc-mingw-w64-base",
"mingw-w64-tools",
],
}, },
'debian_i586_dyn': { "debian_win32_static": {
'COMMON': _debian_common + ['libc6-dev-i386', 'lib32stdc++6', 'gcc-multilib', 'g++-multilib'], "COMMON": _debian_common
+ [
"g++-mingw-w64-i686",
"gcc-mingw-w64-i686",
"gcc-mingw-w64-base",
"mingw-w64-tools",
],
}, },
'debian_i586_static': { "debian_armhf_static": {
'COMMON': _debian_common + ['libc6-dev-i386', 'lib32stdc++6', 'gcc-multilib', 'g++-multilib'], "COMMON": _debian_common,
}, },
'debian_win32_dyn': { "debian_armhf_dyn": {
'COMMON': _debian_common + ['g++-mingw-w64-i686', 'gcc-mingw-w64-i686', 'gcc-mingw-w64-base', 'mingw-w64-tools'], "COMMON": _debian_common,
}, },
'debian_win32_static': { "debian_android": {
'COMMON': _debian_common + ['g++-mingw-w64-i686', 'gcc-mingw-w64-i686', 'gcc-mingw-w64-base', 'mingw-w64-tools'], "COMMON": _debian_common,
}, },
'debian_armhf_static': { "Darwin_native_dyn": {
'COMMON': _debian_common, "COMMON": ["autoconf", "automake", "libtool", "cmake", "pkg-config"],
"file": ["libmagic"],
}, },
'debian_armhf_dyn': { "Darwin_iOS": {
'COMMON': _debian_common, "COMMON": ["autoconf", "automake", "libtool", "cmake", "pkg-config"],
}, "file": ["libmagic"],
'debian_android': {
'COMMON': _debian_common,
},
'Darwin_native_dyn': {
'COMMON': ['autoconf', 'automake', 'libtool', 'cmake', 'pkg-config'],
'file': ['libmagic']
},
'Darwin_iOS': {
'COMMON': ['autoconf', 'automake', 'libtool', 'cmake', 'pkg-config'],
'file': ['libmagic']
}, },
} }

View File

@ -1,15 +1,3 @@
from .base import * from .base import *
from . import ( from . import android, armhf, musl, flatpak, i586, ios, native, neutral, win32, wasm
android,
armhf,
musl,
flatpak,
i586,
ios,
native,
neutral,
win32,
wasm
)

View File

@ -4,137 +4,152 @@ from kiwixbuild._global import get_target_step, option
class AndroidPlatformInfo(PlatformInfo): class AndroidPlatformInfo(PlatformInfo):
build = 'android' build = "android"
static = True static = True
toolchain_names = ['android-ndk'] toolchain_names = ["android-ndk"]
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
def __str__(self): def __str__(self):
return "android" return "android"
@property @property
def libdir(self): def libdir(self):
return 'lib/{}'.format(self.arch_full) return "lib/{}".format(self.arch_full)
@property @property
def binaries_name(self): def binaries_name(self):
arch_full = self.arch_full arch_full = self.arch_full
return { return {
'CC': '{}-{}'.format(arch_full, 'clang'), "CC": "{}-{}".format(arch_full, "clang"),
'CXX': '{}-{}'.format(arch_full, 'clang++'), "CXX": "{}-{}".format(arch_full, "clang++"),
'AR': '{}-{}'.format(arch_full, 'ar'), "AR": "{}-{}".format(arch_full, "ar"),
'STRIP': '{}-{}'.format(arch_full, 'strip'), "STRIP": "{}-{}".format(arch_full, "strip"),
'RANLIB': '{}-{}'.format(arch_full, 'ranlib'), "RANLIB": "{}-{}".format(arch_full, "ranlib"),
'LD': '{}-{}'.format(arch_full, 'ld') "LD": "{}-{}".format(arch_full, "ld"),
} }
def binaries(self): def binaries(self):
install_path = self.install_path install_path = self.install_path
binaries = {k:pj(install_path, 'bin', v) binaries = {
for k,v in self.binaries_name.items()} k: pj(install_path, "bin", v) for k, v in self.binaries_name.items()
binaries['PKGCONFIG'] = 'pkg-config' }
binaries["PKGCONFIG"] = "pkg-config"
return binaries return binaries
@property @property
def ndk_builder(self): def ndk_builder(self):
return get_target_step('android-ndk', self.name) return get_target_step("android-ndk", self.name)
@property @property
def install_path(self): def install_path(self):
return self.ndk_builder.install_path return self.ndk_builder.install_path
def get_cross_config(self): def get_cross_config(self):
extra_libs = ['-llog'] extra_libs = ["-llog"]
extra_cflags = ['-I{}'.format(include_dir) for include_dir in self.get_include_dirs()] extra_cflags = [
if hasattr(self, 'march'): "-I{}".format(include_dir) for include_dir in self.get_include_dirs()
extra_libs.append('-march={}'.format(self.march)) ]
extra_cflags.append('-march={}'.format(self.march)) if hasattr(self, "march"):
extra_libs.append("-march={}".format(self.march))
extra_cflags.append("-march={}".format(self.march))
return { return {
'exe_wrapper_def': '', "exe_wrapper_def": "",
'install_path': self.install_path, "install_path": self.install_path,
'binaries': self.binaries(), "binaries": self.binaries(),
'root_path': pj(self.install_path, 'sysroot'), "root_path": pj(self.install_path, "sysroot"),
'extra_libs': extra_libs, "extra_libs": extra_libs,
'extra_cflags': extra_cflags, "extra_cflags": extra_cflags,
'host_machine': { "host_machine": {
'system': 'Android', "system": "Android",
'lsystem': 'android', "lsystem": "android",
'cpu_family': self.arch, "cpu_family": self.arch,
'cpu': self.cpu, "cpu": self.cpu,
'endian': 'little', "endian": "little",
'abi': self.abi "abi": self.abi,
} },
} }
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
root_path = pj(self.install_path, 'sysroot') root_path = pj(self.install_path, "sysroot")
env['PKG_CONFIG_LIBDIR'] = pj(root_path, 'lib', 'pkgconfig') env["PKG_CONFIG_LIBDIR"] = pj(root_path, "lib", "pkgconfig")
env['NDK_DEBUG'] = '0' env["NDK_DEBUG"] = "0"
return env return env
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.install_path, 'bin')] return [pj(self.install_path, "bin")]
def set_comp_flags(self, env): def set_comp_flags(self, env):
super().set_comp_flags(env) super().set_comp_flags(env)
root_path = pj(self.install_path, 'sysroot') root_path = pj(self.install_path, "sysroot")
march = '-march={}'.format(self.march) if hasattr(self,'march') else '' march = "-march={}".format(self.march) if hasattr(self, "march") else ""
env['CFLAGS'] = '-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} {} '.format(root_path, march) + env['CFLAGS'] env["CFLAGS"] = (
env['CXXFLAGS'] = '-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} {} '.format(root_path, march) + env['CXXFLAGS'] "-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} {} ".format(
env['LDFLAGS'] = '--sysroot={} {} '.format(root_path, march) + env['LDFLAGS'] root_path, march
)
+ env["CFLAGS"]
)
env["CXXFLAGS"] = (
"-fPIC -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 --sysroot={} {} ".format(
root_path, march
)
+ env["CXXFLAGS"]
)
env["LDFLAGS"] = "--sysroot={} {} ".format(root_path, march) + env["LDFLAGS"]
def set_compiler(self, env): def set_compiler(self, env):
binaries = self.binaries() binaries = self.binaries()
for k,v in binaries.items(): for k, v in binaries.items():
env[k] = v env[k] = v
@property @property
def configure_options(self): def configure_options(self):
yield '--host={}'.format(self.arch_full) yield "--host={}".format(self.arch_full)
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_android_cross_file.txt', 'cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile(
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') "cmake_android_cross_file.txt", "cmake_cross_file.txt"
)
self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")
class AndroidArm(AndroidPlatformInfo): class AndroidArm(AndroidPlatformInfo):
name = 'android_arm' name = "android_arm"
arch = cpu = 'arm' arch = cpu = "arm"
arch_full = 'arm-linux-androideabi' arch_full = "arm-linux-androideabi"
abi = 'armeabi-v7a' abi = "armeabi-v7a"
march = 'armv7-a' march = "armv7-a"
class AndroidArm64(AndroidPlatformInfo): class AndroidArm64(AndroidPlatformInfo):
name = 'android_arm64' name = "android_arm64"
arch = 'arm64' arch = "arm64"
arch_full = 'aarch64-linux-android' arch_full = "aarch64-linux-android"
cpu = 'aarch64' cpu = "aarch64"
abi = 'arm64-v8a' abi = "arm64-v8a"
class AndroidX86(AndroidPlatformInfo): class AndroidX86(AndroidPlatformInfo):
name = 'android_x86' name = "android_x86"
arch = abi = 'x86' arch = abi = "x86"
arch_full = 'i686-linux-android' arch_full = "i686-linux-android"
cpu = 'i686' cpu = "i686"
class AndroidX8664(AndroidPlatformInfo): class AndroidX8664(AndroidPlatformInfo):
name = 'android_x86_64' name = "android_x86_64"
arch = cpu = abi = 'x86_64' arch = cpu = abi = "x86_64"
arch_full = 'x86_64-linux-android' arch_full = "x86_64-linux-android"
class Android(MetaPlatformInfo): class Android(MetaPlatformInfo):
name = "android" name = "android"
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
@property @property
def subPlatformNames(self): def subPlatformNames(self):
return ['android_{}'.format(arch) for arch in option('android_arch')] return ["android_{}".format(arch) for arch in option("android_arch")]
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
return super().add_targets(targetName, targets) return super().add_targets(targetName, targets)

View File

@ -6,23 +6,25 @@ from kiwixbuild._global import get_target_step
# Base platform # Base platform
class ArmPlatformInfo(PlatformInfo): class ArmPlatformInfo(PlatformInfo):
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
def get_cross_config(self): def get_cross_config(self):
return { return {
'binaries': self.binaries, "binaries": self.binaries,
'exe_wrapper_def': '', "exe_wrapper_def": "",
'root_path': self.root_path, "root_path": self.root_path,
'extra_libs': [], "extra_libs": [],
'extra_cflags': ['-I{}'.format(include_dir) for include_dir in self.get_include_dirs()], "extra_cflags": [
'host_machine': { "-I{}".format(include_dir) for include_dir in self.get_include_dirs()
'system': 'linux', ],
'lsystem': 'linux', "host_machine": {
'cpu_family': self.cpu_family, "system": "linux",
'cpu': self.cpu, "lsystem": "linux",
'endian': 'little', "cpu_family": self.cpu_family,
'abi': '' "cpu": self.cpu,
} "endian": "little",
"abi": "",
},
} }
@property @property
@ -31,7 +33,7 @@ class ArmPlatformInfo(PlatformInfo):
@property @property
def toolchain(self): def toolchain(self):
return get_target_step(self.build, 'neutral') return get_target_step(self.build, "neutral")
@property @property
def root_path(self): def root_path(self):
@ -39,26 +41,27 @@ class ArmPlatformInfo(PlatformInfo):
@property @property
def binaries(self): def binaries(self):
binaries = ((k,'{}-{}'.format(self.arch_full, v)) binaries = (
for k, v in (('CC', 'gcc'), (k, "{}-{}".format(self.arch_full, v))
('CXX', 'g++'), for k, v in (
('AR', 'ar'), ("CC", "gcc"),
('STRIP', 'strip'), ("CXX", "g++"),
('WINDRES', 'windres'), ("AR", "ar"),
('RANLIB', 'ranlib'), ("STRIP", "strip"),
('LD', 'ld'), ("WINDRES", "windres"),
('LDSHARED', 'g++ -shared') ("RANLIB", "ranlib"),
) ("LD", "ld"),
) ("LDSHARED", "g++ -shared"),
binaries = {k:pj(self.root_path, 'bin', v) )
for k,v in binaries} )
binaries['PKGCONFIG'] = 'pkg-config' binaries = {k: pj(self.root_path, "bin", v) for k, v in binaries}
binaries["PKGCONFIG"] = "pkg-config"
return binaries return binaries
@property @property
def exe_wrapper_def(self): def exe_wrapper_def(self):
try: try:
which('qemu-arm') which("qemu-arm")
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return "" return ""
else: else:
@ -66,31 +69,39 @@ class ArmPlatformInfo(PlatformInfo):
@property @property
def configure_options(self): def configure_options(self):
yield '--host={}'.format(self.arch_full) yield "--host={}".format(self.arch_full)
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.root_path, 'bin')] return [pj(self.root_path, "bin")]
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['LD_LIBRARY_PATH'] = ':'.join([ env["LD_LIBRARY_PATH"] = ":".join(
pj(self.root_path, self.arch_full, 'lib64'), [
pj(self.root_path, 'lib'), pj(self.root_path, self.arch_full, "lib64"),
env['LD_LIBRARY_PATH'] pj(self.root_path, "lib"),
]) env["LD_LIBRARY_PATH"],
env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') ]
env['QEMU_LD_PREFIX'] = pj(self.root_path, self.arch_full, "libc") )
env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format( env["PKG_CONFIG_LIBDIR"] = pj(self.root_path, "lib", "pkgconfig")
':'.join([ env["QEMU_LD_PREFIX"] = pj(self.root_path, self.arch_full, "libc")
pj(self.root_path, self.arch_full, "lib"), env["QEMU_SET_ENV"] = "LD_LIBRARY_PATH={}".format(
env['LD_LIBRARY_PATH'] ":".join(
])) [pj(self.root_path, self.arch_full, "lib"), env["LD_LIBRARY_PATH"]]
)
)
return env return env
def set_comp_flags(self, env): def set_comp_flags(self, env):
super().set_comp_flags(env) super().set_comp_flags(env)
env['CFLAGS'] = " -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CFLAGS'] env["CFLAGS"] = (
env['CXXFLAGS'] = " -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CXXFLAGS'] " -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "
+ env["CFLAGS"]
)
env["CXXFLAGS"] = (
" -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "
+ env["CXXFLAGS"]
)
def set_compiler(self, env): def set_compiler(self, env):
for k, v in self.binaries.items(): for k, v in self.binaries.items():
@ -98,69 +109,78 @@ class ArmPlatformInfo(PlatformInfo):
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile("cmake_cross_file.txt")
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")
class Armv6(ArmPlatformInfo): class Armv6(ArmPlatformInfo):
build = "armv6" build = "armv6"
arch_full = "armv6-rpi-linux-gnueabihf" arch_full = "armv6-rpi-linux-gnueabihf"
toolchain_names = ['armv6'] toolchain_names = ["armv6"]
cpu_family = 'arm' cpu_family = "arm"
cpu = 'armv6' cpu = "armv6"
class Armv6Dyn(Armv6): class Armv6Dyn(Armv6):
name = 'armv6_dyn' name = "armv6_dyn"
static = False static = False
class Armv6Static(Armv6): class Armv6Static(Armv6):
name = 'armv6_static' name = "armv6_static"
static = True static = True
class Armv6Mixed(MixedMixin('armv6_static'), Armv6):
name = 'armv6_mixed' class Armv6Mixed(MixedMixin("armv6_static"), Armv6):
name = "armv6_mixed"
static = False static = False
class Armv8(ArmPlatformInfo): class Armv8(ArmPlatformInfo):
build = "armv8" build = "armv8"
arch_full = "armv8-rpi3-linux-gnueabihf" arch_full = "armv8-rpi3-linux-gnueabihf"
toolchain_names = ['armv8'] toolchain_names = ["armv8"]
cpu_family = 'arm' cpu_family = "arm"
cpu = 'armv8' cpu = "armv8"
class Armv8Dyn(Armv8): class Armv8Dyn(Armv8):
name = 'armv8_dyn' name = "armv8_dyn"
static = False static = False
class Armv8Static(Armv8): class Armv8Static(Armv8):
name = 'armv8_static' name = "armv8_static"
static = True static = True
class Armv8Mixed(MixedMixin('armv8_static'), Armv8):
name = 'armv8_mixed' class Armv8Mixed(MixedMixin("armv8_static"), Armv8):
name = "armv8_mixed"
static = False static = False
class Aarch64(ArmPlatformInfo): class Aarch64(ArmPlatformInfo):
build = 'aarch64' build = "aarch64"
arch_full = 'aarch64-linux-gnu' arch_full = "aarch64-linux-gnu"
toolchain_names = ['aarch64'] toolchain_names = ["aarch64"]
cpu_family = 'aarch64' cpu_family = "aarch64"
cpu = 'aarch64' cpu = "aarch64"
@property @property
def root_path(self): def root_path(self):
return self.toolchain.build_path return self.toolchain.build_path
class Aarch64Dyn(Aarch64): class Aarch64Dyn(Aarch64):
name = 'aarch64_dyn' name = "aarch64_dyn"
static = False static = False
class Aarch64Static(Aarch64): class Aarch64Static(Aarch64):
name = 'aarch64_static' name = "aarch64_static"
static = True static = True
class Aarch64Mixed(MixedMixin('aarch64_static'), Aarch64): class Aarch64Mixed(MixedMixin("aarch64_static"), Aarch64):
name = 'aarch64_mixed' name = "aarch64_mixed"
static = False static = False

View File

@ -1,4 +1,3 @@
import os, sys import os, sys
import subprocess import subprocess
@ -8,13 +7,14 @@ from kiwixbuild.buildenv import BuildEnv
from kiwixbuild._global import neutralEnv, option, target_steps from kiwixbuild._global import neutralEnv, option, target_steps
_SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) _SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
TEMPLATES_DIR = pj(os.path.dirname(_SCRIPT_DIR), 'templates') TEMPLATES_DIR = pj(os.path.dirname(_SCRIPT_DIR), "templates")
class _MetaPlatform(type): class _MetaPlatform(type):
def __new__(cls, name, bases, dct): def __new__(cls, name, bases, dct):
_class = type.__new__(cls, name, bases, dct) _class = type.__new__(cls, name, bases, dct)
if name not in ('PlatformInfo', 'MetaPlatformInfo') and 'name' in dct: if name not in ("PlatformInfo", "MetaPlatformInfo") and "name" in dct:
dep_name = dct['name'] dep_name = dct["name"]
PlatformInfo.all_platforms[dep_name] = _class PlatformInfo.all_platforms[dep_name] = _class
return _class return _class
@ -43,20 +43,20 @@ class PlatformInfo(metaclass=_MetaPlatform):
self.setup_toolchains(targets) self.setup_toolchains(targets)
def __str__(self): def __str__(self):
return "{}_{}".format(self.build, 'static' if self.static else 'dyn') return "{}_{}".format(self.build, "static" if self.static else "dyn")
def setup_toolchains(self, targets): def setup_toolchains(self, targets):
for tlc_name in self.toolchain_names: for tlc_name in self.toolchain_names:
ToolchainClass = Dependency.all_deps[tlc_name] ToolchainClass = Dependency.all_deps[tlc_name]
targets[('source', tlc_name)] = ToolchainClass.Source targets[("source", tlc_name)] = ToolchainClass.Source
plt_name = 'neutral' if ToolchainClass.neutral else self.name plt_name = "neutral" if ToolchainClass.neutral else self.name
targets[(plt_name, tlc_name)] = ToolchainClass.Builder targets[(plt_name, tlc_name)] = ToolchainClass.Builder
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
if (self.name, targetName) in targets: if (self.name, targetName) in targets:
return [] return []
targetClass = Dependency.all_deps[targetName] targetClass = Dependency.all_deps[targetName]
targets[('source', targetName)] = targetClass.Source targets[("source", targetName)] = targetClass.Source
targets[(self.name, targetName)] = targetClass.Builder targets[(self.name, targetName)] = targetClass.Builder
for dep in targetClass.Builder.get_dependencies(self, False): for dep in targetClass.Builder.get_dependencies(self, False):
if isinstance(dep, tuple): if isinstance(dep, tuple):
@ -68,47 +68,40 @@ class PlatformInfo(metaclass=_MetaPlatform):
return [(self.name, targetName)] return [(self.name, targetName)]
def get_fully_qualified_dep(self, dep): def get_fully_qualified_dep(self, dep):
if isinstance(dep, tuple): if isinstance(dep, tuple):
return dep return dep
else: else:
return self.name, dep return self.name, dep
def get_cross_config(self): def get_cross_config(self):
return {} return {}
def get_include_dirs(self): def get_include_dirs(self):
return [pj(self.buildEnv.install_dir, 'include')] return [pj(self.buildEnv.install_dir, "include")]
def get_env(self): def get_env(self):
return DefaultEnv() return DefaultEnv()
def get_bin_dir(self): def get_bin_dir(self):
return [] return []
def set_compiler(self, env): def set_compiler(self, env):
pass pass
def set_comp_flags(self, env): def set_comp_flags(self, env):
if self.static: if self.static:
env['CFLAGS'] = env['CFLAGS'] + ' -fPIC' env["CFLAGS"] = env["CFLAGS"] + " -fPIC"
env['CXXFLAGS'] = env['CXXFLAGS'] + ' -fPIC' env["CXXFLAGS"] = env["CXXFLAGS"] + " -fPIC"
def _gen_crossfile(self, name, outname=None): def _gen_crossfile(self, name, outname=None):
if outname is None: if outname is None:
outname = name outname = name
crossfile = pj(self.buildEnv.build_dir, outname) crossfile = pj(self.buildEnv.build_dir, outname)
template_file = pj(TEMPLATES_DIR, name) template_file = pj(TEMPLATES_DIR, name)
with open(template_file, 'r') as f: with open(template_file, "r") as f:
template = f.read() template = f.read()
content = template.format( content = template.format(**self.get_cross_config())
**self.get_cross_config() with open(crossfile, "w") as outfile:
)
with open(crossfile, 'w') as outfile:
outfile.write(content) outfile.write(content)
return crossfile return crossfile
@ -121,7 +114,6 @@ class PlatformInfo(metaclass=_MetaPlatform):
self.buildEnv.clean_intermediate_directories() self.buildEnv.clean_intermediate_directories()
class MetaPlatformInfo(PlatformInfo): class MetaPlatformInfo(PlatformInfo):
subPlatformNames = [] subPlatformNames = []
@ -133,7 +125,6 @@ class MetaPlatformInfo(PlatformInfo):
return targetDefs return targetDefs
def MixedMixin(static_name): def MixedMixin(static_name):
class MixedMixinClass: class MixedMixinClass:
mixed = True mixed = True
@ -141,7 +132,7 @@ def MixedMixin(static_name):
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
print(targetName) print(targetName)
if option('target') == targetName: if option("target") == targetName:
return super().add_targets(targetName, targets) return super().add_targets(targetName, targets)
else: else:
static_platform = self.get_platform(static_name, targets) static_platform = self.get_platform(static_name, targets)
@ -150,7 +141,7 @@ def MixedMixin(static_name):
def get_fully_qualified_dep(self, dep): def get_fully_qualified_dep(self, dep):
if isinstance(dep, tuple): if isinstance(dep, tuple):
return dep return dep
if option('target') == dep: if option("target") == dep:
return self.name, dep return self.name, dep
return static_name, dep return static_name, dep
@ -161,16 +152,27 @@ def MixedMixin(static_name):
def get_include_dirs(self): def get_include_dirs(self):
return [ return [
pj(self.buildEnv.install_dir, 'include'), pj(self.buildEnv.install_dir, "include"),
pj(self.static_buildEnv.install_dir, 'include') pj(self.static_buildEnv.install_dir, "include"),
] ]
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['PATH'] = ':'.join([pj(self.static_buildEnv.install_dir, 'bin')] + [env['PATH']]) env["PATH"] = ":".join(
pkgconfig_path = pj(self.static_buildEnv.install_dir, self.static_buildEnv.libprefix, 'pkgconfig') [pj(self.static_buildEnv.install_dir, "bin")] + [env["PATH"]]
env['PKG_CONFIG_PATH'] = ':'.join([env['PKG_CONFIG_PATH'], pkgconfig_path]) )
env['CPPFLAGS'] = " ".join(['-I'+pj(self.static_buildEnv.install_dir, 'include'), env['CPPFLAGS']]) pkgconfig_path = pj(
self.static_buildEnv.install_dir,
self.static_buildEnv.libprefix,
"pkgconfig",
)
env["PKG_CONFIG_PATH"] = ":".join([env["PKG_CONFIG_PATH"], pkgconfig_path])
env["CPPFLAGS"] = " ".join(
[
"-I" + pj(self.static_buildEnv.install_dir, "include"),
env["CPPFLAGS"],
]
)
return env return env
return MixedMixinClass return MixedMixinClass

View File

@ -1,18 +1,18 @@
from .base import PlatformInfo from .base import PlatformInfo
from kiwixbuild._global import option, neutralEnv from kiwixbuild._global import option, neutralEnv
class FlatpakPlatformInfo(PlatformInfo): class FlatpakPlatformInfo(PlatformInfo):
name = 'flatpak' name = "flatpak"
build = 'flatpak' build = "flatpak"
static = '' static = ""
toolchain_names = ['org.kde', 'io.qt.qtwebengine'] toolchain_names = ["org.kde", "io.qt.qtwebengine"]
compatible_hosts = ['debian', 'fedora'] compatible_hosts = ["debian", "fedora"]
def __str__(self): def __str__(self):
return "flatpak" return "flatpak"
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['FLATPAK_USER_DIR'] = self.buildEnv.build_dir env["FLATPAK_USER_DIR"] = self.buildEnv.build_dir
return env return env

View File

@ -5,66 +5,75 @@ from kiwixbuild.utils import which, pj
class I586PlatformInfo(PlatformInfo): class I586PlatformInfo(PlatformInfo):
build = 'i586' build = "i586"
arch_full = 'i586-linux-gnu' arch_full = "i586-linux-gnu"
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
def get_cross_config(self): def get_cross_config(self):
return { return {
'binaries': self.binaries, "binaries": self.binaries,
'exe_wrapper_def': '', "exe_wrapper_def": "",
'extra_libs': ['-m32', '-march=i586', '-mno-sse'], "extra_libs": ["-m32", "-march=i586", "-mno-sse"],
'extra_cflags': [ "extra_cflags": [
'-m32', "-m32",
'-march=i586', "-march=i586",
'-mno-sse', "-mno-sse",
*('-I{}'.format(include_dir) for include_dir in self.get_include_dirs()) *(
"-I{}".format(include_dir)
for include_dir in self.get_include_dirs()
),
], ],
'host_machine': { "host_machine": {
'system': 'linux', "system": "linux",
'lsystem': 'linux', "lsystem": "linux",
'cpu_family': 'x86', "cpu_family": "x86",
'cpu': 'i586', "cpu": "i586",
'endian': 'little', "endian": "little",
'abi': '' "abi": "",
} },
} }
@property @property
def configure_options(self): def configure_options(self):
yield f'--host={self.arch_full}' yield f"--host={self.arch_full}"
@property @property
def binaries(self): def binaries(self):
return {k:which(v) return {
for k, v in (('CC', os.environ.get('CC', 'gcc')), k: which(v)
('CXX', os.environ.get('CXX', 'g++')), for k, v in (
('AR', 'ar'), ("CC", os.environ.get("CC", "gcc")),
('STRIP', 'strip'), ("CXX", os.environ.get("CXX", "g++")),
('RANLIB', 'ranlib'), ("AR", "ar"),
('LD', 'ld'), ("STRIP", "strip"),
('PKGCONFIG', 'pkg-config')) ("RANLIB", "ranlib"),
} ("LD", "ld"),
("PKGCONFIG", "pkg-config"),
)
}
def set_comp_flags(self, env): def set_comp_flags(self, env):
super().set_comp_flags(env) super().set_comp_flags(env)
env['CFLAGS'] = "-m32 -march=i586 -mno-sse "+env['CFLAGS'] env["CFLAGS"] = "-m32 -march=i586 -mno-sse " + env["CFLAGS"]
env['CXXFLAGS'] = "-m32 -march=i586 -mno-sse "+env['CXXFLAGS'] env["CXXFLAGS"] = "-m32 -march=i586 -mno-sse " + env["CXXFLAGS"]
env['LDFLAGS'] = "-m32 -march=i586 -mno-sse "+env['LDFLAGS'] env["LDFLAGS"] = "-m32 -march=i586 -mno-sse " + env["LDFLAGS"]
def get_bin_dir(self): def get_bin_dir(self):
return [] return []
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_i586_cross_file.txt', 'cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile(
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') "cmake_i586_cross_file.txt", "cmake_cross_file.txt"
)
self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")
class I586Dyn(I586PlatformInfo): class I586Dyn(I586PlatformInfo):
name = 'i586_dyn' name = "i586_dyn"
static = False static = False
class I586Static(I586PlatformInfo): class I586Static(I586PlatformInfo):
name = 'i586_static' name = "i586_static"
static = True static = True

View File

@ -6,12 +6,13 @@ from .base import PlatformInfo, MetaPlatformInfo, MixedMixin
from kiwixbuild.dependencies.apple_xcframework import AppleXCFramework from kiwixbuild.dependencies.apple_xcframework import AppleXCFramework
MIN_MACOS_VERSION = '12.0' MIN_MACOS_VERSION = "12.0"
class ApplePlatformInfo(PlatformInfo): class ApplePlatformInfo(PlatformInfo):
build = 'iOS' build = "iOS"
static = True static = True
compatible_hosts = ['Darwin'] compatible_hosts = ["Darwin"]
arch = None arch = None
host = None host = None
target = None target = None
@ -35,168 +36,194 @@ class ApplePlatformInfo(PlatformInfo):
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_ios_cross_file.txt', 'cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile(
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_ios_cross_file.txt', 'meson_cross_file.txt') "cmake_ios_cross_file.txt", "cmake_cross_file.txt"
)
self.buildEnv.meson_crossfile = self._gen_crossfile(
"meson_ios_cross_file.txt", "meson_cross_file.txt"
)
def get_cross_config(self): def get_cross_config(self):
config = { config = {
'root_path': self.root_path, "root_path": self.root_path,
'binaries': self.binaries, "binaries": self.binaries,
'exe_wrapper_def': '', "exe_wrapper_def": "",
'extra_libs': [ "extra_libs": [
'-isysroot', self.root_path, "-isysroot",
'-arch', self.arch, self.root_path,
'-target', self.target, "-arch",
self.arch,
"-target",
self.target,
], ],
'extra_cflags': [ "extra_cflags": [
'-isysroot', self.root_path, "-isysroot",
'-arch', self.arch, self.root_path,
'-target', self.target, "-arch",
*('-I{}'.format(include_dir) for include_dir in self.get_include_dirs()) self.arch,
"-target",
self.target,
*(
"-I{}".format(include_dir)
for include_dir in self.get_include_dirs()
),
], ],
'host_machine': { "host_machine": {
'system': 'Darwin', "system": "Darwin",
'lsystem': 'darwin', "lsystem": "darwin",
'cpu_family': self.arch, "cpu_family": self.arch,
'cpu': self.cpu, "cpu": self.cpu,
'endian': '', "endian": "",
'abi': '' "abi": "",
} },
} }
if self.min_iphoneos_version: if self.min_iphoneos_version:
config['extra_libs'].append('-miphoneos-version-min={}'.format(self.min_iphoneos_version)) config["extra_libs"].append(
config['extra_cflags'].append('-miphoneos-version-min={}'.format(self.min_iphoneos_version)) "-miphoneos-version-min={}".format(self.min_iphoneos_version)
)
config["extra_cflags"].append(
"-miphoneos-version-min={}".format(self.min_iphoneos_version)
)
if self.min_macos_version: if self.min_macos_version:
config['extra_libs'].append('-mmacosx-version-min={}'.format(self.min_macos_version)) config["extra_libs"].append(
config['extra_cflags'].append('-mmacosx-version-min={}'.format(self.min_macos_version)) "-mmacosx-version-min={}".format(self.min_macos_version)
)
config["extra_cflags"].append(
"-mmacosx-version-min={}".format(self.min_macos_version)
)
return config return config
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
cflags = [env['CFLAGS']] cflags = [env["CFLAGS"]]
if self.min_iphoneos_version: if self.min_iphoneos_version:
cflags.append('-miphoneos-version-min={}'.format(self.min_iphoneos_version)) cflags.append("-miphoneos-version-min={}".format(self.min_iphoneos_version))
if self.min_macos_version: if self.min_macos_version:
cflags.append('-mmacosx-version-min={}'.format(self.min_macos_version)) cflags.append("-mmacosx-version-min={}".format(self.min_macos_version))
env['CFLAGS'] = ' '.join(cflags) env["CFLAGS"] = " ".join(cflags)
return env return env
def set_comp_flags(self, env): def set_comp_flags(self, env):
super().set_comp_flags(env) super().set_comp_flags(env)
cflags = [ cflags = [
'-isysroot {}'.format(self.root_path), "-isysroot {}".format(self.root_path),
'-arch {}'.format(self.arch), "-arch {}".format(self.arch),
'-target {}'.format(self.target), "-target {}".format(self.target),
env['CFLAGS'], env["CFLAGS"],
] ]
if self.min_iphoneos_version: if self.min_iphoneos_version:
cflags.append('-miphoneos-version-min={}'.format(self.min_iphoneos_version)) cflags.append("-miphoneos-version-min={}".format(self.min_iphoneos_version))
env['CFLAGS'] = ' '.join(cflags) env["CFLAGS"] = " ".join(cflags)
env['CXXFLAGS'] = ' '.join([ env["CXXFLAGS"] = " ".join(
env['CFLAGS'], [
'-std=c++11', env["CFLAGS"],
env['CXXFLAGS'], "-std=c++11",
]) env["CXXFLAGS"],
env['LDFLAGS'] = ' '.join([ ]
' -arch {}'.format(self.arch), )
'-isysroot {}'.format(self.root_path), env["LDFLAGS"] = " ".join(
]) [
" -arch {}".format(self.arch),
"-isysroot {}".format(self.root_path),
]
)
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.root_path, 'bin')] return [pj(self.root_path, "bin")]
@property @property
def binaries(self): def binaries(self):
return { return {
'CC': xrun_find('clang'), "CC": xrun_find("clang"),
'CXX': xrun_find('clang++'), "CXX": xrun_find("clang++"),
'AR': xrun_find('ar'), "AR": xrun_find("ar"),
'STRIP': xrun_find('strip'), "STRIP": xrun_find("strip"),
'RANLIB': xrun_find('ranlib'), "RANLIB": xrun_find("ranlib"),
'LD': xrun_find('ld'), "LD": xrun_find("ld"),
'PKGCONFIG': 'pkg-config', "PKGCONFIG": "pkg-config",
} }
@property @property
def configure_options(self): def configure_options(self):
yield f'--host={self.host}' yield f"--host={self.host}"
class iOSArm64(ApplePlatformInfo): class iOSArm64(ApplePlatformInfo):
name = 'iOS_arm64' name = "iOS_arm64"
arch = cpu = 'arm64' arch = cpu = "arm64"
host = 'arm-apple-darwin' host = "arm-apple-darwin"
target = 'aarch64-apple-ios' target = "aarch64-apple-ios"
sdk_name = 'iphoneos' sdk_name = "iphoneos"
min_iphoneos_version = '15.0' min_iphoneos_version = "15.0"
class iOSx64Simulator(ApplePlatformInfo): class iOSx64Simulator(ApplePlatformInfo):
name = 'iOSSimulator_x86_64' name = "iOSSimulator_x86_64"
arch = cpu = 'x86_64' arch = cpu = "x86_64"
host = 'x86_64-apple-darwin' host = "x86_64-apple-darwin"
target = 'x86-apple-ios-simulator' target = "x86-apple-ios-simulator"
sdk_name = 'iphonesimulator' sdk_name = "iphonesimulator"
min_iphoneos_version = '15.0' min_iphoneos_version = "15.0"
class iOSArm64Simulator(ApplePlatformInfo): class iOSArm64Simulator(ApplePlatformInfo):
name = 'iOSSimulator_arm64' name = "iOSSimulator_arm64"
arch = cpu = 'arm64' arch = cpu = "arm64"
host = 'arm-apple-darwin' host = "arm-apple-darwin"
target = 'aarch64-apple-ios-simulator' target = "aarch64-apple-ios-simulator"
sdk_name = 'iphonesimulator' sdk_name = "iphonesimulator"
min_iphoneos_version = '15.0' min_iphoneos_version = "15.0"
class macOSArm64(ApplePlatformInfo): class macOSArm64(ApplePlatformInfo):
name = 'macOS_arm64_static' name = "macOS_arm64_static"
arch = cpu = 'arm64' arch = cpu = "arm64"
host = 'aarch64-apple-darwin' host = "aarch64-apple-darwin"
target = 'arm64-apple-macos' target = "arm64-apple-macos"
sdk_name = 'macosx' sdk_name = "macosx"
min_iphoneos_version = None min_iphoneos_version = None
min_macos_version = MIN_MACOS_VERSION min_macos_version = MIN_MACOS_VERSION
class macOSArm64Mixed(MixedMixin('macOS_arm64_static'), ApplePlatformInfo): class macOSArm64Mixed(MixedMixin("macOS_arm64_static"), ApplePlatformInfo):
name = 'macOS_arm64_mixed' name = "macOS_arm64_mixed"
arch = cpu = 'arm64' arch = cpu = "arm64"
host = 'aarch64-apple-darwin' host = "aarch64-apple-darwin"
target = 'arm64-apple-macos' target = "arm64-apple-macos"
sdk_name = 'macosx' sdk_name = "macosx"
min_iphoneos_version = None min_iphoneos_version = None
min_macos_version = MIN_MACOS_VERSION min_macos_version = MIN_MACOS_VERSION
class macOSx64(ApplePlatformInfo): class macOSx64(ApplePlatformInfo):
name = 'macOS_x86_64' name = "macOS_x86_64"
arch = cpu = 'x86_64' arch = cpu = "x86_64"
host = 'x86_64-apple-darwin' host = "x86_64-apple-darwin"
target = 'x86_64-apple-macos' target = "x86_64-apple-macos"
sdk_name = 'macosx' sdk_name = "macosx"
min_iphoneos_version = None min_iphoneos_version = None
min_macos_version = MIN_MACOS_VERSION min_macos_version = MIN_MACOS_VERSION
class IOS(MetaPlatformInfo): class IOS(MetaPlatformInfo):
name = "iOS_multi" name = "iOS_multi"
compatible_hosts = ['Darwin'] compatible_hosts = ["Darwin"]
@property @property
def subPlatformNames(self): def subPlatformNames(self):
return ['iOS_{}'.format(arch) for arch in option('ios_arch')] return ["iOS_{}".format(arch) for arch in option("ios_arch")]
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
super().add_targets(targetName, targets) super().add_targets(targetName, targets)
return PlatformInfo.add_targets(self, '_ios_fat_lib', targets) return PlatformInfo.add_targets(self, "_ios_fat_lib", targets)
def __str__(self): def __str__(self):
return self.name return self.name
class AppleStaticAll(MetaPlatformInfo): class AppleStaticAll(MetaPlatformInfo):
name = "apple_all_static" name = "apple_all_static"
compatible_hosts = ['Darwin'] compatible_hosts = ["Darwin"]
@property @property
def subPlatformNames(self): def subPlatformNames(self):
@ -204,7 +231,7 @@ class AppleStaticAll(MetaPlatformInfo):
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
super().add_targets(targetName, targets) super().add_targets(targetName, targets)
return PlatformInfo.add_targets(self, 'apple_xcframework', targets) return PlatformInfo.add_targets(self, "apple_xcframework", targets)
def __str__(self): def __str__(self):
return self.name return self.name

View File

@ -5,28 +5,30 @@ from kiwixbuild._global import get_target_step
class MuslPlatformInfo(PlatformInfo): class MuslPlatformInfo(PlatformInfo):
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
def get_cross_config(self): def get_cross_config(self):
return { return {
'binaries': self.binaries, "binaries": self.binaries,
'exe_wrapper_def': '', "exe_wrapper_def": "",
'root_path': self.root_path, "root_path": self.root_path,
'extra_libs': [], "extra_libs": [],
'extra_cflags': ['-I{}'.format(include_dir) for include_dir in self.get_include_dirs()], "extra_cflags": [
'host_machine': { "-I{}".format(include_dir) for include_dir in self.get_include_dirs()
'system': 'linux', ],
'lsystem': 'linux', "host_machine": {
'cpu_family': self.cpu_family, "system": "linux",
'cpu': self.cpu, "lsystem": "linux",
'endian': 'little', "cpu_family": self.cpu_family,
'abi': '' "cpu": self.cpu,
} "endian": "little",
"abi": "",
},
} }
@property @property
def toolchain(self): def toolchain(self):
return get_target_step(self.build, 'neutral') return get_target_step(self.build, "neutral")
@property @property
def root_path(self): def root_path(self):
@ -34,20 +36,21 @@ class MuslPlatformInfo(PlatformInfo):
@property @property
def binaries(self): def binaries(self):
binaries = ((k,'{}-{}'.format(self.arch_full, v)) binaries = (
for k, v in (('CC', 'gcc'), (k, "{}-{}".format(self.arch_full, v))
('CXX', 'g++'), for k, v in (
('AR', 'ar'), ("CC", "gcc"),
('STRIP', 'strip'), ("CXX", "g++"),
('WINDRES', 'windres'), ("AR", "ar"),
('RANLIB', 'ranlib'), ("STRIP", "strip"),
('LD', 'ld'), ("WINDRES", "windres"),
('LDSHARED', 'g++ -shared') ("RANLIB", "ranlib"),
) ("LD", "ld"),
) ("LDSHARED", "g++ -shared"),
binaries = {k:pj(self.root_path, 'bin', v) )
for k,v in binaries} )
binaries['PKGCONFIG'] = 'pkg-config' binaries = {k: pj(self.root_path, "bin", v) for k, v in binaries}
binaries["PKGCONFIG"] = "pkg-config"
return binaries return binaries
@property @property
@ -63,35 +66,42 @@ class MuslPlatformInfo(PlatformInfo):
@property @property
def configure_options(self): def configure_options(self):
return [f'--host={self.arch_full}'] return [f"--host={self.arch_full}"]
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.root_path, 'bin')] return [pj(self.root_path, "bin")]
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['LD_LIBRARY_PATH'] = ':'.join([ env["LD_LIBRARY_PATH"] = ":".join(
pj(self.root_path, self.arch_full, 'lib64'), [
pj(self.root_path, 'lib'), pj(self.root_path, self.arch_full, "lib64"),
env['LD_LIBRARY_PATH'] pj(self.root_path, "lib"),
]) env["LD_LIBRARY_PATH"],
env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') ]
env['QEMU_LD_PREFIX'] = pj(self.root_path, self.arch_full, "libc") )
env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format( env["PKG_CONFIG_LIBDIR"] = pj(self.root_path, "lib", "pkgconfig")
':'.join([ env["QEMU_LD_PREFIX"] = pj(self.root_path, self.arch_full, "libc")
pj(self.root_path, self.arch_full, "lib"), env["QEMU_SET_ENV"] = "LD_LIBRARY_PATH={}".format(
env['LD_LIBRARY_PATH'] ":".join(
])) [pj(self.root_path, self.arch_full, "lib"), env["LD_LIBRARY_PATH"]]
)
)
return env return env
def set_comp_flags(self, env): def set_comp_flags(self, env):
super().set_comp_flags(env) super().set_comp_flags(env)
env['LD_LIBRARY_PATH'] = ':'.join([ env["LD_LIBRARY_PATH"] = ":".join(
pj(self.root_path, self.arch_full, 'lib'), [pj(self.root_path, self.arch_full, "lib"), env["LD_LIBRARY_PATH"]]
env['LD_LIBRARY_PATH'] )
]) env["CFLAGS"] = (
env['CFLAGS'] = " -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CFLAGS'] " -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "
env['CXXFLAGS'] = " -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CXXFLAGS'] + env["CFLAGS"]
)
env["CXXFLAGS"] = (
" -fPIC -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "
+ env["CXXFLAGS"]
)
def set_compiler(self, env): def set_compiler(self, env):
for k, v in self.binaries.items(): for k, v in self.binaries.items():
@ -99,50 +109,54 @@ class MuslPlatformInfo(PlatformInfo):
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile("cmake_cross_file.txt")
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")
class Aarch64MuslPlatformInfo(MuslPlatformInfo): class Aarch64MuslPlatformInfo(MuslPlatformInfo):
build = 'aarch64_musl' build = "aarch64_musl"
arch_full = 'aarch64-linux-musl' arch_full = "aarch64-linux-musl"
toolchain_names = ['aarch64_musl'] toolchain_names = ["aarch64_musl"]
libdir = "lib/aarch64-linux-musl" libdir = "lib/aarch64-linux-musl"
cpu_family = 'arm' cpu_family = "arm"
cpu = 'armhf' cpu = "armhf"
qemu = 'qemu-arm' qemu = "qemu-arm"
class Aarch64MuslDyn(Aarch64MuslPlatformInfo): class Aarch64MuslDyn(Aarch64MuslPlatformInfo):
name = 'aarch64_musl_dyn' name = "aarch64_musl_dyn"
static = False static = False
class Aarch64MuslStatic(Aarch64MuslPlatformInfo): class Aarch64MuslStatic(Aarch64MuslPlatformInfo):
name = 'aarch64_musl_static' name = "aarch64_musl_static"
static = True static = True
class Aarch64MuslMixed(MixedMixin('aarch64_musl_static'), Aarch64MuslPlatformInfo):
name = 'aarch64_musl_mixed' class Aarch64MuslMixed(MixedMixin("aarch64_musl_static"), Aarch64MuslPlatformInfo):
name = "aarch64_musl_mixed"
static = False static = False
class X86_64MuslPlatformInfo(MuslPlatformInfo): class X86_64MuslPlatformInfo(MuslPlatformInfo):
build = 'x86-64_musl' build = "x86-64_musl"
arch_full = 'x86_64-linux-musl' arch_full = "x86_64-linux-musl"
toolchain_names = ['x86-64_musl'] toolchain_names = ["x86-64_musl"]
libdir = "lib/x86_64-linux-musl" libdir = "lib/x86_64-linux-musl"
cpu_family = 'x86_64' cpu_family = "x86_64"
cpu = 'x86_64' cpu = "x86_64"
class X86_64MuslDyn(X86_64MuslPlatformInfo): class X86_64MuslDyn(X86_64MuslPlatformInfo):
name = 'x86-64_musl_dyn' name = "x86-64_musl_dyn"
static = False static = False
class X86_64MuslStatic(X86_64MuslPlatformInfo): class X86_64MuslStatic(X86_64MuslPlatformInfo):
name = 'x86-64_musl_static' name = "x86-64_musl_static"
static = True static = True
class x86_64MuslMixed(MixedMixin('x86-64_musl_static'), X86_64MuslPlatformInfo):
name = 'x86-64_musl_mixed' class x86_64MuslMixed(MixedMixin("x86-64_musl_static"), X86_64MuslPlatformInfo):
name = "x86-64_musl_mixed"
static = False static = False

View File

@ -4,29 +4,32 @@ from kiwixbuild.utils import pj
from kiwixbuild._global import option, neutralEnv from kiwixbuild._global import option, neutralEnv
from kiwixbuild.platforms.ios import MIN_MACOS_VERSION from kiwixbuild.platforms.ios import MIN_MACOS_VERSION
class NativePlatformInfo(PlatformInfo): class NativePlatformInfo(PlatformInfo):
build = 'native' build = "native"
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
if neutralEnv('distname') == 'fedora': if neutralEnv("distname") == "fedora":
env['QT_SELECT'] = "5-64" env["QT_SELECT"] = "5-64"
if neutralEnv('distname') == 'Darwin': if neutralEnv("distname") == "Darwin":
env['CFLAGS'] += f'-mmacosx-version-min={MIN_MACOS_VERSION}' env["CFLAGS"] += f"-mmacosx-version-min={MIN_MACOS_VERSION}"
return env return env
class NativeDyn(NativePlatformInfo): class NativeDyn(NativePlatformInfo):
name = 'native_dyn' name = "native_dyn"
static = False static = False
compatible_hosts = ['fedora', 'debian', 'Darwin'] compatible_hosts = ["fedora", "debian", "Darwin"]
class NativeStatic(NativePlatformInfo): class NativeStatic(NativePlatformInfo):
name = 'native_static' name = "native_static"
static = True static = True
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
class NativeMixed(MixedMixin('native_static'), NativePlatformInfo):
name = 'native_mixed' class NativeMixed(MixedMixin("native_static"), NativePlatformInfo):
name = "native_mixed"
static = False static = False
compatible_hosts = ['fedora', 'debian', 'Darwin'] compatible_hosts = ["fedora", "debian", "Darwin"]

View File

@ -1,9 +1,10 @@
from .base import PlatformInfo from .base import PlatformInfo
class NeutralPlatformInfo(PlatformInfo): class NeutralPlatformInfo(PlatformInfo):
name = 'neutral' name = "neutral"
static = '' static = ""
compatible_hosts = ['fedora', 'debian', 'Darwin'] compatible_hosts = ["fedora", "debian", "Darwin"]
def __str__(self): def __str__(self):
return "neutral" return "neutral"

View File

@ -5,36 +5,36 @@ from kiwixbuild._global import get_target_step
class WasmPlatformInfo(PlatformInfo): class WasmPlatformInfo(PlatformInfo):
name = 'wasm' name = "wasm"
static = True static = True
build = 'wasm' build = "wasm"
arch_full = 'wasm64-emscripten' arch_full = "wasm64-emscripten"
libdir = "lib" libdir = "lib"
#arch_full = 'wasm64-linux' # arch_full = 'wasm64-linux'
toolchain_names = ['emsdk'] toolchain_names = ["emsdk"]
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
exe_wrapper_def = "" exe_wrapper_def = ""
def get_cross_config(self): def get_cross_config(self):
return { return {
'binaries': self.binaries, "binaries": self.binaries,
'exe_wrapper_def': '', "exe_wrapper_def": "",
'root_path': self.root_path, "root_path": self.root_path,
'extra_libs': [], "extra_libs": [],
'extra_cflags': [], "extra_cflags": [],
'host_machine': { "host_machine": {
'system': 'emscripten', "system": "emscripten",
'lsystem': 'emscripten', "lsystem": "emscripten",
'cpu_family': 'wasm64', "cpu_family": "wasm64",
'cpu': 'wasm64', "cpu": "wasm64",
'endian': 'little', "endian": "little",
'abi': '' "abi": "",
} },
} }
@property @property
def wasm_sdk(self): def wasm_sdk(self):
return get_target_step('emsdk', self.name) return get_target_step("emsdk", self.name)
@property @property
def install_path(self): def install_path(self):
@ -46,22 +46,25 @@ class WasmPlatformInfo(PlatformInfo):
@property @property
def binaries(self): def binaries(self):
binaries = (('CC', 'emcc'), binaries = (
('CXX', 'em++'), ("CC", "emcc"),
('AR', 'emar'), ("CXX", "em++"),
('STRIP', 'emstrip'), ("AR", "emar"),
('WINDRES', 'windres'), ("STRIP", "emstrip"),
('RANLIB', 'emranlib'), ("WINDRES", "windres"),
('LD', 'wasm-ld')) ("RANLIB", "emranlib"),
binaries = {k:pj(self.install_path, 'upstream', 'emscripten', v) ("LD", "wasm-ld"),
for k,v in binaries} )
binaries['PKGCONFIG'] = 'pkg-config' binaries = {
k: pj(self.install_path, "upstream", "emscripten", v) for k, v in binaries
}
binaries["PKGCONFIG"] = "pkg-config"
return binaries return binaries
@property @property
def configure_options(self): def configure_options(self):
#return "" # return ""
return [f'--host={self.arch_full}'] return [f"--host={self.arch_full}"]
@property @property
def configure_wrapper(self): def configure_wrapper(self):
@ -72,24 +75,34 @@ class WasmPlatformInfo(PlatformInfo):
return "emmake" return "emmake"
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.install_path, 'bin')] return [pj(self.install_path, "bin")]
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['PATH'] = ':'.join([ env["PATH"] = ":".join(
env['PATH'], [
self.install_path, env["PATH"],
pj(self.install_path, 'upstream', 'emscripten'), self.install_path,
pj(self.install_path, 'node', '14.18.2_64bit', 'bin') pj(self.install_path, "upstream", "emscripten"),
]) pj(self.install_path, "node", "14.18.2_64bit", "bin"),
env['EMSDK'] = self.install_path ]
env['EMSDK_NODE'] = pj(self.install_path, 'node', '14.18.2_64bit', 'bin', 'node') )
env["EMSDK"] = self.install_path
env["EMSDK_NODE"] = pj(
self.install_path, "node", "14.18.2_64bit", "bin", "node"
)
return env return env
def set_comp_flags(self, env): def set_comp_flags(self, env):
super().set_comp_flags(env) super().set_comp_flags(env)
env['CFLAGS'] = " -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CFLAGS'] env["CFLAGS"] = (
env['CXXFLAGS'] = " -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "+env['CXXFLAGS'] " -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "
+ env["CFLAGS"]
)
env["CXXFLAGS"] = (
" -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 "
+ env["CXXFLAGS"]
)
def set_compiler(self, env): def set_compiler(self, env):
for k, v in self.binaries.items(): for k, v in self.binaries.items():
@ -97,5 +110,5 @@ class WasmPlatformInfo(PlatformInfo):
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile("cmake_cross_file.txt")
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")

View File

@ -6,57 +6,66 @@ from kiwixbuild._global import neutralEnv
class Win32PlatformInfo(PlatformInfo): class Win32PlatformInfo(PlatformInfo):
build = 'win32' build = "win32"
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ["fedora", "debian"]
arch_full = 'i686-w64-mingw32' arch_full = "i686-w64-mingw32"
extra_libs = ['-lwinmm', '-lshlwapi', '-lws2_32', '-lssp'] extra_libs = ["-lwinmm", "-lshlwapi", "-lws2_32", "-lssp"]
def get_cross_config(self): def get_cross_config(self):
return { return {
'exe_wrapper_def': self.exe_wrapper_def, "exe_wrapper_def": self.exe_wrapper_def,
'binaries': self.binaries, "binaries": self.binaries,
'root_path': self.root_path, "root_path": self.root_path,
'extra_libs': self.extra_libs, "extra_libs": self.extra_libs,
'extra_cflags': ['-DWIN32', *('-I{}'.format(include_dir) for include_dir in self.get_include_dirs())], "extra_cflags": [
'host_machine': { "-DWIN32",
'system': 'Windows', *(
'lsystem': 'windows', "-I{}".format(include_dir)
'cpu_family': 'x86', for include_dir in self.get_include_dirs()
'cpu': 'i686', ),
'endian': 'little', ],
'abi': '' "host_machine": {
} "system": "Windows",
"lsystem": "windows",
"cpu_family": "x86",
"cpu": "i686",
"endian": "little",
"abi": "",
},
} }
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile("cmake_cross_file.txt")
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")
@property @property
def root_path(self): def root_path(self):
root_paths = { root_paths = {
'fedora': '/usr/i686-w64-mingw32/sys-root/mingw', "fedora": "/usr/i686-w64-mingw32/sys-root/mingw",
'debian': '/usr/i686-w64-mingw32' "debian": "/usr/i686-w64-mingw32",
} }
return root_paths[neutralEnv('distname')] return root_paths[neutralEnv("distname")]
@property @property
def binaries(self): def binaries(self):
return {k:which('{}-{}'.format(self.arch_full, v)) return {
for k, v in (('CC', 'gcc'), k: which("{}-{}".format(self.arch_full, v))
('CXX', 'g++'), for k, v in (
('AR', 'ar'), ("CC", "gcc"),
('STRIP', 'strip'), ("CXX", "g++"),
('WINDRES', 'windres'), ("AR", "ar"),
('RANLIB', 'ranlib'), ("STRIP", "strip"),
('PKGCONFIG', 'pkg-config')) ("WINDRES", "windres"),
} ("RANLIB", "ranlib"),
("PKGCONFIG", "pkg-config"),
)
}
@property @property
def exe_wrapper_def(self): def exe_wrapper_def(self):
try: try:
which('wine') which("wine")
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return "" return ""
else: else:
@ -64,25 +73,27 @@ class Win32PlatformInfo(PlatformInfo):
@property @property
def configure_options(self): def configure_options(self):
yield f'--host={self.arch_full}' yield f"--host={self.arch_full}"
def set_compiler(self, env): def set_compiler(self, env):
for k, v in self.binaries.items(): for k, v in self.binaries.items():
env[k] = v env[k] = v
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.root_path, 'bin')] return [pj(self.root_path, "bin")]
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') env["PKG_CONFIG_LIBDIR"] = pj(self.root_path, "lib", "pkgconfig")
env['LIBS'] = " ".join(self.extra_libs) + " " +env['LIBS'] env["LIBS"] = " ".join(self.extra_libs) + " " + env["LIBS"]
return env return env
class Win32Dyn(Win32PlatformInfo): class Win32Dyn(Win32PlatformInfo):
name = 'win32_dyn' name = "win32_dyn"
static = False static = False
class Win32Static(Win32PlatformInfo): class Win32Static(Win32PlatformInfo):
name = 'win32_static' name = "win32_static"
static = True static = True

View File

@ -6,57 +6,70 @@ from kiwixbuild._global import neutralEnv
class Win64PlatformInfo(PlatformInfo): class Win64PlatformInfo(PlatformInfo):
extra_libs = ['-lmingw32', '-lwinmm', '-lws2_32', '-lshlwapi', '-lrpcrt4', '-lmsvcr100', '-liphlpapi', '-lshell32', '-lkernel32'] extra_libs = [
build = 'win64' "-lmingw32",
compatible_hosts = ['fedora', 'debian'] "-lwinmm",
arch_full = 'x86_64-w64-mingw32' "-lws2_32",
"-lshlwapi",
"-lrpcrt4",
"-lmsvcr100",
"-liphlpapi",
"-lshell32",
"-lkernel32",
]
build = "win64"
compatible_hosts = ["fedora", "debian"]
arch_full = "x86_64-w64-mingw32"
def get_cross_config(self): def get_cross_config(self):
return { return {
'exe_wrapper_def': self.exe_wrapper_def, "exe_wrapper_def": self.exe_wrapper_def,
'binaries': self.binaries, "binaries": self.binaries,
'root_path': self.root_path, "root_path": self.root_path,
'extra_libs': self.extra_libs, "extra_libs": self.extra_libs,
'extra_cflags': ['-DWIN32'], "extra_cflags": ["-DWIN32"],
'host_machine': { "host_machine": {
'system': 'Windows', "system": "Windows",
'lsystem': 'windows', "lsystem": "windows",
'cpu_family': 'x86_64', "cpu_family": "x86_64",
'cpu': 'x86_64', "cpu": "x86_64",
'endian': 'little', "endian": "little",
'abi': '' "abi": "",
} },
} }
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_cross_file.txt') self.buildEnv.cmake_crossfile = self._gen_crossfile("cmake_cross_file.txt")
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') self.buildEnv.meson_crossfile = self._gen_crossfile("meson_cross_file.txt")
@property @property
def root_path(self): def root_path(self):
root_paths = { root_paths = {
'fedora': '/usr/x86_64-w64-mingw32/sys-root/mingw', "fedora": "/usr/x86_64-w64-mingw32/sys-root/mingw",
'debian': '/usr/x86_64-w64-mingw32' "debian": "/usr/x86_64-w64-mingw32",
} }
return root_paths[neutralEnv('distname')] return root_paths[neutralEnv("distname")]
@property @property
def binaries(self): def binaries(self):
return {k:which('{}-{}'.format(self.arch_full, v)) return {
for k, v in (('CC', 'gcc'), k: which("{}-{}".format(self.arch_full, v))
('CXX', 'g++'), for k, v in (
('AR', 'ar'), ("CC", "gcc"),
('STRIP', 'strip'), ("CXX", "g++"),
('WINDRES', 'windres'), ("AR", "ar"),
('RANLIB', 'ranlib'), ("STRIP", "strip"),
('PKGCONFIG', 'pkg-config')) ("WINDRES", "windres"),
} ("RANLIB", "ranlib"),
("PKGCONFIG", "pkg-config"),
)
}
@property @property
def exe_wrapper_def(self): def exe_wrapper_def(self):
try: try:
which('wine') which("wine")
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return "" return ""
else: else:
@ -64,25 +77,27 @@ class Win64PlatformInfo(PlatformInfo):
@property @property
def configure_options(self): def configure_options(self):
return [f'--host={self.arch_full}'] return [f"--host={self.arch_full}"]
def set_compiler(self, env): def set_compiler(self, env):
for k, v in self.binaries.items(): for k, v in self.binaries.items():
env[k] = v env[k] = v
def get_bin_dir(self): def get_bin_dir(self):
return [pj(self.root_path, 'bin')] return [pj(self.root_path, "bin")]
def get_env(self): def get_env(self):
env = super().get_env() env = super().get_env()
env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') env["PKG_CONFIG_LIBDIR"] = pj(self.root_path, "lib", "pkgconfig")
env['LIBS'] = " ".join(self.extra_libs) + " " +env['LIBS'] env["LIBS"] = " ".join(self.extra_libs) + " " + env["LIBS"]
return env return env
class Win64Dyn(Win64PlatformInfo): class Win64Dyn(Win64PlatformInfo):
name = 'win64_dyn' name = "win64_dyn"
static = False static = False
class Win64Static(Win64PlatformInfo): class Win64Static(Win64PlatformInfo):
name = 'win64_static' name = "win64_static"
static = True static = True

View File

@ -17,16 +17,16 @@ pj = os.path.join
COLORS = { COLORS = {
'OK': '\033[92m', "OK": "\033[92m",
'WARNING': '\033[93m', "WARNING": "\033[93m",
'NEEDED': '\033[93m', "NEEDED": "\033[93m",
'SKIP': '\033[34m', "SKIP": "\033[34m",
'ERROR': '\033[91m', "ERROR": "\033[91m",
'': '\033[0m', "": "\033[0m",
} }
REMOTE_PREFIX = 'http://mirror.download.kiwix.org/dev/kiwix-build/' REMOTE_PREFIX = "http://mirror.download.kiwix.org/dev/kiwix-build/"
def which(name): def which(name):
@ -34,16 +34,19 @@ def which(name):
output = subprocess.check_output(command, shell=True) output = subprocess.check_output(command, shell=True)
return output[:-1].decode() return output[:-1].decode()
def xrun_find(name): def xrun_find(name):
command = "xcrun -find {}".format(name) command = "xcrun -find {}".format(name)
output = subprocess.check_output(command, shell=True) output = subprocess.check_output(command, shell=True)
return output[:-1].decode() return output[:-1].decode()
regex_space = re.compile(r'((?<!\\) )') regex_space = re.compile(r"((?<!\\) )")
def escape_path(path): def escape_path(path):
path = str(path) path = str(path)
return regex_space.sub(r'\ ', path) return regex_space.sub(r"\ ", path)
class Defaultdict(defaultdict): class Defaultdict(defaultdict):
@ -56,7 +59,7 @@ class DefaultEnv(Defaultdict):
super().__init__(str, os.environ) super().__init__(str, os.environ)
def __getitem__(self, name): def __getitem__(self, name):
if name == b'PATH': if name == b"PATH":
raise KeyError raise KeyError
return super().__getitem__(name) return super().__getitem__(name)
@ -78,25 +81,25 @@ def get_sha256(path):
current = 0 current = 0
batch_size = 1024 * 8 batch_size = 1024 * 8
sha256 = hashlib.sha256() sha256 = hashlib.sha256()
with open(path, 'br') as f: with open(path, "br") as f:
while True: while True:
batch = f.read(batch_size) batch = f.read(batch_size)
if not batch: if not batch:
break break
sha256.update(batch) sha256.update(batch)
print_progress(progress_chars[current]) print_progress(progress_chars[current])
current = (current+1)%4 current = (current + 1) % 4
return sha256.hexdigest() return sha256.hexdigest()
def colorize(text, color=None): def colorize(text, color=None):
if color is None: if color is None:
color = text color = text
return "{}{}{}".format(COLORS[color], text, COLORS['']) return "{}{}{}".format(COLORS[color], text, COLORS[""])
def print_progress(progress): def print_progress(progress):
if option('show_progress'): if option("show_progress"):
text = "{}\033[{}D".format(progress, len(progress)) text = "{}\033[{}D".format(progress, len(progress))
print(text, end="") print(text, end="")
@ -126,18 +129,20 @@ def download_remote(what, where):
raise SkipCommand() raise SkipCommand()
os.remove(file_path) os.remove(file_path)
if option('no_cert_check'): if option("no_cert_check"):
context = ssl.create_default_context() context = ssl.create_default_context()
context.check_hostname = False context.check_hostname = False
context.verify_mode = ssl.CERT_NONE context.verify_mode = ssl.CERT_NONE
else: else:
context = None context = None
batch_size = 1024 * 8 batch_size = 1024 * 8
extra_args = {'context':context} if sys.version_info >= (3, 4, 3) else {} extra_args = {"context": context} if sys.version_info >= (3, 4, 3) else {}
progress_chars = "/-\|" progress_chars = "/-\|"
try: try:
with urllib.request.urlopen(what.url, **extra_args) as resource, open(file_path, 'wb') as file: with urllib.request.urlopen(what.url, **extra_args) as resource, open(
tsize = resource.info().get('Content-Length', None) file_path, "wb"
) as file:
tsize = resource.info().get("Content-Length", None)
if tsize is not None: if tsize is not None:
tsize = int(tsize) tsize = int(tsize)
current = 0 current = 0
@ -147,17 +152,17 @@ def download_remote(what, where):
break break
if tsize: if tsize:
current += batch_size current += batch_size
print_progress("{:.2%}".format(current/tsize)) print_progress("{:.2%}".format(current / tsize))
else: else:
print_progress(progress_chars[current]) print_progress(progress_chars[current])
current = (current+1)%4 current = (current + 1) % 4
file.write(batch) file.write(batch)
except urllib.error.URLError as e: except urllib.error.URLError as e:
print("Cannot download url {}:\n{}".format(what.url, e.reason)) print("Cannot download url {}:\n{}".format(what.url, e.reason))
raise StopBuild() raise StopBuild()
if not what.sha256: if not what.sha256:
print('Sha256 for {} not set, do no verify download'.format(what.name)) print("Sha256 for {} not set, do no verify download".format(what.name))
elif what.sha256 != get_sha256(file_path): elif what.sha256 != get_sha256(file_path):
os.remove(file_path) os.remove(file_path)
raise StopBuild("Sha 256 doesn't correspond") raise StopBuild("Sha 256 doesn't correspond")
@ -187,7 +192,7 @@ class StopBuild(BaseCommandResult):
pass pass
class Remotefile(namedtuple('Remotefile', ('name', 'sha256', 'url'))): class Remotefile(namedtuple("Remotefile", ("name", "sha256", "url"))):
def __new__(cls, name, sha256, url=None): def __new__(cls, name, sha256, url=None):
if url is None: if url is None:
url = REMOTE_PREFIX + name url = REMOTE_PREFIX + name
@ -217,28 +222,28 @@ class Context:
def _finalise(self): def _finalise(self):
if self.autoskip_file is not None: if self.autoskip_file is not None:
os.makedirs(os.path.dirname(self.autoskip_file), exist_ok=True) os.makedirs(os.path.dirname(self.autoskip_file), exist_ok=True)
with open(self.autoskip_file, 'w'): with open(self.autoskip_file, "w"):
pass pass
def extract_archive(archive_path, dest_dir, topdir=None, name=None): def extract_archive(archive_path, dest_dir, topdir=None, name=None):
is_zip_archive = archive_path.endswith('.zip') is_zip_archive = archive_path.endswith(".zip")
archive = None archive = None
try: try:
if is_zip_archive: if is_zip_archive:
archive = zipfile.ZipFile(archive_path) archive = zipfile.ZipFile(archive_path)
members = archive.infolist() members = archive.infolist()
getname = lambda info : info.filename getname = lambda info: info.filename
isdir = lambda info: info.filename.endswith('/') isdir = lambda info: info.filename.endswith("/")
else: else:
archive = tarfile.open(archive_path) archive = tarfile.open(archive_path)
members = archive.getmembers() members = archive.getmembers()
getname = lambda info : getattr(info, 'name') getname = lambda info: getattr(info, "name")
isdir = lambda info: info.isdir() isdir = lambda info: info.isdir()
if not topdir: if not topdir:
for d in (m for m in members if isdir(m)): for d in (m for m in members if isdir(m)):
_name = getname(d) _name = getname(d)
if _name.endswith('/'): if _name.endswith("/"):
_name = _name[:-1] _name = _name[:-1]
if not os.path.dirname(_name): if not os.path.dirname(_name):
if topdir: if topdir:
@ -249,9 +254,13 @@ def extract_archive(archive_path, dest_dir, topdir=None, name=None):
break break
topdir = _name topdir = _name
if topdir: if topdir:
members_to_extract = [m for m in members if getname(m).startswith(topdir+'/')] members_to_extract = [
m for m in members if getname(m).startswith(topdir + "/")
]
os.makedirs(dest_dir, exist_ok=True) os.makedirs(dest_dir, exist_ok=True)
with tempfile.TemporaryDirectory(prefix=os.path.basename(archive_path), dir=dest_dir) as tmpdir: with tempfile.TemporaryDirectory(
prefix=os.path.basename(archive_path), dir=dest_dir
) as tmpdir:
if is_zip_archive: if is_zip_archive:
_members_to_extract = [getname(m) for m in members_to_extract] _members_to_extract = [getname(m) for m in members_to_extract]
else: else:
@ -281,8 +290,8 @@ def run_command(command, cwd, context, *, env=None, input=None):
env = DefaultEnv() env = DefaultEnv()
log = None log = None
try: try:
if not option('verbose'): if not option("verbose"):
log = open(context.log_file, 'w') log = open(context.log_file, "w")
print("run command '{}'".format(command), file=log) print("run command '{}'".format(command), file=log)
print("current directory is '{}'".format(cwd), file=log) print("current directory is '{}'".format(cwd), file=log)
print("env is :", file=log) print("env is :", file=log)
@ -293,8 +302,15 @@ def run_command(command, cwd, context, *, env=None, input=None):
log.flush() log.flush()
kwargs = dict() kwargs = dict()
if input: if input:
kwargs['stdin'] = subprocess.PIPE kwargs["stdin"] = subprocess.PIPE
process = subprocess.Popen(command, cwd=cwd, env=env, stdout=log or sys.stdout, stderr=subprocess.STDOUT, **kwargs) process = subprocess.Popen(
command,
cwd=cwd,
env=env,
stdout=log or sys.stdout,
stderr=subprocess.STDOUT,
**kwargs
)
if input: if input:
input = input.encode() input = input.encode()
while True: while True:
@ -308,7 +324,7 @@ def run_command(command, cwd, context, *, env=None, input=None):
# `communicate` timeout (and we must set `input` to None # `communicate` timeout (and we must set `input` to None
# to not communicate again). # to not communicate again).
input = None input = None
print('.', end='', flush=True) print(".", end="", flush=True)
else: else:
break break
if process.returncode: if process.returncode:

View File

@ -1,12 +1,11 @@
# This file reference all the versions of the depedencies we use in kiwix-build. # This file reference all the versions of the depedencies we use in kiwix-build.
main_project_versions = { main_project_versions = {
'libzim': '9.1.0', "libzim": "9.1.0",
'libkiwix': '13.0.0', "libkiwix": "13.0.0",
'kiwix-tools': '3.6.0', "kiwix-tools": "3.6.0",
'zim-tools': '3.4.0', "zim-tools": "3.4.0",
'kiwix-desktop': '2.3.1' # Also change KIWIX_DESKTOP_VERSION and KIWIX_DESKTOP_RELEASE in appveyor.yml "kiwix-desktop": "2.3.1", # Also change KIWIX_DESKTOP_VERSION and KIWIX_DESKTOP_RELEASE in appveyor.yml
} }
# This dictionnary specify what we need to build at each release process. # This dictionnary specify what we need to build at each release process.
@ -30,37 +29,37 @@ main_project_versions = {
# - set KIWIX_DESKTOP_RELEASE to 0 # - set KIWIX_DESKTOP_RELEASE to 0
release_versions = { release_versions = {
'libzim': None, # Depends of base deps (was 0) "libzim": None, # Depends of base deps (was 0)
'libkiwix': None, # Depends of libzim (was 1) "libkiwix": None, # Depends of libzim (was 1)
'kiwix-tools': None, # Depends of libkiwix and libzim (was 0) "kiwix-tools": None, # Depends of libkiwix and libzim (was 0)
'zim-tools': 0, # Depends of libzim (was None) "zim-tools": 0, # Depends of libzim (was None)
'kiwix-desktop': None # Depends of libkiwix and libzim (was 4) "kiwix-desktop": None, # Depends of libkiwix and libzim (was 4)
} }
# This is the "version" of the whole base_deps_versions dict. # This is the "version" of the whole base_deps_versions dict.
# Change this when you change base_deps_versions. # Change this when you change base_deps_versions.
base_deps_meta_version = '96' base_deps_meta_version = "96"
base_deps_versions = { base_deps_versions = {
'zlib' : '1.2.12', "zlib": "1.2.12",
'lzma' : '5.2.6', "lzma": "5.2.6",
'zstd' : '1.5.2', "zstd": "1.5.2",
'docoptcpp' : '0.6.2', "docoptcpp": "0.6.2",
'uuid' : '1.43.4', "uuid": "1.43.4",
'xapian-core' : '1.4.23', "xapian-core": "1.4.23",
'mustache' : '4.1', "mustache": "4.1",
'pugixml' : '1.2', "pugixml": "1.2",
'libmicrohttpd' : '0.9.76', "libmicrohttpd": "0.9.76",
'gumbo' : '0.10.1', "gumbo": "0.10.1",
'icu4c' : '73.2', "icu4c": "73.2",
'libaria2' : '1.37.0', "libaria2": "1.37.0",
'libmagic' : '5.44', "libmagic": "5.44",
'android-ndk' : 'r21e', "android-ndk": "r21e",
'qt' : '5.10.1', "qt": "5.10.1",
'qtwebengine' : '5.10.1', "qtwebengine": "5.10.1",
'org.kde' : '5.15-21.08', "org.kde": "5.15-21.08",
'io.qt.qtwebengine' : '5.15-21.08', "io.qt.qtwebengine": "5.15-21.08",
'zim-testing-suite': '0.3', "zim-testing-suite": "0.3",
'emsdk': '3.1.41', "emsdk": "3.1.41",
} }