Skip to content

Kiwix build architecture

Matthieu Gautier edited this page Jul 7, 2021 · 2 revisions

Goals

The main goal of kiwix-build is to build our projects (kiwix-lib, kiwix-tools, kiwix-desktop, libzim, zim-tools, ...) and their dependencies for and on different platforms. [In kiwix-build, all things to build is called a dependencies. Whatever this is one of our projects or a "true" dependency]

While in theory we could think that all projects are compiled equally on all platforms (or at least that each build systems handle themselves the differences), in practice this is not the case. The exact commands to run are a savant and subtitle mix between generic options and variations with the triplet (project, target platform, build platform).

To achieve this complex goal kiwix-build use (and abuse) of object polymorphism and redirection to define a generic way to build things while allowing specialization.

On top of that there is a common part in charge of setup everything, define what to build and in which order and ...

The informal matrix

For simplicity, kiwix-build tends to merge the concepts of target platform and build platform. While this is definitively not the same things, on the kiwix-build point-of-view, they have to be setup in the same time.

  • We are building on unix platform so the command can be launch the same way (through a shell).
  • We are not supporting several compilers. (Ie, be able to compile for the same target with gcc or clang). We may have to compile for a target with a specific compiler. But they are tied together, so we handle them together.

So, with some exceptions, the command to run is defined by the informal two dimensional matrix target_platformxdependency.

The build environment.

The environment (kiwixbuild/buildenv.py) is mainly in charge to provide an correct environment to launch command and provide some information to other part of kiwix-build.

There is two kinds of environment. One "neutral" in charge for command that don't depends of the target platform (like git, svn, patch, ...). And another one in charge for other commands (make, meson, configure, qmake, ...). As the exact environment variables to set depend of the target platform, it takes the values from the platformInfo object.

The platformInfo.

The platformInfo is in charge to provide as most as possible the values, options, binary paths, ... specific to the target platform.

Platform are defined in the (kiwixbuild/platforms) directory. You can see that sometime, platform depends of toolchains. Those toolchains are defined as dependencies (after all, a toolchain is a things we have to download and setup/install as every other dependencies)

The dependencies.

While each dependency has specificity. We mostly always do the same things :

  • Download the source (archive, git or svn repository)
  • Build the source. (configure with configure, qmake, meson, ... and build with make, ninja, ...)

So each dependency is composed of two part, a Source and a Builder. The Source is in charge to download and setup the source correctly (and it is independent of the platformInfo). The Builder is in charge to configure and build the source. To do so it relies on default options (specific to the build system) that can be overridden by specific dependency's builder and options coming from the platformInfo.

The base Source and Builder are defined in (kiwixbuild/dependencies/base.py) and specific dependencies are defined in files in kiwixbuild/dependencies.

A important thing to keep in mind is that Source are independent of the targetPlatform. kiwix-build shares the source directory across the different build. And so, we always do out of tree compilation, and we cannot have patch specific to a targetPlatform.