STM32Cube*
STM32CubeMX and STM32CubeCLT allow the user to write, compile, and flash code to the STM32 microcontroller! STM32CubeCLT contains the GCC compiler and GDB debugging tool for firmware compilation and debugging, and STM32CubeMX contains the interface for configuring the microcontroller and project environment, and provides a very powerful interface for automatic code generation, allowing the user to initialize an entire module with a few clicks of a button, and have that code show up automatically in the main file.
Downloading and Installing the Cube Tools (Linux)
Section titled “Downloading and Installing the Cube Tools (Linux)”On Ubuntu/Debian, the whole toolchain (CubeMX, CubeProgrammer, CubeCLT, the ARM GNU toolchain,
uv, and everything else scripts/build.sh needs) is set up by one script, run once from the
repo root:
./scripts/bootstrap.shThis installs ansible (if it isn’t already present) and runs the
ansible/bootstrap.yml playbook, which installs system packages, the ARM GNU toolchain, uv, the
cube tools, initializes git submodules, writes your PATH and application launcher entries, and
sets up the python virtual environment at tools/.venv.
The cube tools can’t be downloaded automatically as ST gates all of them behind a login (a free
MyST account; you may use any email address) with no stable download URL. Partway through,
./scripts/bootstrap.sh will pause and ask you to:
-
Go to the CubeMX download page, select the Linux installer, and download it into
install/at the repo root.
-
Go to the CubeProgrammer download page, select the Linux installer, and download it into
install/as well. -
Go to the CubeCLT download page, select the Debian Linux installer, and download it into
install/as well.
-
Optionally, if you want a graphical debugger other than VS Code, go to the CubeIDE download page, select the Debian Linux installer, and download it into
install/too. It is a ~3 GB download and is skipped when absent, since nothing in the build flow needs it. -
Press
Enterin the terminal runningbootstrap.shto continue.
The script then unpacks and installs each archive it finds. CubeMX and CubeProgrammer use graphical installers
with no silent-install flag, so two installer windows will open. Click through both, accepting
the default install location (/usr/local/STMicroelectronics/STM32Cube/...). CubeCLT and CubeIDE install
without prompting, but you may see a system prompt related to licensing depending on your OS.
Afterwards, the script adds the tools to your PATH via /etc/profile.d/mrover-esw.sh. Open a new
terminal to pick it up. The script also writes launcher entries for STM32CubeMX and STM32CubeProgrammer into
~/.local/share/applications, so they show up in your applications menu (STM32CubeIDE installs
its own launcher entry system-wide).
The ARM cross-compiler comes from CubeCLT itself; a standalone copy is installed as a fallback but
is ordered after CubeCLT on PATH, so CubeCLT’s is the one you get. CubeCLT also ships
STM32_Programmer_CLI, which is the copy on your PATH; the standalone CubeProgrammer is the GUI
you launch from the applications menu when you want to flash or inspect a board interactively.
Verifying the Install
Section titled “Verifying the Install”Open a new terminal and run:
./scripts/doctor.sh --buildThis reports the version and location of every required tool, confirms arm-none-eabi-gcc is
coming from CubeCLT, and then builds a small firmware project end to end. If it finishes with
all checks passed, your environment is ready. See Build Tools
for what each check means.
If bootstrap fails partway through, it’s safe to re-run ./scripts/bootstrap.sh. Every step
skips itself if it’s already done, including the two graphical installers.
Upgrading, and Installing Over an Existing Setup
Section titled “Upgrading, and Installing Over an Existing Setup”Bootstrap is safe to run on a machine that already has the cube tools installed by hand. It never
removes an existing install; it installs over it and takes ownership of PATH and the launcher
entries.
To upgrade a cube tool, download the newer installer into install/ and re-run
./scripts/bootstrap.sh. Each installer is gated on a stamp file named after the installer itself,
not after the directory it installs into, so a new archive always runs and an unchanged one never
re-runs. Delete the matching install/.installed-* file to force a reinstall.
To redo just one step, for example the PATH setup after a CubeCLT upgrade, run the following:
ansible-playbook ansible/bootstrap.yml --connection=local --ask-become-pass --tags path-profileValid tags are packages, clang-format, uv, arm-toolchain, submodules, stm,
path-profile, desktop-entries, python-venv and vscode.
Debugging with STM32CubeIDE
Section titled “Debugging with STM32CubeIDE”CubeIDE is installed as a debugger only, it does not build anything. The build stays
with scripts/build.sh and CMake; CubeIDE attaches to the .elf that build produced. That split
is what keeps the terminal build and CI as the build mechanism, while still giving you breakpoints,
watch expressions, a call stack, live registers and the peripheral (SFR) view.
If you skipped CubeIDE during bootstrap, drop its archive into install/ and re-run
./scripts/bootstrap.sh (see install/README.md).
1. Build the Firmware First
Section titled “1. Build the Firmware First”CubeIDE will not build for you, so produce the ELF in a terminal:
./scripts/build.sh --src src/bmc --preset DebugUse the Debug preset. Release is optimized, so breakpoints land in surprising places and half
your locals read <optimized out>. The ELF lands at a predictable path:
<src>/build/<preset>/<target>.elf e.g. src/bmc/build/Debug/bmc.elf2. Create a Workspace
Section titled “2. Create a Workspace”Launch STM32CubeIDE from your applications menu. When it asks for a workspace directory, pick
somewhere outside the repository (~/cubeide-workspace is fine). CubeIDE writes a large
.metadata/ tree into its workspace, and you do not want that inside a git checkout.
3. Import the Project
Section titled “3. Import the Project”File -> Import... -> C/C++ -> Existing Code as Makefile Project -> Next.
- Existing Code Location: the project directory, e.g.
src/bmc - Toolchain for Indexer Settings: STM32 Cortex-M GCC
- Leave “C” and “C++” both ticked, then
Finish.
This does not set up a build - it just gives CubeIDE the source tree so it can map addresses back
to your files and let you set breakpoints. Turn off Project -> Build Automatically so the IDE
never tries.
4. Create the Debug Configuration
Section titled “4. Create the Debug Configuration”Run -> Debug Configurations... -> select STM32 C/C++ Application -> New Configuration.
On the Main tab:
- Project: the project you just imported
- C/C++ Application: the ELF from step 1, e.g.
src/bmc/build/Debug/bmc.elf - Under Build (if required) before launching, choose Disable auto build, otherwise CubeIDE tries to build a project that has no build configured and refuses to launch.
On the Debugger tab:
-
Debug probe: ST-LINK (ST-LINK GDB server)
-
Interface: SWD
-
Reset behavior: Connect under reset, the reliable choice if the firmware reconfigures clocks or pins early in
main. -
SFRs / Device: point the SVD at the file for your MCU so the peripheral view is populated. For the STM32G431 boards used here:
/opt/st/stm32cubeclt_<version>/STMicroelectronics_CMSIS_SVD/STM32G431.svd./scripts/doctor.shprints the CubeCLT version in use if you are unsure which directory that is.
Apply, then Debug.
5. The Edit-Build-Debug Loop (With CubeIDE)
Section titled “5. The Edit-Build-Debug Loop (With CubeIDE)”- Edit code in your normal editor.
./scripts/build.sh --src <project-path> --preset Debugin a terminal.- Back in CubeIDE, hit
Debugagain. It reloads the ELF from disk and re-flashes.
You do not need to re-import or re-create the configuration; only step 2 changes anything.
Debugging Without CubeIDE
Section titled “Debugging Without CubeIDE”CubeIDE is not the only option, and nothing here depends on it. CubeCLT ships
ST-LINK_gdbserver and arm-none-eabi-gdb, which any GDB front end can drive. The
Cortex-Debug extension
for VS Code and CLion’s embedded GDB server configuration both work against the same ELF, and
./scripts/doctor.sh already verifies the gdbserver is present and on PATH.
./scripts/bootstrap.sh supports macOS as well as Ubuntu/Debian. It uses Homebrew instead of
apt, and Homebrew is the one prerequisite it cannot install for you, get it from
brew.sh first, then run the same command as Linux users:
./scripts/bootstrap.shThe flow is identical: it installs ansible (via brew), the build tools, uv, the ARM toolchain
and the cube tools, then writes your PATH and syncs tools/.venv. Download the same archives
into install/, picking the macOS build on each ST download page rather than the Linux one.
Two things differ under the hood:
PATHsetup. macOS has no/etc/profile.d, so the snippet is written to/etc/mrover-esw.shand sourced from both/etc/zshenvand/etc/profile. As on Linux, opening a new terminal is enough; you do not need to log out.- Application shortcuts.
.desktopfiles are an XDG concept and are skipped. ST’s macOS installers register their own.appbundles, so CubeMX, CubeProgrammer and CubeIDE appear in Launchpad on their own.
ST packages its macOS tools inconsistently: each download may arrive as a .zip, a .tar.gz, a
.tar.gz wrapped in a .zip, or a .dmg wrapped in a .zip. Bootstrap takes whatever the
download page gives you, so do not unpack or convert anything first. It unpacks one level of
nesting, then installs by what it finds rather than by filename:
.pkg: installed non-interactively withinstaller..app: opened withopen -W, so a window appears for you to click through, exactly like the Linux CubeMX and CubeProgrammer installers..dmg: mounted withhdiutil, and the.pkginside is installed or the.appinside is copied to/Applications. The image is unmounted again whether or not the install succeeded. CubeIDE is normally the one that arrives this way.
Verifying the Install on macOS
Section titled “Verifying the Install on macOS”Open a new terminal and run:
./scripts/doctor.sh --buildThe checks are PATH-based and work the same on macOS; it knows ST’s macOS install roots
(/opt/ST, /Applications/STMicroelectronics). The .desktop and /etc/profile.d checks are
Linux-only and are skipped rather than reported as problems.
Creating a New Project
Section titled “Creating a New Project”This quick guide will teach you how to make a new project for your STM32G431RB Nucleo board that you will be developing on.
Prerequisites
Section titled “Prerequisites”- STM32CubeMX and STM32CubeCLT installed
To create a new project, use the scripts/new.sh script. The script accepts either an MCU or Development Board ID, project source, and optionally any number of cmake libraries defined under lib. To create a project for the Nucleo G431RB developer kit, run the following.
./scripts/new.sh --board NUCLEO-G431RB --src <path/to/project>When prompted to select default peripheral configurations, select “Unselect All” and “continue”.

If this is the first time STM32CubeMX is being run on a machine, it may need to download the firmware repository. Select “Download” and continue.
Once the script completes, try to build the generated project as follows.
./scripts/build.sh --src <path/to/project>If this completes successfully, then STM32CubeCLT is correctly installed on the system.
Open the <project>.ioc file in STM32CubeMX to modify the project configuration.
Congratulations! You have successfully created a new project with CubeMX!
For how the CMake build actually works (the toolchain file, the presets, and the generated libraries) see the Build System reference.