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