Newer
Older
mbed-os / docs / design-documents / tools / cmake.md
@Vikas Katariya Vikas Katariya on 1 Dec 2020 6 KB docs: Update to reflect Mbed CLI 2 changes

CMake Mbed OS

Requirements:

  • CMake 3.19.0 and higher
  • mbed-tools (python 3.6 and higher)

Two steps approach:

  • Mbed OS core CMake
  • Building an application with mbed-tools

Definitions and configurations would be defined in CMake files, an Mbed app configuration file (/path/to/app/mbed_app.json) and Mbed library configuration files (/path/to/mbed-os/<LIBRARY_NAME>/mbed_lib.json). mbed-tools would parse the Mbed library and app configuration files and generate an mbed_config.cmake file.

The following rules must be respected to include special prefix directories (TARGET, COMPONENT and FEATURE_).

Target labels, components, and features defined in /path/to/mbed-os/targets/targets.json are used to help the build system determine which directories contain sources/include files to use in the build process.

This is a problem as labels, components and features directories will most likely be renamed and will not necessarily use the special prefixes TARGET, COMPONENT and FEATURE_ respectively. Whenever such directories are encountered, check the directory name without the special prefix in the CMake list MBED_TARGET_LABELS generated by mbed-tools then include the subdirectory to the build process if found.

For example when the user builds for the NUCLEO_F411RE Mbed target, mbed-tools includes the STM label to the MBED_TARGET_LABELS list. TARGET_STM can only be added to the list of build directories as shown below:

# CMake input source file: mbed-os/targets/CMakeList.txt

if("STM" IN_LIST MBED_TARGET_LABELS)
    add_subdirectory(TARGET_STM)
endif()

The same could be applied to other labels like features or components.

Mbed OS Core (Mbed OS repository)

There are numerous CMake files in the Mbed OS repository tree:

  • A CMakeLists.txt entry point in the Mbed OS root, describing the top level build specification for the Mbed OS source tree.
  • CMakeLists.txt entry points in each Mbed OS module subdirectory, describing the build specification for a module or component

A number of CMake scripts are contained in the mbed-os/tools/cmake directory:

  • core.cmake - selects the core script from the cmake/cores directory, based on the value of the MBED_CPU_CORE variable
  • profile.cmake - selects the profile script from the cmake/profiles directory, based on the value of the MBED_PROFILE variable
  • toolchain.cmake - selects the toolchain script from the cmake/toolchains directory, based on the value of the MBED_TOOLCHAIN variable

The next sections will describe static CMake files within Mbed OS Core repository.

1. Mbed OS CMakeLists.txt Entry Point

The CMakeLists.txt entry point in the root of the Mbed OS repository contains the top level build specification for Mbed OS. This file also includes the auto generated mbed_config.cmake script, which is created by mbed-tools.

This is not intended to be included by an application. Applications must use add_subdirectory(${MBED_PATH}).

2. Toolchain CMake Scripts

All the toolchain settings are defined in the scripts found in cmake/toolchains/.

3. Profile CMake Scripts

The build profiles such as release or debug are defined in the scripts found in cmake/profiles/.

4. MCU Core CMake Scripts

The MCU core definitions are defined in the scripts found in cmake/cores/.

5. Utilities CMake Scripts

Custom functions/macros used within Mbed OS.

7. Component CMakeLists.txt Entry Point

This file statically defines the build specification of an Mbed OS component. It contains conditional statements that depend on the configuration parameters generated by mbed-tools. The rule of thumb is to not expose header files that are internal. We would like to avoid having everything in the include paths as we do now.

Building an Application

mbed-tools is the next generation of command line tooling for Mbed OS. mbed-tools replaces mbed-cli and the Python modules in the mbed-os/tools directory.

mbed-tools consolidates all of the required modules to build Mbed OS, along with the command line interface, into a single Python package which can be installed using standard Python packaging tools.

Each application contains a top-level CMakeLists.txt file. The mbedtools new command can create this top-level CMakeLists.txt, or a user can create it manually. Each application also has a number of json configuration files. mbedtools configure creates an Mbed configuration CMake file (.mbedbuild/mbed_config.cmake). The process for building an application looks like:

  1. Parse the arguments provided to build command
  2. Parse the application configuration
  3. Get the target configuration
  4. Get the Mbed OS configuration (select what modules we need and get their config, paths, etc)
  5. Create .mbedbuild/mbed_config.cmake
  6. Build an application

Configuration

The main purpose of mbed-tools is to parse the Mbed configuration system's JSON files (mbed_lib.json, mbed_app.json and targets.json). The tool outputs a single CMake configuration script, which is included by app.cmake and mbed-os/CMakeLists.txt.

To generate the CMake config script (named mbed_config.cmake) the user can run the configure command:

mbedtools configure -t <toolchain> -m <target>

This will output mbed_config.cmake in a directory named .mbedbuild at the root of the program tree.

mbed_config.cmake contains several variable definitions used to select the toolchain, core and profile CMake scripts to be used in the build system generation:

  • MBED_TOOLCHAIN
  • MBED_TARGET
  • MBED_CPU_CORE
  • MBED_C_LIB
  • MBED_TARGET_SUPPORTED_C_LIBS
  • MBED_PRINTF_LIB

The tools also generate an MBED_TARGET_LABELS variable, containing the labels, components and feature definitions from targets.json, used to select the required Mbed OS components to be built.

The macro definitions parsed from the Mbed OS configuration system are also included in mbed_config.cmake, so it is no longer necessary for the tools to generate any mbed_config.h file to define macros.

mbedignore

With a build system that can understand dependencies between applications, features, components, and targets, mbedignore is no longer needed. CMake creates a list of exactly what's needed for an application build, rather than do what the legacy tools did and include everything by default, leaving the application to specify what is not needed. It's far more natural to express what you need rather than what you don't need, not to mention more future proof should some new feature appear in Mbed OS which your application would need to ignore.