| # CHRE Framework Build System | 
 |  | 
 | [TOC] | 
 |  | 
 | The CHRE build system is based on Make, and uses a set of Makefiles that allow | 
 | building the CHRE framework for a variety of hardware and software architectures | 
 | and variants (e.g. different combinations of CPU and OS/underlying system). It | 
 | is also flexible to different build toolchains (though LLVM/Clang or GCC are | 
 | recommended), by abstracting out key operations to a few Make or environment | 
 | variables. While the CHRE framework source code may be integrated into another | 
 | build system, it can be beneficial to leverage the existing build system to | 
 | reduce maintenance burden when the CHRE framework is updated. Additionally, it | 
 | should be possible to build nanoapps from the CHRE build system (to have | 
 | commonality across devices), and the CHRE framework build shares configuration | 
 | with the nanoapp build. | 
 |  | 
 | By default, the output of the build is linked into both a static archive | 
 | `libchre.a` and a shared library `libchre.so`, though generally only one of the | 
 | two is used, depending on the target device details. | 
 |  | 
 | ## Design | 
 |  | 
 | The CHRE build system was originally designed around the philosophy that a | 
 | vanilla invocation of `make` or `make all` should build any given nanoapp for | 
 | all targets. This allows for efficient use of the job scheduler in the Make | 
 | build system for multi-threaded builds and also promotes a level of separation | 
 | of concerns between targets (this is not enforced by any Make language | 
 | construct, merely convention). In practice, the CHRE build system is rarely used | 
 | to build multiple targets with one invocation of Make. However, the design goal | 
 | is carried forward for the variant support and separation of concerns between | 
 | targets. | 
 |  | 
 | All variant-specific compiler and linker flags are held under variables that | 
 | only apply to their specific target. This encourages developers to avoid leaking | 
 | build details between targets. This is important because not all compiler or | 
 | linker flags are compatible with all toolchains. For example: if a target uses a | 
 | compiler that does not support `-Wdouble-promotion`, but this were to be | 
 | enforced for all builds, then by definition this target would not compatible | 
 | with the CHRE build. The goal is for the CHRE build to be as flexible as | 
 | possible. | 
 |  | 
 | ### Build Template | 
 |  | 
 | The CHRE build system is implemented using template meta-programming techniques. | 
 | A build template is used to create Make rules for tasks that are common to all | 
 | targets. This includes compiling C/C++/assembly sources, linking, nanoapp header | 
 | generation, etc. The rationale behind this approach is to reduce boilerplate | 
 | when adding support for a new build target. | 
 |  | 
 | The build template is located at `build/build_template.mk`, and is documented | 
 | with all the variables used to generate build targets, like `TARGET_CFLAGS`. | 
 |  | 
 | ## Build Targets (Variants) | 
 |  | 
 | Compiling the framework for different devices is done by specifying the build | 
 | target when invoking `make`. Conventionally, build targets consist of three | 
 | parts: (software) vendor, architecture and variant and follow the | 
 | `<vendor>_<arch>_<variant>` pattern. A “vendor” is typically the company that | 
 | created the CHRE implementation, which may bring with it some details related to | 
 | nanoapp compatibility, for example the Nanoapp Support Library from the same | 
 | vendor may be required. The “arch” field refers to the Instruction Set | 
 | Architecture (ISA) and related compiler configuration to create a binary for the | 
 | target processor. The “variant” is primarily related to the underlying platform | 
 | software that the CHRE framework builds on top of, such as the combination of | 
 | operating system and other software needed to select the appropriate combination | 
 | of code in the `platform/` folder, but can also define other attributes of the | 
 | build, such as the target memory region for the binary. If a vendor, | 
 | architecture, or variant consist of multiple words or components, then they | 
 | should be separated by a hyphen and not an underscore. | 
 |  | 
 | For example, if we assume that a fictional company named Aperture developed its | 
 | own CHRE framework implementation, targeting a CPU family called Potato, and a | 
 | collection of platform software called GladOS/Cake, then a suitable build target | 
 | name would be `aperture_potato_glados-cake`. | 
 |  | 
 | The build target may optionally have `_debug` appended, which is a common suffix | 
 | which enables `-g` and any additional target-specific debug flags. | 
 |  | 
 | ### Creating a New Build Target | 
 |  | 
 | #### Architecture Support | 
 |  | 
 | The architecture-specific portion of the build deals with mainly the build | 
 | toolchain, and its associated flags. | 
 |  | 
 | It is easiest to check if the architecture is currently listed in `build/arch`, | 
 | and if it is, _Hooray! You're (almost) done_. It is still worthwhile to quickly | 
 | read through to know how the build is layered. | 
 |  | 
 | CHRE expects the build toolchain to be exported via Makefile variables, | 
 | specifically the compiler (`TARGET_CC`), archiver (`TARGET_AR`), and the linker | 
 | (`TARGET_LD`). Architecture specific compiler and linker flags are passed in via | 
 | the `TARGET_CFLAGS` and `TARGET_LDFLAGS` respectively. Additional | 
 | architecture-specific configuration is possible - refer to existing files under | 
 | `build/arch` and `build/build_template.mk` for details. | 
 |  | 
 | #### Build Target Makefile | 
 |  | 
 | Makefiles for each build target can be found at | 
 | `build/variant/<target_name>.mk`. These files are included at the end of the | 
 | top-level Makefile, and has the responsibility of collecting arguments for the | 
 | build template and invoking it to instantiate build rules. This involves doing | 
 | steps including (not an exhaustive listing): | 
 |  | 
 | * Setting the target name and platform ID | 
 |  | 
 | * Configuring (if needed) and including the apporpriate `build/arch/*.mk` file | 
 |  | 
 | * Collecting sources and flags specific to the platform into | 
 |   `TARGET_VARIANT_SRCS` and `TARGET_CFLAGS` | 
 |  | 
 | * Including `build/build_template.mk` to instantiate the build targets - this | 
 |   must be the last step, as the make targets cannot be modified once generated | 
 |  | 
 | Refer to existing files under `build/variant` for examples. | 
 |  | 
 | ## Device Variants | 
 |  | 
 | While the build target is primarily concerned with configuring the CHRE build | 
 | for a particular chipset, the same chipset can appear in multiple device | 
 | models/SKUs, potentially with different peripheral hardware, targeted levels of | 
 | feature support, etc. Additionally, a device/chip vendor may wish to provide | 
 | additional build customization outside of the Makefiles contained in the | 
 | system/chre project. The build system supports configuration at this level via | 
 | the device variant makefile, typically named `variant.mk`, which is injected | 
 | into the build by setting the `CHRE_VARIANT_MK_INCLUDES` environment variable | 
 | when invoking the top-level Makefile. Refer to the file | 
 | `variant/android/variant.mk` for an example. | 
 |  | 
 | ## Platform Sources | 
 |  | 
 | The file at `platform/platform.mk` lists sources and flags needed to compile the | 
 | CHRE framework for each supported platform. These must be added to Make | 
 | variables prefixed with the platform name (for example, `SIM_SRCS` for platform | 
 | sources used with the simulator build target), and not `COMMON_SRCS` or other | 
 | common variables, to avoid affecting other build targets. | 
 |  | 
 | ## Build Artifacts | 
 |  | 
 | At the end of a successful build, the following are generated in the `out` | 
 | directory: | 
 |  | 
 | * `<build_target>/libchre.so` and `libchre.a`: the resulting CHRE framework | 
 |   binary, built as a dynamic/static library | 
 |  | 
 | * `<build_target>_objs/`: Directory with object files and other intermediates | 
 |  | 
 | * Depending on the build target, additional intermediates (e.g. `nanopb_gen` for | 
 |   files generated for use with NanoPB) |