|
|
# Android Build System Concepts
|
|
|
|
|
|
This document provides high level explanations and mapping of the internal
|
|
|
build system components and concepts of the Android build system and Bazel,
|
|
|
and how components communicate with each other.
|
|
|
|
|
|
## High level components
|
|
|
|
|
|
This table provides a high level overview of the components in the current
|
|
|
Android Platform build system, and how each component maps to a concept in
|
|
|
Bazel.
|
|
|
|
|
|
|Android build system component|Description|Mapping to Bazel concepts|
|
|
|
|---|---|---|
|
|
|
|Kati|Make-compatible front-end. Encodes build logic in `.mk` scripts. Declares buildable units in `Android.mk`. Generates Ninja file directly.|Loading and analysis phase. Conceptually similar to `bazel build --nobuild`.|
|
|
|
|Blueprint|Build definition syntax. Build syntax parser. Internal data structures like Modules/Variations/Context/Scope. Ninja file generator.|Starlark.|
|
|
|
|Soong|Bazel-like front-end. Encodes build logic in Go. Declares build units in `Android.bp`, parsed by Blueprint. Uses Blueprint to generate Ninja file. Generates a `.mk` file with prebuilt module stubs to Kati.|Loading and analysis phase. Conceptually similar to `bazel build --nobuild command`.|
|
|
|
|Ninja|Serialized command line action graph executor. Executes Ninja graph generated from Kati and Soong.|Bazel's execution phase.|
|
|
|
|atest|Test executor and orchestrator.|Conceptually similar to `bazel test` command.|
|
|
|
|Blueprint + Kati + Soong + Ninja + atest|The entire build pipeline for Android.|Conceptually similar to `bazel build` or `bazel test` commands.|
|
|
|
|`<script>.sh`|Running arbitrary scripts in AOSP.|Conceptually similar to `bazel run` command.|
|
|
|
|Make (replaced in-place by Kati)|No longer in use. Entire build system, replaced by the tools above.|Loading, analysis, execution phases. Conceptually similar to `bazel build` command.|
|
|
|
|`Android.bp`|Build definition file for Soong.|`BUILD.bazel` or `BUILD`.|
|
|
|
|`Android.mk`|Build definition file for Kati.|`BUILD.bazel` or `BUILD`.|
|
|
|
|
|
|
## Communication between components
|
|
|
|
|
|
* Kati product configuration component to generate config variables (config.mk, AndroidProducts.mk)
|
|
|
* **“Kati-config” for the purpose of this document**
|
|
|
* Kati component to generate build actions in Ninja files (main.mk, Android.mk files)
|
|
|
* **“Kati-build” for the purpose of this document**
|
|
|
* Kati component to generate packaging actions in Ninja files (packaging.mk file)
|
|
|
* **“Kati-package” for the purpose of this document**
|
|
|
* Kati component to generate cleaning actions in Ninja files (cleanbuild.mk, CleanSpec.mk files)
|
|
|
* **"Kati-cleanspec" for the purpose of this document**
|
|
|
* **soong\_build** (and **Blueprint**) component to generate build actions (Android.bp, Blueprints files)
|
|
|
* **Ninja** component to execute actions from Kati-build, Kati-package and soong\_build
|
|
|
* **Bazel** as the next generation of the entire build system, starting as a Ninja executor drop-in replacement
|
|
|
* **soong\_ui** as the tool to orchestrate all of the above, and with auxiliary tools like finder, path\_interposer, soong\_env, minibp and bpglob.
|
|
|
|
|
|
The current build system architecture primarily uses **files** as the medium
|
|
|
for inter-process communication (IPC), with one known case of unix socket
|
|
|
communication (e.g.
|
|
|
[path\_interposer](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/paths/logs.go;l=112-133;drc=184901135cda8bdcc51cab4f16c401a28a510593)),
|
|
|
and a fifo between Ninja and soong_ui for the Protobuf stream for build
|
|
|
status reporting.
|
|
|
|
|
|
## Component order
|
|
|
|
|
|
The build system components run in the following order, orchestrated by soong\_ui:
|
|
|
|
|
|
1. soong\_ui bootstraps itself with microfactory (`go build` replacement) and launches.
|
|
|
1. soong\_ui runs auxiliary tools to aggregate files into filelists, for
|
|
|
Android.mk, Android.bp, AndroidProducts.mk and several others.
|
|
|
1. soong\_ui runs Kati-config with
|
|
|
[the config.mk entry point](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/dumpvars.go;l=89;drc=9f43597ff7349c4facd9e338e5b4b277e625e518).
|
|
|
1. soong\_ui orchestrates 3 Blueprint/Soong phases to generate the main out/soong/build.ninja file:
|
|
|
minibootstrap, bootstrap, and primary.
|
|
|
1. Minibootstrap phase uses Blueprint/Microfactory to build itself
|
|
|
(minibp) so that Android.bp and Blueprint files can be used to define
|
|
|
Soong.
|
|
|
1. Bootstrap phase runs Ninja on a build.ninja file that runs minibp to
|
|
|
read all Android.bp files across the source tree that describes Soong and
|
|
|
plugins, and builds soong\_build.
|
|
|
1. Primary phase runs Ninja on a build.ninja file that runs soong_build
|
|
|
to generate the final out/soong/build.ninja file.
|
|
|
1. soong\_build also runs its own tests alongside generating
|
|
|
out/soong/build.ninja, which can be skipped with the `--skip-soong-tests`
|
|
|
argument.
|
|
|
1. soong\_ui runs Kati-cleanspec with
|
|
|
[the cleanbuild.mk entry point](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/kati.go;l=362;drc=b1d30d63c5d1b818ea38e77cd155da2016fe8b6c).
|
|
|
1. soong\_ui runs Kati-build to generate a Ninja file, with
|
|
|
[the main.mk entry point.](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/kati.go;l=202;drc=b1d30d63c5d1b818ea38e77cd155da2016fe8b6c)
|
|
|
1. soong\_ui runs Kati-package to generate a Ninja file, with
|
|
|
[the packaging/main.mk](https://cs.android.com/android/platform/superproject/+/master:build/soong/ui/build/kati.go;l=314;drc=b1d30d63c5d1b818ea38e77cd155da2016fe8b6c)
|
|
|
entry point.
|
|
|
1. soong\_ui generates a Ninja file to combine above Ninja files.
|
|
|
1. soong\_ui runs either Ninja or Bazel to execute the build, with the
|
|
|
combined Ninja file as entry point.
|
|
|
|
|
|
soong\_ui has a --skip-make flag that will skip Kati-config, Kati cleanspec,
|
|
|
Kati-build and Kati-package, used for Soong-only builds in NDK and some
|
|
|
Mainline projects.
|
|
|
|
|
|
### soong\_ui
|
|
|
|
|
|
soong\_ui is primarily responsible for orchestrating the build, cleaning the
|
|
|
build environment, and running auxiliary tools. These tools (minibp,
|
|
|
microfactory) can bootstrap other tools (soong\_build), aggregate file lists
|
|
|
(finder.go), improve hermeticity (path\_interposer, nsjail) or perform checks
|
|
|
against the environment (soong\_env).
|
|
|
|
|
|
soong\_ui uses finder.go to generate <filename>.list files for other
|
|
|
tools. For example, it generates Android.mk.list for Kati-build,
|
|
|
AndroidProducts.mk.list for Kati-config, and Android.bp.list for
|
|
|
soong\_build.
|
|
|
|
|
|
soong\_ui uses path\_interposer to prepare an hermetic $PATH with runtime
|
|
|
checks against allowlisted system tools. The $PATH contains these system
|
|
|
tools with checked-in prebuilts, and uses path\_interposer to intercept calls
|
|
|
and error out whenever non-allowlisted tools are used (see out/.path for
|
|
|
directory of intercepted tool symlinks).
|
|
|
|
|
|
soong\_ui generates a Kati suffix to ensure that Kati-generated files are
|
|
|
regenerated if inputs to Kati have changed between builds.
|
|
|
|
|
|
soong\_ui calls Soong and Kati to generate Ninja files, and eventually
|
|
|
creates another Ninja file (out/combined-<product>.ninja) to combine the
|
|
|
others, and executes either Ninja or Bazel to complete the build.
|
|
|
|
|
|
soong\_ui sets up the sandbox and environment for the Ninja/Bazel process.
|
|
|
|
|
|
## Kati-config
|
|
|
|
|
|
As a product configuration tool, soong\_ui runs Kati-config in
|
|
|
**[--dumpvars-mode](https://cs.android.com/android/platform/superproject/+/master:build/soong/cmd/soong_ui/main.go;l=298-305;drc=master)**
|
|
|
to dump the values of specified Make variables at the end of an evaluation,
|
|
|
with build/make/core/config.mk as the entry point. During this phase,
|
|
|
Kati-config eventually evaluates[
|
|
|
soong\_config.mk](https://cs.android.com/android/platform/superproject/+/master:build/make/core/soong_config.mk;l=2?q=soong.variables)
|
|
|
to generate the **[soong.variables JSON
|
|
|
file](https://cs.android.com/android/platform/superproject/+/master:build/make/core/soong_config.mk;l=16-222;drc=341928ecc5da205401bcfd86f098662b0cee7857)**.
|
|
|
This way, Kati-config can communicate product configuration to soong\_build,
|
|
|
as soong\_build parses the dumped variables from the JSON on startup, and
|
|
|
stores them into an in-memory Config object.
|
|
|
|
|
|
To communicate
|
|
|
[dexpreopt](https://cs.android.com/android/platform/superproject/+/master:build/soong/java/dexpreopt.go;l=115;drc=8cbc5d269b20b5743679bfb8684ed174dcf58a30)
|
|
|
variables to soong\_build, [dexpreopt.config is also
|
|
|
generated](https://cs.android.com/android/platform/superproject/+/master:build/make/core/dex_preopt_config.mk;l=71-142;drc=f26015449f0747b9fdeceb5ce70e30ecd76e20e8)
|
|
|
as a $(shell) action and [read by
|
|
|
soong\_build](https://cs.android.com/android/platform/superproject/+/master:build/soong/dexpreopt/config.go;l=175-196;drc=1af783fae74715bcf1a94733bd75b2e6cc688e8c)
|
|
|
in a similar way as Kati-config evaluates dex\_preopt\_config.mk included in
|
|
|
soong\_config.mk.
|
|
|
|
|
|
soong\_ui sets up a **KatiReader** to monitor Kati-config’s stdout/err for UI
|
|
|
reporting and error handling purposes.
|
|
|
|
|
|
## soong\_build
|
|
|
|
|
|
soong\_build’s primary role is to evaluate all Android.bp files, run a series
|
|
|
of mutators, and generate out/soong/build.ninja file.
|
|
|
|
|
|
soong\_build communicates with Kati-build by generating Make Vars and running
|
|
|
the AndroidMk singleton to generate .mk files in the output directory
|
|
|
(out/soong/{Android, late, make\_vars}-<product>.mk).
|
|
|
|
|
|
* Android-<product>.mk contains Soong modules as Make modules so Make
|
|
|
modules can depend on Soong modules.
|
|
|
* make\_vars-<product>.mk contains Make variables for Kati-build, exported
|
|
|
from Soong modules. There are also checks built into this .mk file to ensure that
|
|
|
if a duplicate Make variable of the same name comes from another source, the Soong
|
|
|
and Make variable values are identical.
|
|
|
* late-<product>.mk contains Make variables that are not read while Kati-build
|
|
|
parses the Android.mk file. (Late variables)
|
|
|
* soong\_ui invokes Kati to parse make\_vars .mk file earlier than the Android.mk
|
|
|
files,and late.mk after parsing the Android.mk files.
|
|
|
* late.mk is used to define phony rules to take advantage of Make’s ability to
|
|
|
add extra dependencies to an existing rule. late.mk is not strictly necessary to
|
|
|
make this happen at this moment, since late.mk rules don’t currently depend on any
|
|
|
variables defined during Android.mk processing (e.g. ALL\_MODULES$(module).INSTALLED).
|
|
|
|
|
|
## Kati-build / Kati-package
|
|
|
|
|
|
Kati-build’s primary role is to evaluate all Android.mk files with
|
|
|
build/make/core/main.mk as entry point, and generate
|
|
|
out/build-<product>.ninja. It also generates cleanspec.ninja for the
|
|
|
product, containing statements on how to remove stale output files.
|
|
|
|
|
|
Kati-build’s primary role is to evaluate all packaging .mk files with
|
|
|
build/make/packaging/main.mk as entry point, including
|
|
|
build/make/packaging/distdir.mk for dist-for-goals calls, and generate
|
|
|
out/package-<product>.ninja.
|
|
|
|
|
|
Kati-build/Kati-package’s stdout/stderr is monitored by soong\_ui’s
|
|
|
KatiReader to UI and error handling.
|
|
|
|
|
|
As Kati-build/Kati-package generates Ninja files, they also generate
|
|
|
out/ninja-<product>.sh and out/env-<product>.sh. These scripts are
|
|
|
wrappers for soong\_ui to execute Ninja with the correct Ninja files, in a
|
|
|
controlled environment.
|
|
|
|
|
|
## Ninja
|
|
|
|
|
|
As Ninja executes files from Kati-build, Kati-package, soong\_build and other
|
|
|
bootstrapping tools like Blueprint, it writes to a fifo in a proto front end
|
|
|
that soong\_ui monitors with NinjaReader. NinjaReader ensures that the user
|
|
|
interface for Ninja progress is consistent with the rest of the build.
|
|
|
|
|
|
## Bazel
|
|
|
|
|
|
As more Soong modules are converted to BUILD files, soong\_build serializes
|
|
|
information about converted modules to BUILD/bzl files on disk. soong\_build
|
|
|
then consumes information about these targets from Bazel by directly calling
|
|
|
the Bazel client to issue `cquery` calls about these targets.
|