Skip to content

Commit 4d4f4d3

Browse files
committed
CMake design doc: restructure and update to the latest mbed-tools updates
Add mbed-tools - how an application is built with mbed-tools and CMake Refactor Mbed OS CMake scripts section - details about mbed-os/cmake scripts
1 parent ef6ba14 commit 4d4f4d3

File tree

1 file changed

+72
-55
lines changed

1 file changed

+72
-55
lines changed
Lines changed: 72 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,118 @@
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
7-
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).
10+
- Building an application with mbed-tools
911

10-
To stay backward compatible, we create common rules as follows.
12+
Definitions and configurations would be defined in CMake files, Mbed app configuration file (`/path/to/app/mbed_app.json`) and Mbed library configuration files (`/path/to/mbed-os/<LIBRARY_NAME>/mbed_lib.json`). The Mbed build system would parse the Mbed configuration files and generate a `CMakeLists.txt` configuration file.
1113

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.
14+
The following rules must be respected for backward compatibility.
1315

14-
Example, to add stm_directory only for STM targets (current rule TARGET_STM):
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.
1517

16-
```
17-
add_subdirectory_if_target(STM stm_directory)
18+
An example, to add `TARGET_STM` in the folder `targets` where we have folders like TARGET_NXP, TARGET_STM, etc:
1819

1920
```
20-
21-
Application example:
22-
23-
```
24-
./TARGET_STM/qspi/driver_stm_qspi.cpp
25-
./TARGET_STM/peripheral_specific_to_stm/stm_specific_driver.cpp
26-
```
27-
28-
As result, the top level application CMake:
29-
21+
mbed_add_cmake_directory_if_labels("TARGET")
3022
```
31-
add_subdirectory_if_target(STM TARGET_STM/qspi)
32-
add_subdirectory_if_target(STM TARGET_STM/peripheral_specific_to_stm)
3323

34-
```
24+
If a user selects for example target `NUCLEO_F411RE`, the target defines the label `STM`. As result, the target folder STM is included.
3525

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.
26+
The same could be applied to other labels like features or components.
3727

3828
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.
3929

4030
## Mbed OS Core (Mbed OS repository)
4131

42-
There are couple of CMakes in the tree.
32+
There are numerous CMake files in the Mbed OS repository tree:
33+
34+
* A `CMakeLists.txt` entry point in the Mbed OS root, describing the top level build specification for the Mbed OS source tree.
35+
* `CMakeLists.txt` entry points in each Mbed OS module subdirectory, describing the build specification for a module or component
4336

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)
37+
A number of CMake scripts are contained in the `mbed-os/cmake` directory:
38+
* `toolchain.cmake` - selects the toolchain script from the `cmake/toolchains` directory, based on the value of the `MBED_TOOLCHAIN` variable
39+
* `profile.cmake` - selects the profile script from the `cmake/profiles` directory, based on the value of the `MBED_PROFILE` variable
40+
* `core.cmake` - selects the core script from the `cmake/cores` directory, based on the value of the `MBED_CPU_CORE` variable
41+
* `util.cmake` - custom CMake helper functions and macros
42+
* `app.cmake` - contains part of the build specification for an application
4743

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

50-
### 1. Boilerplate CMake
46+
### 1. Mbed OS `CMakeLists.txt` Entry Point
5147

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.
48+
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`.
5349

54-
### 2. Toolchain CMake
50+
This is not intended to be included by an application.
5551

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.
52+
### 2. Toolchain CMake Scripts
5753

58-
This toolchain CMake is included by the Mbed OS CMake.
54+
All the toolchain settings are defined in the scripts found in `cmake/toolchains/`.
5955

60-
### 3. Module CMake
56+
### 3. Profile CMake Scripts
6157

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.
58+
The build profiles such as release or debug are defined in the scripts found in `cmake/profiles/`.
6359

60+
### 4. MCU Core CMake Scripts
6461

65-
`add_subdirectory` always adds the directory to the main CMake.
62+
The MCU core definitions are defined in the scripts found in `cmake/cores/`.
6663

67-
```
68-
add_subdirectory(drivers)
69-
```
64+
### 5. Utilities CMake Scripts
7065

71-
Conditionally directories addition based on the config:
66+
Custom functions/macros used within Mbed OS.
7267

73-
```
74-
add_subdirectory_if_config(CONFIG_REQUIRES_RTOS rtos)
75-
```
76-
77-
Conditionally directories addition based on the target/toolchain/feature.
68+
### 6. Application CMake
7869

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

8072
```
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)
73+
include(${MBED_ROOT}/cmake/app.cmake)
8474
```
8575

76+
### 7. Component `CMakeLists.txt` Entry Point
8677

87-
## Application CMake
78+
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.
79+
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.
8880

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.
81+
## Building an Application
9082

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.
83+
`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.
84+
85+
`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.
9286

9387
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:
9488

9589
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
90+
1. Parse the application configuration
91+
1. Get the target configuration
92+
1. Get the Mbed OS configuration (select what modules we need and get their config, paths, etc)
93+
1. Create .mbedbuild/mbed_config.cmake
94+
1. Build an application
95+
96+
### Configuration
97+
98+
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`.
99+
100+
To generate the CMake config script (named `mbed_config.cmake`) the user can run the `configure` command:
101+
102+
`mbedtools configure -t <toolchain> -m <target>`
103+
104+
This will output `mbed_config.cmake` in a directory named `.mbedbuild` at the root of the program tree.
105+
106+
`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:
107+
* `MBED_TOOLCHAIN`
108+
* `MBED_TARGET`
109+
* `MBED_CPU_CORE`
110+
* `MBED_PROFILE`
111+
112+
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.
113+
114+
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.
115+
116+
### mbedignore
117+
118+
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)