# 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//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 1. Parse the application configuration 1. Get the target configuration 1. Get the Mbed OS configuration (select what modules we need and get their config, paths, etc) 1. Create .mbedbuild/mbed_config.cmake 1. 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 -m ` 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.