cancel
Showing results for 
Search instead for 
Did you mean: 

CMake integration in STM32CubeMX and usage in STM32CubeIDE for Visual Studio Code

Nawres GHARBI
ST Employee

Summary

This article aims to introduce STM32 developers to the basics of CMake, focusing on practical use cases that simplify the learning curve and help avoid common pitfalls during onboarding. 

Introduction

In the rapidly evolving world of embedded development, efficient and reliable build systems play a crucial role in accelerating product development and ensuring code quality. For STM32 developers, grasping the build process is fundamental to fully leveraging the power of STM32 microcontrollers and their extensive ecosystem. 

CMake has emerged as a modern, versatile, and widely adopted build system generator that addresses many challenges faced by embedded developers today. Unlike traditional IDE-specific project formats, CMake provides a unified, flexible, and portable approach to managing builds across different platforms, toolchains, and environments. 

1. Why learn CMake for STM32 development? 

1.1 IDE independence and choice

STM32CubeIDE and Eclipse/CDT offer excellent GUI-based development solutions. However, to meet the growing demand for automation and modern engineering practices, we are expanding our offering to fully support flexible, CLI-based workflows and robust CI/CD integration.

Our command-line tools (CLT) are the first step in this transition. We are fundamentally embracing CMake because it provides the necessary foundation for true flexibility. CMake enables developers to easily generate project files for a variety of IDEs or compile code directly via the command line, ensuring maximum freedom and tool choice.

1.2 Improved project portability and scalability

CMake uses simple, text-based configuration files (CMakeLists.txt) that are easy to version control, share, and maintain. This is not the case with IDE-specific project files that are often bulky and difficult to manage. As STM32 projects grow in complexity, CMake’s modular approach helps maintain a clean and scalable build system.

1.3 Compiler abstraction

CMake’s toolchain abstraction can allow developers to switch seamlessly between toolchains without rewriting build scripts. This flexibility allows STM32 developers to more easily port projects between toolchains. 

1.4 Automation and continuous integration ready 

In modern embedded development, automated builds and testing pipelines are key to maintaining code quality and accelerating delivery. CMake’s command-line driven workflow integrates naturally with continuous integration (CI) systems, enabling STM32 teams to automate builds, run tests, and deploy firmware efficiently.

1.5 Software component and library integration

Many STM32 software components, middleware, and libraries now provide native CMake support or integration examples. Learning CMake empowers developers to take full advantage of these resources, reducing integration effort.

By understanding and adopting CMake, STM32 developers gain a powerful skillset that enhances productivity, fosters collaboration, and future-proofs their projects. This article will guide you step-by-step through essential CMake concepts and practical examples tailored to STM32 development, ensuring a smooth and confident onboarding experience. 

This article is not an intended to be full training on all CMake concepts and usage. To learn more, visit the official CMake online documentation link. 

2. How to generate a CMake project from STM32CubeMX and open it in STM32Cube for Visual Studio Code

To generate a CMake project, follow these steps:

  • After configuring your project, select CMake in the STM32CubeMX toolchain configuration and choose [GCC] or [Clang] as compiler/linker.

NawresGHARBI_0-1761040114190.png

 

  • After generating the project, click on [Open Folder] to open the project in the file explorer.

 

           NawresGHARBI_1-1761040114195.png                  NawresGHARBI_2-1761040114197.png

  • Open VS Code and click on the [File] menu, then click [Open Folder] to import the created project

The selected folder must contain only one Project (CMakeLists.txt). If you want to open multiple projects in your workspace, you must add them one by one using “File → Add Folder to Workspace…” menu.

 

NawresGHARBI_3-1761040114203.png  NawresGHARBI_4-1761040114205.png

3. STM32CubeMX generated files

STM32CubeMX is responsible for the generation of two types of CMake files:

  • Tool-owned files - do not modify, these will be overwritten by STM32CubeMX.      
  • User-owned files - owned and modified by the user to manage builds.

 

Laurids_PETERSEN_1-1764930765166.png

 

4. Generated files

4.1 How to create a configuration preset

You can create or add your own configuration and build preset in the CMakePresets.json file

This is an example of a preset configuration:

NawresGHARBI_34-1761040930088.png

For more details about the parameters, visit https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html

After creating the config preset, a build preset must be created in the same file example:

 

NawresGHARBI_35-1761040994062.png

 

To use this configuration preset you can select it from the “Project Status” tab of the CMake extension interface as following, or via the command line with --preset=example:

NawresGHARBI_36-1761041070603.png

You can also use the CMAKE_BUILD_TYPE as a condition to build/include files.

4.2 CMakeLists.txt

CMakeLists.txt is a one-time generated file. Any user change is kept if STM32CubeMX or other ST tools are regenerating assets.

 Two CMakeLists.txt files are available in your project:

  • One generic CMakeLists.txt in the main project folder.
  • One CubeMX-generated CMakeLists.txt included by the generic one containing the STM32CubeMX project configuration.
NawresGHARBI_38-1761041304199.png           NawresGHARBI_39-1761041332680.png

 

4.2.1 How to add source files

We advise using relative paths instead of full path to help share your project across development environments.

To add source files, use the "target_sources" node as shown below:

NawresGHARBI_40-1761041543795.png

4.2.2 How to add include files/folders

  • CMakeLists.txt is a one generated time file, so any user change will be kept after project regeneration.
  • The build engine is able to search for your include files in the user-added directories.

To add header folders, use the "target_include_directories" node:

NawresGHARBI_42-1761041712783.png

4.2.3 How to add symbols

  • CMakeLists.txt is a one generated time file, so any user change will be kept after project regeneration.
  • The build engine is then able to use the user added symbols when building the project.
To add symbols you can use the "target_compile_definitions" node:NawresGHARBI_43-1761041774129.png

4.2.4 How to add libraries

  • CMakeLists.txt allows you by the two tags in the left side to add libraries to your project and specify a custom folder to search for them.
  • Each change must be done in the CMakeLists.txt under the CMAKE folder which is managed by STM32CubeMX.

To add library files, use the "target_link_libraries" node for the lib name and "target_link_directories" for the lib path:

NawresGHARBI_44-1761041933140.pngNawresGHARBI_45-1761041939560.png

4.3 Toolchain files

Toolchain files are for GCC and starm-clang.cmake for llvm. Both files embed the parameters, but the configuration differs from one toolchain to another.

When creating a new project from extension, you have the choice between GCC LLVM or a hybrid environment with both LLVM and GCC. In the hybrid environment, both files are present in the project.

 

NawresGHARBI_46-1761042015720.png   NawresGHARBI_47-1761042021416.png

4.3.1 Compiler settings

You can change your compiler settings from this batch of parameter

NawresGHARBI_50-1761042323733.png

4.3.2 Build output suffix

You can change your output settings from this batch of parameter

NawresGHARBI_51-1761042373642.png

4.3.3 Cortex settings

 

You can change your cortex settings for the compiler from this batch of flags

NawresGHARBI_52-1761042445753.png

4.3.4 Build optimization settings

The settings depend on the selected context. By default, only release and debug are available. If you have an additional build context, you can add more configurations in this area.

 

NawresGHARBI_53-1761042493764.png

 

The compiler supports the following optimization levels:

  • -O (same as -O1)
  • -O0 (do not optimize, the default if no optimization level is specified)
  • -O1 (optimize minimally, favoring compilation time)
  • -O2 (optimize more, without speed/size trade-off)
  • -O3 (optimize even more, favoring speed)
  • -Ofast (optimize very aggressively to the point of breaking standard compliance, favoring speed. May change program behavior)
  • -Og (Optimize debugging experience.

-Og enables optimizations that do not interfere with debugging. It should be the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience.)

  • -Os (optimize for size). 

-Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size. -Os disables the following optimization flags: -falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays -ftree-vect-loop-version)

4.3.5 ASM configuration

You can change your ASM compiler settings from this batch of parameter

NawresGHARBI_54-1761042589676.png

 

4.3.6 Linker configuration

You can change your Linker settings from this batch of parameter

NawresGHARBI_55-1761042625860.png

5. STM32CubeMX generated project structure

Two types of projects can be generated, single context projects and multicontext projects.

A multicontext project is generated for:

  • Dual core products
  • Flash less products
  • Secure products

In the figure below you can see the difference between these two types of projects.

Laurids_PETERSEN_0-1764928421537.png

 

 

For the multicontext projects, you find the same described files before in single projects but with more specificity:

  • Top-level Cmakelists.txt and CMakePresets.json. (All subprojects will inherit from those two files.)
  • Specific cmakelists.txt and CMakePresets.json for each sub project where you can add/modify settings for only the related subproject.

Get additional support

For additional help, visit our VS Code forum board below and ask your question there: 

https://community.st.com/t5/stm32cubeide-for-visual-studio/bd-p/stm32-vscode-extension-mcus

Version history
Last update:
‎2025-12-05 2:55 AM
Updated by: