xref: /arm-trusted-firmware/docs/design_documents/cmake_framework.rst (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700SchasingluluTF-A CMake buildsystem
2*91f16700Schasinglulu======================
3*91f16700Schasinglulu
4*91f16700Schasinglulu:Author: Balint Dobszay
5*91f16700Schasinglulu:Organization: Arm Limited
6*91f16700Schasinglulu:Contact: Balint Dobszay <balint.dobszay@arm.com>
7*91f16700Schasinglulu:Status: Accepted
8*91f16700Schasinglulu
9*91f16700Schasinglulu.. contents:: Table of Contents
10*91f16700Schasinglulu
11*91f16700SchasingluluAbstract
12*91f16700Schasinglulu--------
13*91f16700SchasingluluThis document presents a proposal for a new buildsystem for TF-A using CMake,
14*91f16700Schasingluluand as part of this a reusable CMake framework for embedded projects. For a
15*91f16700Schasinglulusummary about the proposal, please see the `Phabricator wiki page
16*91f16700Schasinglulu<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As
17*91f16700Schasinglulumentioned there, the proposal consists of two phases. The subject of this
18*91f16700Schasingluludocument is the first phase only.
19*91f16700Schasinglulu
20*91f16700SchasingluluIntroduction
21*91f16700Schasinglulu------------
22*91f16700SchasingluluThe current Makefile based buildsystem of TF-A has become complicated and hard
23*91f16700Schasingluluto maintain, there is a need for a new, more flexible solution. The proposal is
24*91f16700Schasingluluto use CMake language for the new buildsystem. The main reasons of this decision
25*91f16700Schasingluluare the following:
26*91f16700Schasinglulu
27*91f16700Schasinglulu* It is a well-established, mature tool, widely accepted by open-source
28*91f16700Schasinglulu  projects.
29*91f16700Schasinglulu* TF-M is already using CMake, reducing fragmentation for tf.org projects can be
30*91f16700Schasinglulu  beneficial.
31*91f16700Schasinglulu* CMake has various advantages over Make, e.g.:
32*91f16700Schasinglulu
33*91f16700Schasinglulu  * Host and target system agnostic project.
34*91f16700Schasinglulu  * CMake project is scalable, supports project modularization.
35*91f16700Schasinglulu  * Supports software integration.
36*91f16700Schasinglulu  * Out-of-the-box support for integration with several tools (e.g. project
37*91f16700Schasinglulu    generation for various IDEs, integration with cppcheck, etc).
38*91f16700Schasinglulu
39*91f16700SchasingluluOf course there are drawbacks too:
40*91f16700Schasinglulu
41*91f16700Schasinglulu* Language is problematic (e.g. variable scope).
42*91f16700Schasinglulu* Not embedded approach.
43*91f16700Schasinglulu
44*91f16700SchasingluluTo overcome these and other problems, we need to create workarounds for some
45*91f16700Schasinglulutasks, wrap CMake functions, etc. Since this functionality can be useful in
46*91f16700Schasingluluother embedded projects too, it is beneficial to collect the new code into a
47*91f16700Schasinglulureusable framework and store this in a separate repository. The following
48*91f16700Schasingluludiagram provides an overview of the framework structure:
49*91f16700Schasinglulu
50*91f16700Schasinglulu|Framework structure|
51*91f16700Schasinglulu
52*91f16700SchasingluluMain features
53*91f16700Schasinglulu-------------
54*91f16700Schasinglulu
55*91f16700SchasingluluStructured configuration description
56*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57*91f16700SchasingluluIn the current Makefile system the build configuration description, validation,
58*91f16700Schasingluluprocessing, and the target creation, source file description are mixed and
59*91f16700Schasingluluspread across several files. One of the goals of the framework is to organize
60*91f16700Schasingluluthis.
61*91f16700Schasinglulu
62*91f16700SchasingluluThe framework provides a solution to describe the input build parameters, flags,
63*91f16700Schasinglulumacros, etc. in a structured way. It contains two utilities for this purpose:
64*91f16700Schasinglulu
65*91f16700Schasinglulu* Map: simple key-value pair implementation.
66*91f16700Schasinglulu* Group: collection of related maps.
67*91f16700Schasinglulu
68*91f16700SchasingluluThe related parameters shall be packed into a group (or "setting group"). The
69*91f16700Schasinglulusetting groups shall be defined and filled with content in config files.
70*91f16700SchasingluluCurrently the config files are created and edited manually, but later a
71*91f16700Schasingluluconfiguration management tool (e.g. Kconfig) shall be used to generate these
72*91f16700Schasinglulufiles. Therefore, the framework does not contain parameter validation and
73*91f16700Schasingluluconflict checking, these shall be handled by the configuration tool.
74*91f16700Schasinglulu
75*91f16700SchasingluluTarget description
76*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^
77*91f16700SchasingluluThe framework provides an API called STGT ('simple target') to describe the
78*91f16700Schasinglulutargets, i.e. what is the build output, what source files are used, what
79*91f16700Schasinglululibraries are linked, etc. The API wraps the CMake target functions, and also
80*91f16700Schasingluluextends the built-in functionality, it can use the setting groups described in
81*91f16700Schasingluluthe previous section. A group can be applied onto a target, i.e. a collection of
82*91f16700Schasinglulumacros, flags, etc. can be applied onto the given output executable/library.
83*91f16700SchasingluluThis provides a more granular way than the current Makefile system where most of
84*91f16700Schasingluluthese are global and applied onto each target.
85*91f16700Schasinglulu
86*91f16700SchasingluluCompiler abstraction
87*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^
88*91f16700SchasingluluApart from the built-in CMake usage of the compiler, there are some common tasks
89*91f16700Schasingluluthat CMake does not solve (e.g. preprocessing a file). For these tasks the
90*91f16700Schasingluluframework uses wrapper functions instead of direct calls to the compiler. This
91*91f16700Schasingluluway it is not tied to one specific compiler.
92*91f16700Schasinglulu
93*91f16700SchasingluluExternal tools
94*91f16700Schasinglulu^^^^^^^^^^^^^^
95*91f16700SchasingluluIn the TF-A buildsystem some external tools are used, e.g. fiptool for image
96*91f16700Schasinglulugeneration or dtc for device tree compilation. These tools have to be found
97*91f16700Schasingluluand/or built by the framework. For this, the CMake find_package functionality is
98*91f16700Schasingluluused, any other necessary tools can be added later.
99*91f16700Schasinglulu
100*91f16700SchasingluluWorkflow
101*91f16700Schasinglulu--------
102*91f16700SchasingluluThe following diagram demonstrates the development workflow using the framework:
103*91f16700Schasinglulu
104*91f16700Schasinglulu|Framework workflow|
105*91f16700Schasinglulu
106*91f16700SchasingluluThe process can be split into two main phases:
107*91f16700Schasinglulu
108*91f16700SchasingluluIn the provisioning phase, first we have to obtain the necessary resources, i.e.
109*91f16700Schasingluluclone the code repository and other dependencies. Next we have to do the
110*91f16700Schasingluluconfiguration, preferably using a config tool like KConfig.
111*91f16700Schasinglulu
112*91f16700SchasingluluIn the development phase first we run CMake, which will generate the buildsystem
113*91f16700Schasingluluusing the selected generator backend (currently only the Makefile generator is
114*91f16700Schasinglulusupported). After this we run the selected build tool which in turn calls the
115*91f16700Schasinglulucompiler, linker, packaging tool, etc. Finally we can run and debug the output
116*91f16700Schasingluluexecutables.
117*91f16700Schasinglulu
118*91f16700SchasingluluUsually during development only the steps in this second phase have to be
119*91f16700Schasinglulurepeated, while the provisioning phase needs to be done only once (or rarely).
120*91f16700Schasinglulu
121*91f16700SchasingluluExample
122*91f16700Schasinglulu-------
123*91f16700SchasingluluThis is a short example for the basic framework usage.
124*91f16700Schasinglulu
125*91f16700SchasingluluFirst, we create a setting group called *mem_conf* and fill it with several
126*91f16700Schasingluluparameters. It is worth noting the difference between *CONFIG* and *DEFINE*
127*91f16700Schasinglulutypes: the former is only a CMake domain option, the latter is only a C language
128*91f16700Schasinglulumacro.
129*91f16700Schasinglulu
130*91f16700SchasingluluNext, we create a target called *fw1* and add the *mem_conf* setting group to
131*91f16700Schasingluluit. This means that all source and header files used by the target will have all
132*91f16700Schasingluluthe parameters declared in the setting group. Then we set the target type to
133*91f16700Schasingluluexecutable, and add some source files. Since the target has the parameters from
134*91f16700Schasingluluthe settings group, we can use it for conditionally adding source files. E.g.
135*91f16700Schasinglulu*dram_controller.c* will only be added if MEM_TYPE equals dram.
136*91f16700Schasinglulu
137*91f16700Schasinglulu.. code-block:: cmake
138*91f16700Schasinglulu
139*91f16700Schasinglulu   group_new(NAME mem_conf)
140*91f16700Schasinglulu   group_add(NAME mem_conf TYPE DEFINE KEY MEM_SIZE VAL 1024)
141*91f16700Schasinglulu   group_add(NAME mem_conf TYPE CONFIG DEFINE KEY MEM_TYPE VAL dram)
142*91f16700Schasinglulu   group_add(NAME mem_conf TYPE CFLAG KEY -Os)
143*91f16700Schasinglulu
144*91f16700Schasinglulu   stgt_create(NAME fw1)
145*91f16700Schasinglulu   stgt_add_setting(NAME fw1 GROUPS mem_conf)
146*91f16700Schasinglulu   stgt_set_target(NAME fw1 TYPE exe)
147*91f16700Schasinglulu
148*91f16700Schasinglulu   stgt_add_src(NAME fw1 SRC
149*91f16700Schasinglulu       ${CMAKE_SOURCE_DIR}/main.c
150*91f16700Schasinglulu   )
151*91f16700Schasinglulu
152*91f16700Schasinglulu   stgt_add_src_cond(NAME fw1 KEY MEM_TYPE VAL dram SRC
153*91f16700Schasinglulu       ${CMAKE_SOURCE_DIR}/dram_controller.c
154*91f16700Schasinglulu   )
155*91f16700Schasinglulu
156*91f16700Schasinglulu.. |Framework structure| image::
157*91f16700Schasinglulu   ../resources/diagrams/cmake_framework_structure.png
158*91f16700Schasinglulu   :width: 75 %
159*91f16700Schasinglulu
160*91f16700Schasinglulu.. |Framework workflow| image::
161*91f16700Schasinglulu   ../resources/diagrams/cmake_framework_workflow.png
162*91f16700Schasinglulu
163*91f16700Schasinglulu--------------
164*91f16700Schasinglulu
165*91f16700Schasinglulu*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
166