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