| User Guide |
| ========== |
| |
| This guide describes how the framework features are supposed to be used, through |
| an example implementation for the |TF-A| project. Please refer to the `TF-A |
| repository`_ for the code. |
| |
| Root CMakeLists file |
| -------------------- |
| |
| The root CMakeLists file contains the following sections: |
| |
| #. Set required CMake version |
| |
| This is mandatory at the start of every CMake project. The framework |
| requires version 3.13 or newer. |
| |
| #. Set default build type |
| |
| Set the default value for ``CMAKE_BUILD_TYPE`` as a cache entry. This |
| ensures that the variable will have a value when it is not specified as a |
| command line argument. |
| |
| #. Set project root dir |
| |
| This is not strictly necessary, but makes referring to project relative |
| paths easier. Using ``CMAKE_CURRENT_LIST_DIR`` is recommended, it contains |
| the absolute path to the directory containing the currently processed file. |
| |
| #. Find the framework |
| |
| The framework is written as a CMake module, which can be used by |
| :cmake:command:`find_package`. This will take care of the version matching |
| and adding the framework dir to the module path. |
| |
| In the example, we try to find the framework at the parent directory of the |
| TF-A project dir and inside the TF-A project. If the framework is not |
| found, we clone the git repository using :cmake:module:`FetchContent`. The |
| path to the framework can also be provided as a command line option to |
| CMake, using ``-DTFACMF_DIR=<path to framework>``. |
| |
| #. Add project specific paths |
| |
| There are some CMake modules which are specific to the project, so cannot |
| be part of the generic framework (e.g. find fiptool). These should also be |
| added to the module path. |
| |
| #. Set CMake system parameters |
| |
| The framework provides a new platform called ``Embedded``. The project |
| should set :cmake:variable:`CMAKE_SYSTEM_NAME` to ``Embedded`` in order to |
| use the platform. This is an important step as this method is the only way |
| in CMake to ensure the correct output extension, library name |
| prefix/suffix, etc. |
| |
| :cmake:variable:`CMAKE_SYSTEM_PROCESSOR` should be set to ``arm``. This has |
| no particular effect, but it indicates that the project is cross-compiled. |
| |
| #. Include framework files |
| |
| It is more convenient to include the framework files here. The config and |
| target files included later will inherit the environment. |
| |
| #. Start CMake project |
| |
| The start of a CMake project, ``C`` and ``ASM`` languages should be |
| selected. |
| |
| #. Find platform module |
| |
| Currently for finding platform related config a minimal |
| :cmake:command:`find_package` module is implemented. These module files |
| describing the platform are located in the ``<TF-A root>/cmake/HwPlat`` |
| directory, which is added to :cmake:variable:`CMAKE_MODULE_PATH` in the |
| project specific paths section. |
| |
| A platform description file contains more :cmake:command:`find_package` |
| calls to find other external tools which are needed by the platform, and |
| sets the following global variables: |
| |
| * :cmake:variable:`HW_PLAT_CONFIG`: path to config file which contains |
| the :cmake:module:`group` for the platform options, |
| * :cmake:variable:`HW_PLAT_TARGET`: path to target file which contains |
| target creation, adding source files, etc. for the platform, |
| * :cmake:variable:`HW_PLAT_IMAGE`: path to file which describes the steps |
| of packaging the compiled binaries into an image (e.g. fiptool usage). |
| |
| The files indicated by these variables should be included in the relevant |
| sections of the root CMakeLists file, as described below. |
| |
| #. Include config files |
| |
| All the config files containing the settings groups have to be included. |
| These create and fill the groups with content, so in the target files we |
| can select which group to apply on which target. This means including the |
| :cmake:variable:`HW_PLAT_CONFIG` too. |
| |
| #. Include target files |
| |
| The target files selected for the current build have to be included. These |
| create the target and add source files, includes, etc. to the target. |
| Include :cmake:variable:`HW_PLAT_TARGET` in this section. |
| |
| Currently there is no solution provided to select which targets are |
| necessary, except adding/removing the include command in this section. A |
| better solution would be to decide based on the current build configuration |
| (from Kconfig?) so targets can be selected without modifying the CMakeLists |
| file. |
| |
| #. Include image files |
| |
| The files describing how to package the output binaries into an image can |
| be included here. Since this is platform specific, only |
| :cmake:variable:`HW_PLAT_IMAGE` should be used. |
| |
| Config file |
| ----------- |
| |
| The config files are located in the ``<TF-A root>/configs`` directory. Each |
| config file creates a :cmake:module:`group` using :cmake:command:`group_new` and |
| fills the group with content using :cmake:command:`group_add`. |
| |
| An important topic in the example is the difference between the ``CONFIG`` and |
| ``DEFINE`` types in a group. The idea is, that ``CONFIG`` is a parameter that |
| affects the build, i.e. what sources are necessary for a given target, etc. |
| while ``DEFINE`` is a simple C language define. Often a build option falls into |
| both categories, but not necessarily. For example, |
| |
| * ``ENABLE_AMU`` is a config, because it affects the build, it determines |
| whether ``amu.c`` is added to ``BL31`` or not. It is a define too, because |
| there is ``#if ENABLE_AMU`` conditional compilation in the C source, |
| |
| * ``FVP_MAX_PE_PER_CPU`` is a define only, because it does not affect the list |
| of files necessary for the build, |
| |
| * ``ENABLE_STACK_PROTECTOR`` is a config only, because it is never used in the |
| source code. |
| |
| Target file |
| ----------- |
| |
| A target file can be one of two types, ``CMakeLists.txt`` or ``<module |
| name>.cmake``. The former is for a module which is likely to be reused in other |
| projects and can be built stand-alone, the latter is a module which only has |
| meaning as part of the project. A ``CMakeLists.txt`` must contain a |
| :cmake:command:`project` command and has to be included using |
| :cmake:command:`add_subdirectory`, while a ``<module name>.cmake`` cannot start |
| a new project and the file is simply included with the :cmake:command:`include` |
| command. |
| |
| A target file uses the :cmake:module:`STGT` functions to create a target, add |
| groups to the target, add source files, etc. Please check the example code in |
| TF-A, e.g.: |
| |
| * ``bl*/bl*.cmake`` |
| * ``plat/arm/board/fvp/platform.cmake`` |
| * ``plat/arm/common/arm_common.cmake`` |
| * ``lib/libc/CMakeLists.txt`` |
| * etc. |
| |
| Image file |
| ---------- |
| |
| The purpose of this file is to package the output binaries into an image, using |
| the platform specific tools. The recommendation is to use |
| :cmake:command:`add_custom_target` which depends on the targets/files packaged |
| into the image. It is likely that ``ALL`` should be added to the command |
| options, since usually this image is the final output of the build, so no other |
| targets will depend on this therefore it would not be built without ``ALL``. |
| Please check the example in ``plat/arm/board/fvp/image.cmake``. |
| |
| .. todo:: Add support for ``install`` feature of CMake. |
| |
| -------------- |
| |
| .. _`TF-A repository`: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/ |
| |
| *Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* |
| |
| SPDX-License-Identifier: BSD-3-Clause |