Skip to content

Commit f0072e7

Browse files
0xc0170hugueskamba
authored andcommitted
CMake design doc: update to the latest mbed-tools updates
Refactor Mbed OS CMake scripts section - details about mbed-os/cmake scripts Add mbed-tools - how mbed-tools built an application with CMake
1 parent 10f4212 commit f0072e7

File tree

1 file changed

+70
-55
lines changed

1 file changed

+70
-55
lines changed

docs/design-documents/tools/cmake.md

Lines changed: 70 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,116 @@
11
# CMake Mbed OS
22

3+
Requirements:
4+
- CMake 3.13 and higher
5+
- `mbed-tools` (python 3.6 and higher)
6+
37
Two steps approach:
48

59
- Mbed OS core CMake
6-
- Application CMake
10+
- Building an application with mbed-tools
711

8-
All what can be defined should be in CMake files and configuration (app/mbed .json files). Our build system would parse the configuration, create rules and generate top level CMake file that would include others (application CMake files plus also Mbed OS core CMake).
12+
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.
913

10-
To stay backward compatible, we create common rules as follows.
14+
The following rules must be respected for backward compatibility.
1115

12-
We replace current `TOOLCHAIN_`, `FEATURE_`, `TARGET_` by providing `add_subdirectory` macros. There would be `if_target()`, `if_feature()`, `_if_toolchain()` macros for better readability.
16+
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.
1317

14-
Example, to add stm_directory only for STM targets (current rule TARGET_STM):
18+
An example, to add `TARGET_STM` in the folder `targets` where we have folders like TARGET_NXP, TARGET_STM, etc:
1519

1620
```
17-
add_subdirectory_if_target(STM stm_directory)
18-
21+
mbed_add_cmake_directory_if_labels("TARGET")
1922
```
2023

21-
Application example:
24+
If a user selects for example target `NUCLEO_F411RE`, the target defines the label `STM`. As result, the target folder STM is included.
2225

23-
```
24-
./TARGET_STM/qspi/driver_stm_qspi.cpp
25-
./TARGET_STM/peripheral_specific_to_stm/stm_specific_driver.cpp
26-
```
26+
The same could be applied to other labels like features or components.
2727

28-
As result, the top level application CMake:
28+
## Mbed OS Core (Mbed OS repository)
2929

30-
```
31-
add_subdirectory_if_target(STM TARGET_STM/qspi)
32-
add_subdirectory_if_target(STM TARGET_STM/peripheral_specific_to_stm)
30+
There are numerous CMake files in the Mbed OS repository tree:
3331

34-
```
32+
* A `CMakeLists.txt` entry point in the Mbed OS root, describing the top level build specification for the Mbed OS source tree.
33+
* `CMakeLists.txt` entry points in each Mbed OS module subdirectory, describing the build specification for a module or component
3534

36-
There would be static CMakes in the `./TARGET_STM/qspi/` and `./TARGET_STM/peripheral_specific_to_stm` that would define what files should be included or specific settins for these modules.
35+
A number of CMake scripts are contained in the `mbed-os/cmake` directory:
36+
* `toolchain.cmake` - selects the toolchain script from the `cmake/toolchains` directory, based on the value of the `MBED_TOOLCHAIN` variable
37+
* `profile.cmake` - selects the profile script from the `cmake/profiles` directory, based on the value of the `MBED_PROFILE` variable
38+
* `core.cmake` - selects the core script from the `cmake/cores` directory, based on the value of the `MBED_CPU_CORE` variable
39+
* `util.cmake` - custom CMake helper functions and macros
40+
* `app.cmake` - contains part of the build specification for an application
3741

38-
To migrate to the new build system, we can provide auto scanning of the module and generate CMake based on what we find or use the way as described above. In both cases, we could stay backward compatible.
42+
The next sections will describe static CMake files within Mbed OS Core repository.
3943

40-
## Mbed OS Core (Mbed OS repository)
44+
### 1. Mbed OS `CMakeLists.txt` Entry Point
4145

42-
There are couple of CMakes in the tree.
46+
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`.
4347

44-
1. Mbed OS boiler plate defined in Mbed OS root (provides way for build system to overwrite/add configuration)
45-
2. Mbed OS Toolchain settings (toolchain.cmake) that would get generated based on the toolchain selected
46-
3. Each module has own CMake (describing the module - what files are there, target/feature/component selection based on target, etc)
48+
This is not intended to be included by an application.
4749

48-
The next sections will describe static CMake files within Mbed OS Core repository.
50+
### 2. Toolchain CMake Scripts
4951

50-
### 1. Boilerplate CMake
52+
All the toolchain settings are defined in the scripts found in `cmake/toolchains/`.
5153

52-
The main CMake file in Mbes OS repository provides just boilerplate for Mbed OS to be built. It described the Mbed OS tree, provides all the options we have in Mbed OS. This will be autogenerated by the tools.
54+
### 3. Profile CMake Scripts
5355

54-
### 2. Toolchain CMake
56+
The build profiles such as release or debug are defined in the scripts found in `cmake/profiles/`.
5557

56-
There are 3 toolchains, we provide the template that tools could fill in. The information is already in the build tools, we just need to extract that info and make it CMake compatible.
58+
### 4. MCU Core CMake Scripts
5759

58-
This toolchain CMake is included by the Mbed OS CMake.
60+
The MCU core definitions are defined in the scripts found in `cmake/cores/`.
5961

60-
### 3. Module CMake
62+
### 5. Utilities CMake Scripts
6163

62-
This file statically defines the structure of the module within Mbed OS. It's conditionally config based. We use regular CMake expressions plus extend it with own macros to conditionally include/exclude directories. The thumb of the rule, do not expose headers that are internal. We would like to avoid having everything in the include paths as we do now.
64+
Custom functions/macros used within Mbed OS.
6365

66+
### 6. Application CMake
6467

65-
`add_subdirectory` always adds the directory to the main CMake.
68+
The CMake script that must be included by all applications using:
6669

6770
```
68-
add_subdirectory(drivers)
71+
include(${MBED_ROOT}/cmake/app.cmake)
6972
```
7073

71-
Conditionally directories addition based on the config:
74+
### 7. Component `CMakeLists.txt` Entry Point
7275

73-
```
74-
add_subdirectory_if_config(CONFIG_REQUIRES_RTOS rtos)
75-
```
76+
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.
77+
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.
7678

77-
Conditionally directories addition based on the target/toolchain/feature.
79+
## Building an Application
7880

81+
`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.
7982

80-
```
81-
add_subdirectory_if_target(STM targets\TARGET_STM)
82-
add_subdirectory_if_toolchain(GCC_ARM cmsis\TARGET_GCC_ARM)
83-
add_subdirectory_if_feature(BLE ble\FEATURE_BLE)
84-
```
83+
`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.
8584

85+
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:
8686

87-
## Application CMake
87+
1. Parse the arguments provided to build command
88+
1. Parse the application configuration
89+
1. Get the target configuration
90+
1. Get the Mbed OS configuration (select what modules we need and get their config, paths, etc)
91+
1. Create .mbedbuild/mbed_config.cmake
92+
1. Build an application
8893

89-
We should provide application CMake functionality with our own configuration. There are couple of approaches we could take. Statically defined CMake but then this disconnectes config and CMake - as CMake contains configuration for a project (like includes, sources, etc). Our build tool would need to parse CMake to get all paths used in the project or Mbed OS to find out where to look for configuration file. Therefore the build system has a knowledge as it is currently. We use `requires` to include/exclude modules.
94+
### Configuration
9095

91-
By default, baremetal would be selected - requires set to hal, platform, drivers and cmsis. If an app needs anything else, would use `requires` in the config to include - BLE/networking/etc.
96+
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`.
9297

93-
A user create own CMake file to configure an application, also with `mbed_app.json` configuration file. The building of an app would look like:
98+
To generate the CMake config script (named `mbed_config.cmake`) the user can run the `configure` command:
9499

95-
1. Parse the arguments provided to build command
96-
2. Parse the application configuration
97-
3. Get the target configuration
98-
4. Get the Mbed OS configuration (select what modules we need and get their config, paths, etc)
99-
5. Create the toolchain.cmake file
100-
6. Inject all previous steps to the Mbed OS Core CMake
101-
7. Build an application
100+
`mbedtools configure -t <toolchain> -m <target>`
101+
102+
This will output `mbed_config.cmake` in a directory named `.mbedbuild` at the root of the program tree.
103+
104+
`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:
105+
* `MBED_TOOLCHAIN`
106+
* `MBED_TARGET`
107+
* `MBED_CPU_CORE`
108+
* `MBED_PROFILE`
109+
110+
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.
111+
112+
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.
113+
114+
### mbedignore
115+
116+
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.

0 commit comments

Comments
 (0)