Skip to content

Commit df43984

Browse files
committed
doc: merge the cmake wiki
Signed-off-by: Frederic Pillon <[email protected]>
1 parent 2a3d04b commit df43984

10 files changed

+854
-3
lines changed

Home.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
![stm32duino](https://avatars2.githubusercontent.com/u/12180191?v=3&s=200)
1+
![stm32duino](https://avatars2.githubusercontent.com/u/12180191?v=3&s=200)
22
# Welcome to the **stm32duino** wiki!
33

44
# [[Getting Started|Getting-Started]]
@@ -49,4 +49,4 @@ Or submit a topic on the [stm32duino forum](http://stm32duino.com):
4949
# Links
5050
[Arduino.cc official website](https://www.arduino.cc/)
5151

52-
[STM32 MCU](http://www.st.com/en/microcontrollers/stm32-32-bit-arm-cortex-mcus.html)
52+
[STM32 MCU](http://www.st.com/en/microcontrollers/stm32-32-bit-arm-cortex-mcus.html)

_Sidebar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* [Board support based on a core](https://github.com/stm32duino/wiki/wiki/Custom-board-based-on-a-core)
5050
* [How to debug](https://github.com/stm32duino/wiki/wiki/How-to-debug)
5151
* [PlatformIO](https://github.com/stm32duino/wiki/wiki/PlatformIO)
52-
* [CMake support](https://github.com/massonal/Arduino_Core_STM32/wiki)
52+
* [CMake support](./Cmake_home)
5353
</details>
5454

5555
* <details>

_cmake/Advanced usage.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
2+
This page will discuss how to customize your project beyond the functions provided with Arduino_Core_STM32, using some standard CMake features.
3+
Hence, knowledge of both CMake and the STM32 CMake framework is assumed.
4+
Regarding the latter, an [`insight()`](./Functions-reference#insights) can be useful, namely LOGIC_STRUCTURE.
5+
6+
Below is the logic structure of the simplest example, the Blink sketch.
7+
The following sections may refer to it to illustrate their points.
8+
9+
![Blink logic structure](../img/logicstructure.gv.svg)
10+
11+
12+
# Adding new settings to the build
13+
14+
Depending on the particular setting, CMake provides several functions:
15+
- [`target_compile_definitions()`](https://cmake.org/cmake/help/latest/command/target_compile_definitions.html)
16+
- [`target_compile_options()`](https://cmake.org/cmake/help/latest/command/target_compile_options.html)
17+
- [`target_include_directories()`](https://cmake.org/cmake/help/latest/command/target_include_directories.html)
18+
- [`target_link_directories()`](https://cmake.org/cmake/help/latest/command/target_link_directories.html)
19+
- [`target_link_libraries()`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html)
20+
- [`target_link_options()`](https://cmake.org/cmake/help/latest/command/target_link_options.html)
21+
- [`target_sources()`](https://cmake.org/cmake/help/latest/command/target_sources.html)
22+
23+
Most of these commands make use of the `PUBLIC`, `INTERFACE` or `PRIVATE` keywords.
24+
- `PUBLIC` and `INTERFACE` will apply the setting to all the dependers of the target in question;
25+
- `INTERFACE` and `PRIVATE` apply the setting to the target itself.
26+
27+
[Here](https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html) is a comprehensive list of commands that can be used in a project.
28+
29+
# Where to add the settings
30+
31+
Several interface targets are of interest when the settings are to affect more than just the user sketch:
32+
- `base_config` is depended upon by all the project (core, libraries, sketch);
33+
- The targets ending in `_usage` contain settings that are propagated upwards through the tree;
34+
these are useful when the scope of the setting is more specific.
35+
36+
It is also possible to add `PRIVATE` build settings directly on the code targets; e.g., to the sketch target.
37+
However, a good practice is to instead create additional INTERFACE targets to put these flags in,
38+
and make it a dependency of other parts of the project, using [`target_link_libraries()`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html).
39+
40+
Some code part come in three targets, e.g., `core`, `core_bin`, `core_usage`.
41+
The actual source files always are in the `_bin` target; that is to say, when there are source files (think of precompiled Arduino libraries).
42+
`*_usage` gathers "public" settings to be used in that that target, and also by the dependers.
43+
Lastly, the bare name target is just a wrapper are the previous two.
44+
45+
# Change the way CMake builds the project
46+
47+
Some variables affect the way CMake builds the project.
48+
They can be specified either in a CMakeLists.txt, or (preferably) on the command-line, with the following syntax:
49+
```sh
50+
cmake -S ... -B ... -DVARIABLE=VALUE
51+
```
52+
_(The value is mandatory; use `1`, `ON` or `YES` as boolean true value.)_
53+
54+
A comprehensive list of such variables is defined in the [CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html); some of the most relevant ones are listed below.
55+
56+
- [`CMAKE_DISABLE_PRECOMPILE_HEADERS`](https://cmake.org/cmake/help/latest/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.html)
57+
- [`CMAKE_INCLUDE_CURRENT_DIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_INCLUDE_CURRENT_DIR.html)
58+
- [`CMAKE_INTERPROCEDURAL_OPTIMIZATION`](https://cmake.org/cmake/help/latest/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.html) (equivalent to the `LTO` switch in [`overall_settings()`](./Functions-reference#overall_settings))
59+
- [`CMAKE_UNITY_BUILD`](https://cmake.org/cmake/help/latest/variable/CMAKE_UNITY_BUILD.html)
60+
- [`EXECUTABLE_OUTPUT_PATH`](https://cmake.org/cmake/help/latest/variable/EXECUTABLE_OUTPUT_PATH.html)
61+
62+
CMake is also affected by some environment variables (doc [here](https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html)), e.g.:
63+
- [`CMAKE_BUILD_PARALLEL_LEVEL`](https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html)
64+
- [`CMAKE_GENERATOR`](https://cmake.org/cmake/help/latest/envvar/CMAKE_GENERATOR.html) (_usful to omit the `-G` on each CMake call_)
65+
- `CC`, `CXX`, `CFLAGS`, `CXXFLAGS`, `LDFLAGS` with the same meaning as with `make`
66+
67+
Please note that not all features work, or even make sense, for embedded projects.
68+
Caution and testing are advised when dealing with the variables listed here.

_cmake/Arduino (in)compatibility.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Deviations to the behavior of Arduino IDE
2+
3+
While the CMake toolsuite aims at replicating the behavior of Arduino IDE, there may be some deviations, by design or accident.
4+
This page lists all such known deviations.
5+
6+
# Source files
7+
8+
Arduino IDE dynamically discovers all the source files of the sketch when rebuilding.
9+
On the other hand, with the CMake tools, there is a hard-coded list of files to update manually (cf. [`build_sketch()`](./Functions-reference#build_sketch).).
10+
11+
This comes from the different levels at which the tools operate: Arduino IDE behaves as a build system, while CMake is a _meta_ build system.
12+
This means that, while CMake can discover all the source files when it is manually invoked,
13+
it may not be reinvoked (as should be) after a source file is added, since it was not "monitoring" that file in the first place.
14+
Please reat the [warning note](https://cmake.org/cmake/help/latest/command/file.html#glob) in the CMake documentation for details.
15+
16+
Also, as mentioned in [the Arduino documentation](https://arduino.github.io/arduino-cli/0.21/sketch-build-process/#pre-processing), all the
17+
`.ino` files of the sketch are concatenated during the pre-processing step.
18+
This is not implemented with CMake, as most sketches have a single `.ino` file, but if you fill the need for this feature, please submit a PR!
19+
20+
On the other hand, Arduino _requires_ each sketch to have a `.ino` file with the same name as the sketch folder.
21+
In CMake, there is no such restriction; you may name your `.ino` files differently, or even not have any `.ino` file at all.
22+
23+
Final tweak: as part of the conversion `.ino` -> `.cpp`, Arduino IDE generates the prototypes of all the functions defined in .ino files.
24+
This is meant mostly for beginners, so that they may write their functions in any order without the added complexity of prototypes.
25+
This process is replicated with CMake, with the slight nuance that Arduino runs the GCC preprocessor _before_ doing this,
26+
in order to resolve all the macros and get "sane" C++ code. As opposed to this, CMake does not model the preprocessing stage, so it has to work
27+
on the "raw" `.ino` file. Usually this has no consequence whatsoever, but it may cause trouble if you use complex macros that alter the structure
28+
of the code.
29+
30+
# Library management
31+
32+
Arduino IDE comes with a full library management suite, to download and update third-pary libraries as needed.
33+
This is out of the scope of the CMake tool; users have to download and manage their libraries externally.
34+
It is, however, possible to reuse the libraries installed by `arduino-cli`, e.g., by using the [quickstart script](./Quickstart-guide#Quickstart%20script).
35+
36+
Second item, Arduino IDE discovers at compile-time what libraries the sketch needs.
37+
This is done by catching GCC errors during the preprocessing stage, and fuzzy matching the missing `#include` with all the available libraries,
38+
as described in [their documentation](https://arduino.github.io/arduino-cli/0.21/sketch-build-process/#dependency-resolution).
39+
40+
CMake does not have access to all these data _at configure-time_; also, it does not model the preprocessing at all.
41+
This means the dependency resolution process, if implemented, would have been awkward and fragile.
42+
This is why another solution has been preferred: to have the user fill in all the dependencies manually (cf. the `DEPENDS` keyword in several functions in [Functions reference](./Functions-reference).)
43+
44+
45+
# Upload, serial monitor, debugger
46+
47+
These items are out of the scope of a CMake-based tool. Your IDE may handle (part of) those features; please refer to its documentation.
48+
As a fallback, [`arduino-cli`](https://arduino.github.io/arduino-cli/0.25/) may also be used to these ends.

_cmake/Cmake_home.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Welcome to the CMake port of Arduino_Core_STM32!
2+
3+
The goal of this repository is to let users build Arduino sketches for STM32 boards, without using neither Arduino IDE nor `arduino-cli`.
4+
Advantages of this approach include:
5+
- faster build time (about -50%, tested on Windows 10 and Ubuntu20.04);
6+
- flexibility: CMake has a full language centered around build description;
7+
- integration with IDEs: CMake integrates with most recent IDEs, easing the work of those who code outside of Arduino IDE;
8+
- better support of incremental compilation;
9+
- overstepping limits set by Arduino: sketch filename, library selection...
10+
11+
Of course, this all has a cost: building is no longer as simple as hitting "build" in Arduino IDE; there is a CMake file to write and maintain.
12+
However, much has been done to make the file as high-level as possible: it is written in CMake's own syntax, but makes heavy use of the custom functions defined here in the [`cmake/` folder](../blob/cmake_dev/cmake).
13+
Didactic examples can be found on a separate repository: [https://github.com/stm32duino/CMake_workspace](https://github.com/stm32duino/CMake_workspace).
14+
15+
Before delving into this wiki, be sure to read [the dedicated README](https://github.com/massonal/Arduino_Core_STM32/blob/cmake_dev/README_CMAKE.md) first!

_cmake/Functions reference.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# Functions reference
2+
3+
This document lists all the functions defined in the [`/cmake`](../blob/cmake_dev/cmake) folder in this project.
4+
It would be a good idea to add this folder to the "CMake search path" in your project :
5+
6+
```cmake
7+
list(APPEND CMAKE_MODULE_PATH ${CORE_PATH}/cmake)
8+
```
9+
(done by default in the [quickstart template](./Quickstart-guide#Quickstart-script).)
10+
11+
All the functions are defined in a CMake module of the same name. Therefore, you have to include said module before calling the function:
12+
13+
```cmake
14+
include(foo)
15+
foo()
16+
```
17+
18+
(Of course, this does _not_ apply to the CMake built-in functions as described in [Introduction to CMake](./Introduction-to-CMake#CMake-language). These can be called directly.)
19+
20+
# Functions emulating the Arduino behavior
21+
22+
## build_sketch
23+
24+
__Syntax:__
25+
26+
```cmake
27+
build_sketch(TARGET <targetName>
28+
SOURCES <sourcefile...>
29+
[DEPENDS <dependency...>]
30+
)
31+
```
32+
33+
This is the main function that encapsulates most of the automation of Arduino. It should only be called _after_ `overall_settings` and `set_board`.
34+
35+
- `targetName` is the name of the [binary target](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#binary-executables) that will be created as a result of this function; this is a handle that may be reused in later calls, to e.g., `insights()`.
36+
- `sourcefile...` is a list of sources files to be compiled. This does not comprise header files (`.h`).
37+
You are strongly advised to hard-code the list of files directly in the CMakeLists.txt. Using [wildcards](https://cmake.org/cmake/help/latest/command/file.html#glob) is possible, but not guaranteed to work in all cases.
38+
- the optional `dependencies` are targets, usually Arduino libraries such as created by `external_library()`, that the sketch depdends on.
39+
The CMake build model makes it awkward at best to automatically handle dependencies the way Arduino does, so they have to be specified explicitely.
40+
41+
What this function does is the following:
42+
43+
- Include the parts of Arduino_Core_STM32 needed for the project (core + right variant);
44+
- Preprocess the sources: turn the `.ino` files to `.cpp`;
45+
- Create the binary executable target;
46+
- Bind the target to its dependencies (core + "DEPENDS");
47+
- Add post-build hooks to:
48+
- Display the size report message ("Sketch uses xxx bytes of program storage space. Maximum is yyy bytes...";
49+
- Convert the binary to `.bin` and `.hex`.
50+
51+
## external_library
52+
53+
__Syntax:__
54+
55+
```cmake
56+
external_library(PATH <path_to_lib>
57+
[DEPENDS <dependency...>]
58+
[FORCE]
59+
)
60+
```
61+
62+
This function is used to add a third-party library in the build description. It takes as arguments:
63+
- the path to the library to parse;
64+
- as with `build_sketch()`, an optional list of dependencies of the library;
65+
- optionally, the `FORCE` keyword; read below about it.
66+
67+
Most third-party libraries do not ship with a CMakeLists.txt.
68+
Therefore, one needs to be generated before that library can be used in a CMake build.
69+
This function wraps the generation of the CMakeLists.txt and the subsequent `add_subdirectory()` to actually add the library to the build.
70+
71+
If no CMakeLists.txt is found, it is autogenerated by a Python script after reading `library.properties`.
72+
The `FORCE` keyword lets you override this behavior and overwrite the CMakeLists.txt unconditionally.
73+
74+
In the default case, the autogenerated CMakeLists.txt will create for the library __a target with the same name as the folder name__.
75+
You can then use this target as a dependency of another library or of your sketch.
76+
77+
Note: libraries built into Arduino_Core_STM32 are handled automatically; they do not need this function and can be used out-of-the-box.
78+
Such libraries include EEPROM, Servo, SPI, Mouse, or Wire.
79+
Libraries that are shipped with Arduino IDE (SD, Ethernet, ...) are not covered by this convenience.
80+
81+
## insights
82+
83+
__Syntax:__
84+
85+
```cmake
86+
insights(TARGET <targetName>
87+
[DIRECT_INCLUDES]
88+
[TRANSITIVE_INCLUDES]
89+
[SYMBOLS]
90+
[ARCHIVES]
91+
[LOGIC_STRUCTURE]
92+
)
93+
```
94+
95+
This function lets you produce insights about the build process.
96+
It uses Graphviz to generate SVG files in order to better understand what happens throughout the build: configuration, compilation, linking.
97+
The mandatory TARGET argument is the name of the element to analyze, usually your sketch target (crated with `build_sketch()`).
98+
Each insight keyword is optional; even when provided, they are not built by default, you have to explicitely generate them with the build tool (e.g., `ninja symbols.svg`).
99+
100+
| Keyword | Generated file | Description |
101+
| :------ | :------------- | :---------- |
102+
| DIRECT_INCLUDES | direct_includes.svg | Shows which source files include which |
103+
| TRANSITIVE_INCLUDES | transitive_includes.svg | Shows which source files include which, both directly and indirectly (chained `#include`) |
104+
| SYMBOLS | symbols.svg | Shows which symbol pull which other(s), at link-time |
105+
| ARCHIVES | archives.svg | Shows which archive pull which other(s), at link-time |
106+
| LOGIC_STRUCTURE | logicstructure.svg | Shows the targets involved in the project, and the dependencies they share. This is a wrapper around a built-in feature of CMake, read about details [here](https://cmake.org/cmake/help/latest/module/CMakeGraphVizOptions.html). |
107+
108+
Note: Enabling some of these graphs can hinder performances much (in the order of +50% build time).
109+
110+
## overall_settings
111+
__Syntax:__
112+
113+
```cmake
114+
overall_settings(
115+
[STANDARD_LIBC]
116+
[PRINTF_FLOAT]
117+
[SCANF_FLOAT]
118+
[DEBUG_SYMBOLS]
119+
[LTO]
120+
[NO_RELATIVE_MACRO]
121+
[UNDEF_NDEBUG]
122+
[CORE_CALLBACK]
123+
[OPTIMIZATION <optLevel>]
124+
[BUILD_OPT <path_to_build.opt>]
125+
[DISABLE_HAL_MODULES <modules...>]
126+
)
127+
```
128+
129+
This function replaces, with additions, some of the options of the menu bar of Arduino IDE.
130+
All the keywords are optional; the default behavior is selected on fallback. The order of the keywords does not matter.
131+
132+
Keywords that take no argument:
133+
- STANDARD_LIBC: switch to Newlib Standard as the runtime library, instead of Newlib Nano;
134+
- PRINTF_FLOAT: enable `%f` in `printf` (Newlib Nano only);
135+
- SCANF_FLOAT: enable `%f` in `scanf` (Newlib Nano only);
136+
- DEBUG_SYMBOLS: add `-g` to GCC (for debug);
137+
- LTO: enable Link-Time Optimizations (`-flto`);
138+
- NO_RELATIVE_MACRO: make `__FILE__` yield absolute paths; the default is the oppisite, for size and security reasons;
139+
- UNDEF_NDEBUG: do not define the `NDEBUG` macro; use this keyword for debug builds;
140+
- CORE_CALLBACK: define the `CORE_CALLBACK` macro; read about use cases [here](https://github.com/stm32duino/wiki/wiki/API#core-callback).
141+
142+
Keywords that take a single argument:
143+
- OPTIMIZATION: takes an optimization level (one of `0123gs`); this will then be passed to GCC's as a `-O` flag;
144+
- BUILD_OPT: add the specified file to GCC's command line, as a `@file`. The file is usually named "build.opt", hence the keyword name. Note: with Arduino IDE, the file is taken by default into account; with CMake, it is not, only this keyword triggers this.
145+
146+
Keyword that takes several arguments:
147+
- DISABLE_HAL_MODULES: lets you disable any unused HAL modules as an optimization.
148+
Read about it [on the wiki](https://github.com/stm32duino/wiki/wiki/HAL-configuration).
149+
The supported HAL modules are:
150+
- ADC
151+
- I2C
152+
- RTC
153+
- SPI
154+
- TIM
155+
- DAC
156+
- EXTI
157+
- ETH
158+
- SD
159+
- QSPI
160+
Disabling them all (when possible) yields a significant additional size gain.
161+
162+
## set_board
163+
164+
__Syntax:__
165+
166+
```cmake
167+
set_board(<boardName>
168+
[SERIAL <serialSetting>]
169+
[USB <usbSetting>]
170+
[XUSB <usbSpeed>]
171+
[VIRTIO <virtioSetting>]
172+
)
173+
```
174+
175+
This function replaces the options of the menu bar of Arduino IDE that are related to board-specific features.
176+
It manages to stay up-to-date with what Arduino IDE would offer by parsing `board.txt`/`platform.txt` as needed,
177+
and caches the result in a CMake-readable database.
178+
179+
The first argument to this function must be the board codename, as used in boards.txt.
180+
E.g., "GENERIC_L010RBTX", not "Generic L010RBTx" (the latter being what the IDE displays).
181+
Then come any number of the four keywords, in any order. As with `overall_settings`, default values are used on fallback.
182+
Depending on your board, not all features may be meaningful. Note: the values for each keyword are case-sensitive!
183+
- SERIAL: Serial support. Usually one of `generic`, `disabled`, `none` (standing for "Enabled (no generic 'Serial')");
184+
- USB: USB support. Usually one of `none`, `CDCgen`, `CDC`, `HID`;
185+
- XUSB: USB speed. Usually one of `FS`, `HS`, `HSFS`;
186+
- VIRTIO: virtIO support. Usually one of `disable`, `generic`, `enabled`.

0 commit comments

Comments
 (0)