diff options
Diffstat (limited to 'documentation/build_system.md')
-rw-r--r-- | documentation/build_system.md | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/documentation/build_system.md b/documentation/build_system.md new file mode 100644 index 0000000..fa11e95 --- /dev/null +++ b/documentation/build_system.md @@ -0,0 +1,325 @@ +# Build system + +The OP-TEE build system is based on GNU make. It consists of a main `Makefile` +in the root of the project together with `sub.mk` files in all source +directories. In addition, some supporting files are used to recursively process +all `sub.mk` files and generate the build rules. + +Name | Description +:-----------------|:----------- +`core/core.mk` | Included from `Makefile` to build the TEE Core +`ta/ta.mk` | Included from `Makefile` to create the TA devkit +`mk/compile.mk` | Create rules to make objects from source files +`mk/lib.mk` | Create rules to make a libraries (.a) +`mk/subdir.mk` | Process `sub.mk` files recursively +`mk/config.mk` | Global configuration variable +`core/arch/$(ARCH)/$(ARCH).mk` | Arch-specific compiler flags +`core/arch/$(ARCH)/plat-$(PLATFORM)/conf.mk` | Platform-specific compiler flags and configuration variables +`core/arch/$(ARCH)/plat-$(PLATFORM)/link.mk` | Make recipes to link the TEE Core +`ta/arch/arm/link.mk` | Make recipes to link Trusted Applications +`ta/mk/ta_dev_kit.mk` | Main Makefile to be included when building Trusted Applications +`mk/checkconf.mk` | Utility functions to manipulate configuration variables and generate a C header file +`sub.mk` | List source files and define compiler flags + +`make` is always invoked from the top-level directory; there is no recursive +invocation of make itself. + +## Choosing the build target + +The target architecture, platform and build directory may be selected by setting +environment or make variables (**VAR=value make** or **make VAR=value**). + +### ARCH (CPU architecture) + +**$(ARCH)** is the CPU architecture to be built. Currently, the only supported +value is **arm** for 32-bit ARMv7. + +Architecture-specific source code belongs to sub-directories that follow the +`arch/$(ARCH)` pattern, such as: +`core/arch/arm`, `lib/libmpa/arch/arm`, `lib/libutee/arch/arm` and +so on. + +### PLATFORM / PLATFORM_FLAVOR (hardware platform) + +A *platform* is a family of closely related hardware configurations. A platform +*flavor* is a variant of such configurations. When used together they define the +target hardware on which OP-TEE will be run. + +For instance **PLATFORM=stm PLATFORM_FLAVOR=b2260** will build for the +ST Microelectronics 96boards/cannes2 board, while **PLATFORM=vexpress +PLATFORM_FLAVOR=qemu_virt** will generate code for a para-virtualized ARM +Versatile Express board running on QEMU. + +For convenience, the flavor may be appended to the platform name with a dash, so +**make PLATFORM=stm-b2260** is a shortcut for +**make PLATFORM=stm PLATFORM_FLAVOR=b2260**. Note that in both cases the value +of **$(PLATFORM)** is **stm** in the makefiles. + +Platform-specific source code belongs to `core/arch/$(ARCH)/plat-$(PLATFORM)`, +for instance: `core/arch/arm/plat-vexpress` or `core/arch/arm/plat-stm`. + +### O (output directory) + +All output files go into a platform-specific build directory, which is by default +`out/$(ARCH)-plat-$(PLATFORM)`. + +The output directory has basically the same structure as the source tree. +For instance, assuming **ARCH=arm PLATFORM=stm**, +`core/kernel/panic.c` will compile into `out/arm-plat-stm/core/kernel/panic.o`. + +However, some libraries are compiled several times: once or twice for user +mode, and once for kernel mode. This is because they may be used by the TEE +Core as well as by the Trusted Applications. As a result, the `lib` source +directory gives two or three build directories: `ta_arm{32,64}-lib` and +`core-lib`. + +The output directory also has an `export-ta_arm{32,64}` directory, which +contains: +- All the files needed to build Trusted Applications. + - In `lib/`: **libutee.a** (the GlobalPlatform Internal API), **libutils.a** + (which implements a part of the standard C library), and **libmpa.a** (which + implements multiple precision arithmetic and is required by libutee.a). + - In `include/`: header files for the above libraries + - In `mk/`: **ta_dev_kit.mk**, which is a Make include file with suitable + rules to build a TA, and its dependencies + - `scripts/sign.py`: a Python script used by ta_dev_kit.mk to sign TAs. + - In `src`: **user_ta_header.c**: source file to add a suitable header to the + Trusted Application (as expected by the loader code in the TEE Core) +- Some files needed to build host applications (using the Client API), under + `export-ta_arm{32,64}/host_include`. + +Finally, the build directory contains the auto-generated configuration file +for the TEE Core: `$(O)/include/generated/conf.h` (see below). + +### CROSS_COMPILE* (cross-compiler selection) + +**$(CROSS_COMPILE)** is the prefix used to invoke the (32-bit) cross-compiler +toolchain. +The default value is **arm-linux-gnueabihf-**. This is the variable you want to +change in case you want to use +[ccache](https://ccache.samba.org/) to speed you recompilations: +```shell +$ make CROSS_COMPILE="ccache arm-linux-gnueabihf-" +``` + +If the build includes a mix of 32-bit and 64-bit code, for instance if you +set `CFG_ARM64_core=y` to build a 64-bit secure kernel, then two different +toolchains are used, that are controlled by **$(CROSS_COMPILE32)** and +**$(CROSS_COMPILE64)**. +The default value of **$(CROSS_COMPILE32)** is the value of CROSS_COMPILE, +which defaults to **arm-linux-gnueabihf-** as mentioned above. +The default value of **$(CROSS_COMPILE64)** is **aarch64-linux-gnu-**. + +Examples: +```shell +# FOr this example, select HiKey which supports both 32- and 64-bit builds +$ export PLATFORM=hikey + +# 1. Build everything 32-bit +$ make + +# 2. Same as (1.) but override the toolchain +$ make CROSS_COMPILE="ccache arm-linux-gnueabihf-" + +# 3. Same as (2.) +$ make CROSS_COMPILE32="ccache arm-linux-gnueabihf-" + +# 4. Select 64-bit secure 'core' (and therefore both 32- and 64-bit +# Trusted Application libraries) +$ make CFG_ARM64_core=y + +# 5. Same as (4.) but override the toolchains +$ make CFG_ARM64_core=y \ + CROSS_COMPILE32="ccache arm-linux-gnueabihf-" \ + CROSS_COMPILE64="ccache aarch64-linux-gnu-" +``` + +## Platform-specific configuration and flags + +The following variables are defined in `core/arch/$(ARCH)/$(ARCH).mk`: + +- **$(core-platform-aflags)**, **$(core-platform-cflags)** and + **$(core-platform-cppflags)** are added to the assembler / C compiler + / preprocessor flags for all source files compiled for TEE Core including + the kernel versions of **libmpa.a** and **libutils.a**. +- **$(ta_arm{32,64}-platform-aflags)**, **$(ta_arm{32,64}-platform-cflags)** + and **$(ta_arm{32,64}-platform-cppflags)** are added to the assembler / C + compiler / preprocessor flags when building the user-mode libraries + (**libutee.a**, **libutils.a**, **libmpa.a**) or Trusted Applications. + +The following variables are defined in +`core/arch/$(ARCH)/plat-$(PLATFORM)/conf.mk`: + +- If **$(arm{32,64}-platform-cflags)**, **$(arm{32,64}-platform-aflags)** and + **$(arm{32,64}-platform-cppflags)** are defined their content will be added + to **$(\*-platform-\*flags)** when they are are initialized in + `core/arch/$(ARCH)/$(ARCH).mk` as described above. +- **$(core-platform-subdirs)** is the list of the subdirectories that are + added to the TEE Core. + +## Platform-specific link recipes for the TEE Core + +The file `core/arch/$(ARCH)/plat-$(PLATFORM)/link.mk` contains the rules to +link the TEE Core and perform any related tasks, such as running **objdump** +to produce a dump file. **link.mk** adds files to the **all:** target. + +## Source files + +Each directory that contains source files has a file called `sub.mk`. This +makefile defines the source files that should be included in the build, as well +as any subdirectories that should be processed, too. + +For example: +```Makefile +# core/arch/arm/sm/sub.mk +srcs-y += sm_asm.S +srcs-y += sm.c +``` +```Makefile +# core/sub.mk +subdirs-y += kernel +subdirs-y += mm +subdirs-y += tee +subdirs-y += drivers +``` + +The `-y` suffix is meant to facilitate conditional compilation. +See *Configuration* below. + +`srcs-y` and `subdirs-y` are often not used together in the same `sub.mk`, +because source files are usually alone in leaf directories. But this is not a +hard rule. + +In addition to source files, `sub.mk` may define compiler flags, include +directories and/or configuration variables as explained below. + +## Compiler flags + +Default compiler flags are defined in `mk/compile.mk`. Note that platform-specific flags must not appear in this file which is common to all platforms. + +To add flags for a given source file, you may use the following variables in +`sub.mk`: +* `cflags-<filename>-y` for C files (*.c) +* `aflags-<filename>-y` for assembler files (*.S) +* `cppflags-<filename>-y` for both C and assembler + +For instance: + +```Makefile +# core/lib/libtomcrypt/src/pk/dh/sub.mk +srcs-y += dh.c +cflags-dh.c-y := -Wno-unused-variable +``` +Compiler flags may also be removed, as follows: + +```Makefile +# lib/libutils/isoc/newlib/sub.mk +srcs-y += memmove.c +cflags-remove-memmove.c-y += -Wcast-align +``` + +Some variables apply to libraries only (that is, when using `mk/lib.mk`) +and affect all the source files that belong to the library: `cppflags-lib-y` +and `cflags-lib-y`. + +## Include directories + +Include directories may be added to `global-incdirs-y`, in which case they will +be accessible from all the source files and will be copied to +`export-ta_arm{32,64}/include` and `export-ta_arm{32,64}/host_include`. + +When `sub.mk` is used to build a library, `incdirs-lib-y` may receive additional +directories that will be used for that library only. + +## Configuration variables + +Some features may be enabled, disabled or otherwise controlled at compile time +through makefile variables. Default values are normally provided in makefiles +with the `?=` operator so that their value may be easily overridden by +environment variables. For instance: + +```Makefile +PLATFORM ?= stm +PLATFORM_FLAVOR ?= default +``` + +Some global configuration variables are defined in `mk/config.mk`, but others +may be defined in `sub.mk` when then pertain to a specific library for instance. + +Variables with the `CFG_` prefix are treated in a special +way: their value is automatically reflected in the generated header +file `$(out-dir)/include/generated/conf.h`, after all the included +makefiles have been processed. `conf.h` is automatically included by the +preprocessor when a source file is built. + +Depending on their value, variables may +be considered either boolean or non-boolean, which affects how they are +translated into `conf.h`. + +### Boolean configuration variables + +When a configuration variable controls the presence or absence of a feature, +**y** means *enabled*, while **n**, an empty value or an undefined variable +means *disabled*. For instance, the following commands are equivalent and would +disable feature *CFG_CRYPTO_GCM*: + +```Shell +$ make CFG_CRYPTO_GCM=n +``` +```Shell +$ make CFG_CRYPTO_GCM= +``` +```Shell +$ CFG_CRYPTO_GCM=n make +``` +```Shell +$ export CFG_CRYPTO_GCM=n +$ make +``` + +Configuration variables may then be used directly in `sub.mk` to +trigger conditional compilation: + +```Makefile +# core/lib/libtomcrypt/src/encauth/sub.mk +subdirs-$(CFG_CRYPTO_CCM) += ccm +subdirs-$(CFG_CRYPTO_GCM) += gcm +``` + +When a configuration variable is *enabled* (**y**), `<generated/conf.h>` +contains a macro with the same name as the variable and the value **1**. +If it is *disabled*, however, no macro definition is output. This allows the C +code to use constructs like: + +```C +/* core/lib/libtomcrypt/src/tee_ltc_provider.c */ + +/* ... */ + +#if defined(CFG_CRYPTO_GCM) +struct tee_gcm_state { + gcm_state ctx; /* the gcm state as defined by LTC */ + size_t tag_len; /* tag length */ +}; +#endif +``` + +### Non-boolean configuration variables + +Configuration variables that are not recognized as booleans are simply output +unchanged into `<generated/conf.h>`. For instance: + +```Makefile +$ make CFG_TEE_CORE_LOG_LEVEL=4 +``` +```C +/* out/arm-plat-vexpress/include/generated/conf.h */ + +#define CFG_TEE_CORE_LOG_LEVEL 4 /* '4' */ +``` + +### Configuration dependencies + +Some combinations of configuration variables may not be valid. This should be +dealt with by custom checks in makefiles. `mk/checkconf.h` provides functions +to help detect and deal with such situations. |