LLVM Toolchain Guide#
This guide shows how to install, enable, and build Silicon Labs Platform projects with the Low Level Virtual Machine (LLVM) Arm Toolchain for Embedded.
What This Guide Covers#
Install the LLVM toolchain and required build tools
Configure your environment
Enable LLVM in a project
Build with CMake
Troubleshoot common setup and build issues
Requirements#
You will typically need:
Tool | Why you need it |
|---|---|
Simplicity Studio / SLC | Generate project files with LLVM support |
SLT ( | Install the LLVM toolchain and utilities |
CMake | Configure the generated CMake project |
Ninja | Build the generated CMake project |
Simplicity Commander | Flash and debug the built image |
Supported Targets#
Cortex-M based Silicon Labs Platform devices
C projects
C++ projects with
cpp_support
Install the Toolchain#
1. Check that SLT is available#
slt --version
slt update --selfIf slt is not installed, follow the official installation guide:
2. Install Conan#
slt install conan3. Install the LLVM embedded toolchain#
Recommended:
slt install llvm-arm-toolchain-for-embeddedor
slt install llvm-arm-toolchain-for-embedded -e conan4. Install build tools#
Install CMake and Ninja:
slt install cmake
slt install ninjaAdditionally, you can install CMake from https://cmake.org/download/ and Ninja from https://ninja-build.org/.
5. Manual installation option#
If you are not using SLT to install LLVM, download the Arm Toolchain for Embedded directly from the Arm release page and extract it to your preferred location:
https://github.com/arm/arm-toolchain/releases
If you install the toolchain manually, make sure ARM_LLVM_DIR points to the toolchain root directory that contains the bin directory. Additionally, install newlib-nano-overlay and extract it into the toolchain directory.
Configure Your Environment#
Get installed slc-cli path:
slt where slc-cliIf you haven't had slc yet:
slt install slc-cliAdd environment variables#
The slc tool uses the following variables to generate and build the project:
Variable | Explanation |
|---|---|
| Stores the install directory of |
| Adds the tool directories so commands like |
| Points to the root directory of the ARM LLVM toolchain. |
| Points specifically to the LLVM |
| Path to |
The generated toolchain.cmake needs to find the LLVM tools. The easiest and most reliable method is to set ARM_LLVM_DIR. ARM_LLVM_DIR must point to the toolchain root.
Windows (PowerShell)#
$slcDir = (slt where slc-cli)
[Environment]::SetEnvironmentVariable("PATH", "$slcDir;" + [Environment]::GetEnvironmentVariable("PATH", "User"), "User")
$llvmDir = (slt where llvm-arm-toolchain-for-embedded)
[Environment]::SetEnvironmentVariable("ARM_LLVM_DIR", $llvmDir, "User")
[Environment]::SetEnvironmentVariable("SLED_TOOL_LLVM_ARM_PATH", "$llvmDir\bin\", "User")
[Environment]::SetEnvironmentVariable("PATH", "$llvmDir\bin;" + [Environment]::GetEnvironmentVariable("PATH", "User"), "User")Make sure Ninja is also available on PATH:
$ninjaDir = (slt where ninja)
[Environment]::SetEnvironmentVariable("PATH", "$ninjaDir;" + [Environment]::GetEnvironmentVariable("PATH", "User"), "User")
[Environment]::SetEnvironmentVariable("NINJA_EXE_PATH", "$ninjaDir\ninja.exe", "User")After saving environment variables, restart your terminal or Simplicity Studio.
Linux/macOS#
After installing llvm-arm-toolchain-for-embedded, make sure clang is available in your shell environment by adding the toolchain's bin directory to your PATH, as shown below. In most cases, you do not need to build Clang from source.
If clang is still not available after installation, refer to the official Clang getting started guide for additional setup information: https://clang.llvm.org/get_started.html
To apply these settings automatically whenever you open a shell, add them to your shell startup file, such as ~/.bashrc or ~/.zshrc:
export SLC_CLI_DIR="$(slt where slc-cli)"
export PATH="$SLC_CLI_DIR:$PATH"
export ARM_LLVM_DIR="$(slt where llvm-arm-toolchain-for-embedded)"
export SLED_TOOL_LLVM_ARM_PATH="${ARM_LLVM_DIR}/bin/"
export PATH="$ARM_LLVM_DIR/bin:$PATH"Verify the Installation#
Verify that the tools are available:
clang --version
ninja --versionIf clang is not found, verify that ARM_LLVM_DIR is correct and that bin is on your PATH.
Enable LLVM in Your Project#
Option 1: Simplicity Studio#
Create or open your project.
Make sure the project uses CMake as the target IDE/export type.
Open the
.slcpfile.In Software Components, go to Platform -> Toolchain.
Remove the default GNU toolchain component if it is present.
Install
toolchain_llvm.Optional: also install
toolchain_ltoif you want link-time optimization.Generate or export the project.
Open the generated CLI CMake project.
Build from the
cmake_llvmdirectory.
Example:
cmake --workflow --preset projectOption 2: SLC command line#
Generate a CMake export with LLVM:
slc generate -p my_app.slcp -d ./app_dir --toolchain llvm --output-type=cmake --with brd4194aBuild the Project#
Recommended: one command workflow#
From the cmake_llvm directory:
cmake --workflow --preset projectOutput files#
After a successful build, you will usually see:
.out- main linked output for debugging.hexor.s37- image files for flashing.map- linker map file for memory and size inspection
Typical layout:
cmake_llvm/
CMakeLists.txt
CMakePresets.json
toolchain.cmake
<project>.cmake
build/
base/
<app>.out
<app>.hex
<app>.s37
<app>.map
CMakeFiles/
.ninja_deps
.ninja_log
build.ninja
build-base.ninja
cmake_install.cmake
CMakeCache.txtFlash and Debug#
Once the image has been built, you can flash it the same way you would flash a GCC-built image.
Example:
commander flash cmake_llvm/build/base/my_app.s37 --device <part>For debugging, use Simplicity Studio Launcher with VSCode extension.
Optional: Enable LTO#
To use link-time optimization with LLVM:
Add
toolchain_ltoto the project in addition totoolchain_llvmRegenerate the project
Rebuild from a clean
builddirectory
Use LTO only after your normal LLVM build is already working. Some stacks or third-party libraries may need extra validation when LTO is enabled.
Code Size and RAM Comparison#
The following table shows reference build results for a few sample applications.
Important notes:
Results may be different with newer LLVM releases, newer SDK versions, different libraries, or different project settings
Flash and RAM impact can vary depending on optimization level, LTO usage, stack configuration, and application features
Application | GCC | LLVM/nanolib | Diff vs GCC | LLVM/nanolib LTO | Diff vs LLVM | Diff vs GCC | GCC LTO | LLVM LTO vs GCC LTO |
|---|---|---|---|---|---|---|---|---|
| Flash: 15896 / RAM: 4580 | Flash: 15200 / RAM: 4548 | Flash: -4% / RAM: -1% | Flash: 8088 / RAM: 4168 | Flash: -47% / RAM: -8% | Flash: -49% / RAM: -9% | Flash: 8920 / RAM: 4576 | Flash: -9% / RAM: -9% |
| Flash: 22452 / RAM: 8808 | Flash: 21304 / RAM: 8776 | Flash: -5% / RAM: 0% | Flash: 12028 / RAM: 8392 | Flash: -44% / RAM: -4% | Flash: -46% / RAM: -5% | Flash: 13364 / RAM: 8800 | Flash: -10% / RAM: -5% |
| Flash: 393240 / RAM: 26876 | Flash: 385028 / RAM: 27008 | Flash: -2% / RAM: 0% | Flash: 355484 / RAM: 26448 | Flash: -8% / RAM: -2% | Flash: -10% / RAM: -2% | Flash: 360364 / RAM: 26476 | Flash: -1% / RAM: 0% |
| Flash: 159120 / RAM: 20624 | Flash: 156084 / RAM: 20580 | Flash: -2% / RAM: 0% | Flash: 130228 / RAM: 19816 | Flash: -17% / RAM: -4% | Flash: -18% / RAM: -4% | Flash: 151676 / RAM: 20392 | Flash: -14% / RAM: -3% |
| Flash: 506044 / RAM: 51280 | Flash: 504816 / RAM: 51332 | Flash: 0% / RAM: 0% | Flash: 470208 / RAM: 51072 | Flash: -7% / RAM: -1% | Flash: -7% / RAM: 0% | Flash: 461716 / RAM: 50904 | Flash: 2% / RAM: 0% |
| Flash: 949972 / RAM: 173516 | Flash: 952388 / RAM: 173220 | Flash: 0% / RAM: 0% | Flash: 882148 / RAM: 172312 | Flash: -7% / RAM: -1% | Flash: -7% / RAM: -1% | Flash: 869396 / RAM: 173196 | Flash: 1% / RAM: -1% |
Common Notes#
C++ projects#
If your project uses cpp_support, LLVM links against libc++ instead of libstdc++.
Automatically added dependencies#
When you enable toolchain_llvm, required support components such as memory layout support and syscall stubs are normally added automatically. In most projects, you do not need to add them manually.
In application code#
If you need to detect LLVM-specific behavior in source code:
#if defined(SLI_BUILT_WITH_LLVM)
/* LLVM-specific path */
#else
/* GCC or generic path */
#endifTroubleshooting#
Error: Not using LLVM-compatible makefile template#
This usually means your export templates do not support LLVM yet.
Try one of these fixes:
Update Simplicity Studio and SLT
Confirm you are exporting with
--output-type=cmakeUse an LLVM-capable export template directory with
--export-templates
Example:
slc generate my_app.slcp \
-d ./cmake_llvm \
--toolchain=toolchain_llvm \
--output-type=cmake \
--export-templates=/path/to/llvm-compatible/templatesslt where ... does not return a toolchain path#
If slt where llvm-arm-toolchain-for-embedded fails:
install the LLVM toolchain with SLT, or
set
ARM_LLVM_DIRmanually to the directory that contains thebinfolder
cmake --workflow fails#
Your CMake version may be too old.
Use:
cmake --preset project
cmake --build --preset default_configor install CMake 3.25+.
Link errors such as _sbrk, _write, or _read#
This usually indicates missing or mismatched syscall support.
Make sure your project still includes the required syscall stubs and do not remove the default nosys / startup configuration unless you are replacing it intentionally.
Clang warnings are treated as errors#
LLVM may report warnings differently than GCC. Fix the warnings or update the project compile options to match your team's policy.
Reference#
Useful related files in the Platform (gsdk) repository:
Path | Description |
|---|---|
| LLVM toolchain component definition |
| LLVM LTO component |
| Syscall support for LLVM/newlib |
| Linker template area used by LLVM-aware exports |