Newer
Older
mbed-os / docs / design-documents / tools / cmake.md

CMake Mbed OS

Requirements:

  • CMake 3.13 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 for backward compatibility.

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 accomplished through a custom CMake function (mbed_add_cmake_directory_if_labels) to append a prefix (TARGET, COMPONENT and FEATURE_) and add matching directories to the list of directories to process.

An example, to add TARGET_STM in the folder targets where we have folders like TARGET_NXP, TARGET_STM, etc:

mbed_add_cmake_directory_if_labels("TARGET")

If a user selects for example target NUCLEO_F411RE, the target defines the label STM. As result, the target folder STM is included.

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/cmake directory:

  • toolchain.cmake - selects the toolchain script from the cmake/toolchains directory, based on the value of the MBED_TOOLCHAIN variable
  • profile.cmake - selects the profile script from the cmake/profiles directory, based on the value of the MBED_PROFILE variable
  • core.cmake - selects the core script from the cmake/cores directory, based on the value of the MBED_CPU_CORE variable
  • util.cmake - custom CMake helper functions and macros
  • app.cmake - contains part of the build specification for an application

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.

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.

6. Application CMake

The CMake script that must be included by all applications using:

include(${MBED_ROOT}/cmake/app.cmake)

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 component entry points make use of functions/macros defined in util.cmake to conditionally include or exclude directories. 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 init 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_PROFILE

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.