blob: d4e87e403b031651ff5505dc3140c5b1fb6a1af6 [file] [log] [blame]
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