STM32CubeIDE for Visual Studio Code Documentation

Table Of Contents

- STM32CubeIDE for Visual Studio Code
- Introduction
  - Overview
  - System requirements
  - Release note
- Basic Concepts
  - User interface
  - Command-line tools
  - Visual Studio Code extension packs
  - Bundles
  - CMake
  - Toolchains
  - STMicroelectronics Arm Clang Toolchain for STM32
- Getting Started
  - Installation
  - First project creation
- Workspace and extension workflow
  - Workspace overview
  - Extension commands
  - Project files
  - Multi-project workspaces
- Tutorials
  - Migrating from STM32CubeIDE for Visual Studio Code extension 2.x to 3.x
  - Dual-core STM32 projects
  - Power management
  - RTOS-based STM32 projects
  - Firmware security and integrity
- Development
  - Projects
  - Editing
  - Build
  - Debug
  - API manual
  - Integration with external tools
  - Testing and validation
- Troubleshooting
  - Frequently asked questions
  - Known issues
  - Support

### On this page

- Toolchains components overview
- Hybrid toolchain
  - Integration in STM32CubeMX CMake projects:
  - Command-line flags:
  - C Standard Libraries
- Full LLVM toolchain
  - Linker
  - C Standard Libraries
    - Newlib
      - Integration in STM32CubeMX CMake projects:
      - Command-line flags:
    - Picolibc
      - Integration in STM32CubeMX CMake projects:
      - Command-line flags:
  - C++ support
- Supported architectures
- Migrating from GNU Tools for STM32
  - Toolchain identification
  - Architecture identification
  - C and C++ language extensions
  - Assembly language
  - Optimization flags
- Focus on C standard formatted I/O
  - Hybrid toolchain
    - Newlib
    - Newlib nano
  - Full LLVM toolchain
    - Newlib
    - Picolibc
- Thread local storage
- Components
- Host platforms
- External documentation resources

# STMicroelectronics Arm Clang Toolchain for STM32

ST Arm Clang is a new C/C++ toolchain offering for STM32 development built on the modern LLVM compiler infrastructure and the Arm Toolchain for Embedded toolchain from Arm.

This new LLVM-based toolchain provides developers with a more efficient, flexible, and future-proof development environment while maintaining compatibility with existing projects.

ST Arm Clang is designed as a drop-in replacement for the GNU Tools for STM32, minimizing disruption for developers transitioning to it. However, some minor incompatibilities or divergent features may exist due to differences in the underlying infrastructure. To ease this transition, two flavors of the toolchain are provided:

> - Hybrid toolchain: only the C/C++ LLVM Clang compiler and integrated assembler are used to compile the code into object files (local applications, HAL, etc.). The final binary is built using the tools and libraries from the existing GNU Tools for STM32 (GNU Binutils linker, C/C++ libraries, and runtime). This use case is ideal for developers looking to test or leverage Clang’s compilation benefits while retaining the familiar GNU linking and runtime environment. Both toolchains (Clang and GCC) should be installed on your system, and link-time optimization (LTO) is not available in this mode.

> - Full LLVM toolchain: this version offers the complete long-term LLVM-based solution (Clang compiler, LLVM linker and runtime) with up-to-date libraries, such as Picolibc or LLVM libc++. It benefits from the combined effort from the LLVM community, Arm, and ST research and development teams to reach optimal support, performance, and code-size on STM32 devices. The toolchain offers two distinct C library implementations, allowing developers to choose based on their project priorities or device resources: Newlib for performance and Picolibc for code size.

## Toolchains components overview

Component | GNU Tools for STM32 ( `arm-none-eabi-`) | Hybrid Toolchain | Full LLVM Toolchain
--- | --- | --- | ---
C, C++ compiler | `gcc`, `g++` | `starm-clang`, `starm-clang++` | `starm-clang`, `starm-clang++`
Assembler | `as` | `starm-clang` (integrated assembler) | `starm-clang` (integrated assembler)
Linker | `ld` | `ld` | `starm-lld`
Binutils | `objdump`, `readelf`, … | `starm-objdump`, `starm-readelf`, … | `starm-objdump`, `starm-readelf`, …
Compiler runtime library | `libgcc` | `libgcc` | `libclang_rt`
Unwinder | `libgcc` | `libgcc` | `libunwind`
C standard library | `newlib`, `newlib-nano` | `newlib`, `newlib-nano` | `newlib`, `picolibc`
C++ ABI library | `libsupc++` | `libsupc++` | `libc++abi`
C++ standard library | `libstdc++` | `libstdc++` | `libc++`

## Hybrid toolchain

The Hybrid toolchain mode leverages the Clang compiler and integrated assembler for compiling source code, while relying on the GNU Tools for STM32 for linking and runtime libraries. This approach allows developers to benefit from Clang’s modern compilation capabilities without fully migrating their build environment. It is particularly useful for incremental migration or testing purposes.

In this mode, the toolchain requires both the ST Arm Clang and GNU toolchains to be installed on the system. Link-time optimization (LTO) is not supported due to the mixed toolchain components. The hybrid flavor maintains compatibility with existing GNU linker scripts, libraries, and runtime behaviors, minimizing integration effort.

### Integration in STM32CubeMX CMake projects:

`set(STARM_TOOLCHAIN_CONFIG "STARM_HYBRID")`

### Command-line flags:

`--gcc-toolchain=<PATH_TO_GCC_TOOLCHAIN_ROOT_DIR> --multi-lib-config=<PATH_TO_STARM_CLANG_ROOT_DIR>/multilib.gnu_tools_for_stm32.yaml`

### C Standard Libraries

GNU tools for STM32 toolchain provides two versions of the C standard library Newlib (used by default) and Newlib nano (selected with `starm-clang` GCC spec files emulation: `--gcc-specs=nano.specs`).

## Full LLVM toolchain

The full LLVM toolchain is a complete, standalone solution built entirely on the LLVM infrastructure, including the Clang compiler ( `starm-clang`), LLVM linker ( `starm-lld`), and modern runtime libraries such as Picolibc and libc++. This flavor is designed for long-term use and continuous improvement, providing enhanced performance, and reduced code size.

It supports advanced features like link-time optimization (LTO) and offers two C standard library options — Newlib for performance-oriented applications and Picolibc for minimal code size. The full LLVM toolchain enables developers to fully leverage the benefits of the LLVM toolchain on STM32 devices, with ongoing support and optimizations contributed by ST, Arm, and the LLVM community.

### Linker

`starm-lld` is designed as a drop in replacement for GNU `ld`, however there are some known differences to take into account, see:

> - Linker Script implementation notes and policy in the LLD documentation.

> - The LLD and GNU linker incompatibilities blog post.

### C Standard Libraries

#### Newlib

Newlib is a complete C library implementation specifically designed for embedded systems. This full Newlib variant supports nearly all standard C library features and is optimized to deliver high performance in resource-constrained environments. For detailed information, refer to the Newlib Documentation

##### Integration in STM32CubeMX CMake projects:

To select Newlib in your STM32CubeMX-generated CMake project, set:

`set(STARM_TOOLCHAIN_CONFIG "STARM_NEWLIB")`

##### Command-line flags:

When building from the command line, use the configuration flag:

`--config=newlib.cfg`

#### Picolibc

Picolibc is a modern complete C library implementation targeting the embedded systems with a focus on minimal code size, making it suitable for applications where footprint reduction is critical. More details can be found in Picolibc Documentation

##### Integration in STM32CubeMX CMake projects:

To select Picolibc in your STM32CubeMX-generated CMake project, set:

`set(STARM_TOOLCHAIN_CONFIG "STARM_PICOLIBC")`

##### Command-line flags:

Picolibc is the default mode and requires no additional command-line flag.

### C++ support

C++ is partially supported with the use of libc++ and libc++abi from LLVM. Features that are not supported include:

> - Multithreading

ST Arm Clang uses the unstable libc++ ABI version. This ABI benefits from all the latest libc++ improvements and bug fixes, but may result in link errors when linking against objects compiled against older versions of the ABI. For more information, see https://libcxx.llvm.org/DesignDocs/ABIVersioning.html.

## Supported architectures

- Armv6-M (Cortex-M0/M0+/M1)

- Armv7-M (Cortex-M3)

- Armv7E-M (Cortex-M4/M7)

- Armv8-M Mainline and Baseline (Cortex-M23/M33/M35P)

- Armv8.1-M Mainline and Baseline (Cortex-M52/M55/M85)

See STM32 MCU products list for CPU/product correspondence.

## Migrating from GNU Tools for STM32

### Toolchain identification

ST Arm Clang is identified by the `__starm__` macro.

Toolchain version macros:

Version number | GNU macro | LLVM macro
--- | --- | ---
Major | `__GNUC__` | `__clang_major__`
Minor | `__GNUC_MINOR__` | `__clang_minor__`
Patch level | `__GNUC_PATCHLEVEL__` | `__clang_patchlevel__`

Note that `starm-clang` defines GNU macros for compatibility too: `__GNUC__` equal to `4`, `__GNUC_MINOR__` equal to `2`, and `__GNUC_PATCHLEVEL__` equal to `1`.

### Architecture identification

Both compilers define the same macros to identify Arm® architectures, except for Armv8.1-M Mainline: GCC defines the `__ARM_ARCH_8M_MAIN__` macro, whereas Clang defines `__ARM_ARCH_8_1M_MAIN__`.

### C and C++ language extensions

ST Arm Clang supports the majority of GNU C and C++ extensions as described in Clang Language Extensions.

The following feature checking macros can be used to test whether a particular feature is supported:

> - __has_builtin

> - __has_feature

> - __has_extension

> - __has_attribute

### Assembly language

`starm-clang` should be used instead of `arm-none-eabi-as` to compile assembly ( `.s` and `.S`) files.

There are minor differences in the assembly syntax between GNU and LLVM compilers. However, most of the time, it is possible to write code that both accept.

For example, GNU and LLVM compilers differ in:

> - The use of `.N` and `.W` suffixes for Thumb instructions.

> - The use of `S` suffix for flag setting instructions.

### Optimization flags

For better code size optimization, consider using `-Oz` or `--config=Osize.cfg` instead of `-Os`.

Note: In previous ST Arm Clang releases, `Osize.cfg` was named `Omin.cfg`.

## Focus on C standard formatted I/O

Functions of the `printf` and `scanf` families can account for a significant portion of an embedded application’s code size. This is primarily due to the expensive logic required to support the formatting of `long long`, `float`, and `double` types, even though these formats are not always used.

To reduce the cost associated with these functions, some configurations of ST Arm Clang provide mechanisms to select reduced versions of `printf` and `scanf` that only support formats used in your application.

### Hybrid toolchain

#### Newlib

This library provides a single implementation of the `printf` and `scanf` functions. It supports all formats but the code size of these functions is maximal.

#### Newlib nano

This library provides two implementations of the `printf` and `scanf` functions: (1) the default one only supports formatting of characters, strings, pointers, and integer types up to 32 bits (2) the other one adds support for floating-point types. Specify `-u _printf_float` or `-u _scanf_float` linker flags to select the second version. Note that neither version supports the formatting of 64-bit wide integers, contrary to the single implementation in Newlib.

### Full LLVM toolchain

#### Newlib

This library provides a single implementation of the `printf` and `scanf` functions. It supports all formats but the code size of these functions is maximal. Note that this library is compiled for optimal execution speed rather than lowest code size.

#### Picolibc

This library offers five implementations of the `printf` and `scanf` functions. Read the Picolibc documentation for details on the formats supported by each version. If the format strings can be analyzed at compile time, the ST Arm Clang toolchain will automatically link the minimal version of `printf` and `scanf` functions that supports all the formats used by your application. This mechanism can be disabled using `--no-auto-printf-variant-selection` or `--no-auto-scanf-variant-selection` linker flags, allowing the selection of a specific version.

NOTE: When optimizations are disabled ( `-O0`), the `--gc-sections` linker flag is needed to remove unused `printf` and `scanf` versions from the final binary. This flag is already set in CMake projects generated by STM32CubeMX.

## Thread local storage

ST Arm Clang with Picolibc supports thread local storage (TLS).

You can declare a thread-local variable in your code by using the `__thread` specifier or the `_Thread_local` keyword (or `thread_local` in C++). Such variables are manipulated like any regular (non-thread-local) variable in the source code. The toolchain automatically insert the necessary code to ensure each thread accesses its own copy. Picolibc itself uses TLS for thread-specific library data, such as errno , I/O buffers, and other internal states.

For STM32Cube CMake projects generated for ST Arm Clang, all necessary TLS setup for the first thread is included by default. The linker script and startup code are configured according to the Thread Local Storage in Picolibc documentation, with one exception: instead of calling `_set_tls(__tls_base)` directly in the startup code to set the TLS pointer for the first thread, a `.preinit_array` section references `_initial_set_tls()`, which serves the same purpose. This section and the function are only linked in the application if TLS data is used, in which case the function is automatically called by `__libc_init_array()` in the startup code.

As a result, TLS works out of the box for single-threaded STM32Cube CMake projects. For multi-threaded projects, refer to the Creating more TLS blocks section of the aforementioned Picolibc documentation to initialize TLS for subsequent threads.

Note: TLS for the first thread is only guaranteed to be initialized after `__libc_init_array()` has executed all functions registered in the `.preinit_array` section. Therefore, it is safe to use TLS data after `__libc_init_array()`, or in functions registered in the .init_array section.

## Components

ST Arm Clang toolchain relies on the following upstream components

Component | Link | Version
--- | --- | ---
LLVM | https://github.com/llvm/llvm-project | 21.1.1
Picolibc | https://github.com/picolibc/picolibc | 1.8.10
Newlib | https://sourceware.org/newlib/ | 4.5.0

## Host platforms

ST Arm Clang toolchain is built and tested on:

> - RHEL 8 x86_64

> - MacOS 15.5 Apple Silicon and X86_64

> - Windows 10 x86_64

## External documentation resources

- Clang user’s manual

- LLVM linker: LLD

- libc++ C++ standard library

- Picolibc

- Newlib