# ObKo/stm32-cmake for STM32 GCC and CMake Builds

> ObKo/stm32-cmake supplies CMake tooling for STM32 applications built with GCC, including CMSIS discovery, device metadata, linker support, examples, and tests. It is useful for developers maintaining repeatable embedded builds across supported STM32 families, although STM32Cube and an ARM toolchain remain external requirements.

**ObKo/stm32-cmake** — CMake for stm32 developing.

- Repository: https://github.com/ObKo/stm32-cmake
- Stars: 1,377 · Forks: 357
- Language: C
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/obko-stm32-cmake

## What ObKo/stm32-cmake Removes from an STM32 Build

ObKo/stm32-cmake targets developers building applications for ST's ARM Cortex-Mx STM32 microcontrollers with CMake and GCC. The project does not provide the microcontroller runtime itself. Instead, it supplies the build-system layer: an ARM toolchain file, device information, CMSIS discovery, optional STM32 HAL discovery, linker-script generation, library support, examples, and tests.

That division matters because STM32 builds require several pieces that a normal host C project does not resolve automatically. A target needs a cross compiler, startup code, peripheral headers, device-specific compile definitions, and a memory layout describing flash and RAM. It may also need STM32Cube libraries, CMSIS, FreeRTOS, or another supported dependency. The README says this repository can identify, for example, an STM32F407VG as an F4 device with 1 MB of flash, 128 KB of RAM, and CMSIS device type F407xx.

The intended audience is therefore engineers who want their embedded application described in CMake rather than through a vendor IDE's generated project metadata. The repository supports the C0, F0, F1, F2, F3, F4, F7, G0, G4, H7, L0, L1, L4, L5, U0, U5, WB, and WL device families. It also describes C++ use in the blinky example, although the primary language is C.

This is not a complete embedded development environment. The documented requirements include CMake 3.16 or later, a GCC toolchain with newlib where needed, and an STM32Cube package appropriate to the selected STM32 family. Keeping those inputs separate makes the project reusable, but it also leaves hardware preparation and dependency compatibility to the adopter.

## Toolchain, Device Metadata, and Imported CMSIS Targets

The core mechanism is CMake's imported-target model. Based on the repository layout, `cmake/stm32_gcc.cmake` configures CMake to use an ARM GCC toolchain. Family-specific modules then describe memory sizes, CPU types, device types, and device naming. `cmake/FindCMSIS.cmake` finds CMSIS, while `cmake/FindHAL.cmake` handles the STM32 HAL library. There is also `cmake/stm32/linker_ld.cmake` for generating a tunable linker script.

A typical project first locates CMSIS for a device or family. The README gives this pattern:

```cmake
find_package(CMSIS [CMSIS_version] COMPONENTS STM32F4 REQUIRED)
```

The component may identify a family such as `STM32F4` or a specific device such as `STM32F407VG`. Omitting `COMPONENTS` tells the package to search across all supported families and chips, but the README warns that every corresponding STM32Cube package must then be available somewhere on the system.

The selected CMSIS package becomes targets such as `CMSIS::STM32::F4`, while a device-specific target is named `CMSIS::STM32::F407VG`. These are not merely labels. According to the README, each target carries its own headers, sources, compiler definitions, flags, and dependencies. Linking the application target propagates the relevant CMSIS component to that executable.

CMSIS contributes family headers, the peripheral access layer, device startup sources, and device-specific linker information. This target-based design keeps the application relationship explicit. It also exposes a practical limitation: a successful configuration depends on correct family metadata and correctly located vendor sources. Multi-core naming is stricter than the commercial part name suggests. Devices with two cores may need a name that includes the core, such as `STM32H7_M7` or `STM32H7_M4`, and STM32WB is identified as multi-core even when the second core is not accessible to the end user.

## Configuring STM32Cube and the GCC Toolchain

Before configuration, a developer must tell CMake where the appropriate STM32Cube package and toolchain are located. The required setting is `STM32_CUBE_<FAMILY>_PATH`, whose default is `/opt/STM32Cube<FAMILY>`. The `<FAMILY>` portion is replaced with a supported family identifier such as `F4` or `H7`.

The optional `STM32_TOOLCHAIN_PATH` defaults to `/usr`. If the toolchain directory is already on the system path, that can avoid a separate setting, but an explicit `STM32_TOOLCHAIN_PATH` takes precedence. The target triplet defaults to `arm-none-eabi` and can be changed through `STM32_TARGET_TRIPLET`.

The README describes three ways to supply these variables: pass them with `-D<VAR_NAME>=...`, set them in `CMakeLists.txt`, or provide them as environment variables. On a Unix-like shell, it gives the following helper-script pattern:

```sh
export STM32_TOOLCHAIN_PATH="<ToolchainPath>"
export STM32_TARGET_TRIPLET=arm-none-eabi
export STM32_CUBE_<FAMILY>_PATH="<PathToCubeRoot>"
```

After saving that as `path_helper.sh`, `. path_helper.sh` loads it into the current shell. On Windows PowerShell, the documented equivalents assign the same variables to the process environment:

```sh
$env:STM32_TOOLCHAIN_PATH = "<ToolchainPath>"
$env:STM32_TARGET_TRIPLET = arm-none-eabi
$env:STM32_CUBE_<FAMILY>_PATH="<PathToCubeRoot>"
```

These examples configure paths only. They do not install GCC, CMake, newlib, or STM32Cube. The README points users to those components as requirements and provides no package-manager installation procedure.

## A First Application with the Template Example

The repository includes an empty application template under `examples/template`. Its purpose is to provide an application target linked with CMSIS, rather than to demonstrate board-specific runtime behavior. A developer can use it as the starting point for a real firmware image after preparing CMake, GCC, newlib if required, and the matching STM32Cube package.

The core project definition documented by the README consists of finding CMSIS and creating an executable. For an F407VG target, the target declaration is:

```cmake
add_executable(stm32-template main.c)
target_link_libraries(stm32-template CMSIS::STM32::F407VG)
```

This executable name is an example from the README. The target link supplies the device-specific CMSIS dependency, which in turn carries include directories, peripheral layer files, startup source, linker information, and compiler flags as described by the project.

The first configuration should identify one exact MCU wherever possible. Family-wide discovery is useful for a matrix build, but the README states that it causes CMSIS to search all families and chips and therefore requires all relevant Cube packages. An exact device target narrows the relationship between the application and the selected STM32 part.

For projects needing a different linker script, `examples/custom-linker-script` offers the alternative route. For dependency acquisition, `examples/fetch-cube` shows FetchContent use for STM32Cube, while `examples/fetch-cmsis-hal` demonstrates fetching CMSIS and HAL from ST's Git repositories. Those examples address dependency sourcing, but the documentation still treats an appropriate STM32Cube package and GCC toolchain as project inputs.

## Blinky, FreeRTOS, and Supported Build Variants

The blinky example is the clearest functional example in the repository. It builds an STM32 HAL and SysTick application, defaults to the F4 family, and can select L0 or F1 through CMake generation options. The README names the options exactly as `BLINKY_L0_EXAMPLE=ON` and `BLINKY_F1_EXAMPLE=ON`. A C++ source file can be selected with `USE_CPP_FILE=ON`.

The FreeRTOS example requires at least one board option in the form `FREERTOS_<BOARD>_EXAMPLE=ON`. Only the `H743ZI` and `F407VG` board targets are listed. It can use the Cube repository's CMSIS RTOS implementation through either `USE_CMSIS_RTOS=ON` or `USE_CMSIS_RTOS_V2`. If a direct FreeRTOS kernel is used rather than CMSIS, `FREERTOS_PATH` points to that kernel. These distinctions matter because the names refer to different integration paths and should not be treated as interchangeable switches.

The examples reduce initial setup, but they do not remove target-specific decisions. Board selection, MCU core selection, family-specific Cube paths, startup source, and memory configuration still matter. A project that changes the MCU must also confirm that the chosen CMSIS device target exists and that the generated linker information matches the part.

ObKo/stm32-cmake is designed for a CMake-defined dependency graph, so adopting it means accepting responsibility for cross-compilation paths and imported targets. It is also a poor fit if no matching STM32Cube package is available, because the project does not manufacture that vendor package.

## Testing, Maintenance, and MIT Upgrade Considerations

The repository includes a `tests` area described as projects that check whether the CMake scripts work. A GitHub Actions workflow is represented by the Tests badge in the README. These facts indicate that the build scripts are intended to receive automated checking, but the README does not describe the exact test matrix, hardware coverage, or flashing procedure. It would be unjustified to infer those details from the presence of tests alone.

The repository is not archived, and its last push was on 2026-07-25. That supports a recent maintenance signal, although the release list in the repository documentation contains `v2.1.0` and `v2.0`, both dated 2021-08-09. The gap matters when selecting an upgrade source. Recent commits do not guarantee that the latest tagged release includes every current example or module, and the README does not document a compatibility matrix between the `master` branch and those releases.

The project uses the MIT License. That is the license identifier recorded for the repository. Its practical effect for an organization still depends on how the code is distributed and combined with STM32Cube, CMSIS, FreeRTOS, GCC, and other separately supplied components. The README does not state the licenses of all dependencies, so it cannot support a complete compliance review.

Before upgrading, compare the selected tag or branch with the application's `CMakeLists.txt`, inspect changes to family metadata, and verify that device targets still resolve. That is especially important when changing MCU families or crossing from a single-core target to a named core such as `STM32H7_M7`.

## Conclusion

Adopt ObKo/stm32-cmake when a project needs repeatable STM32 GCC builds across chips and already has the matching STM32Cube package. Do not choose it for an unsupported device family. Verify first that the repository supplies the exact family and device metadata, CMSIS and HAL paths, linker configuration, and GCC installation that your target requires. Its repository received a push on 2026-07-25, while the listed v2.1.0 and v2.0 releases date from 2021-08-09, so check compatibility between current examples and the version you adopt.

## FAQ

### What does ObKo/stm32-cmake provide for STM32 development?

It provides CMake configuration for GCC-based STM32 applications, including a toolchain file, family and device metadata, CMSIS and HAL discovery, linker support, examples, and tests. It does not replace STM32Cube or the GCC toolchain.

### What requirements does ObKo/stm32-cmake have?

The README requires CMake 3.16 or later, a GCC toolchain with newlib where needed, and an STM32Cube package appropriate to the selected STM32 family.

### How do I select an STM32 device in ObKo/stm32-cmake?

Pass a family or specific device through the CMSIS `COMPONENTS` setting, then link the application to the corresponding device target. For example, the README links an executable to `CMSIS::STM32::F407VG`; multi-core devices may require the core in the target name.

## Sources

- [Issues](https://github.com/ObKo/stm32-cmake/issues)
- [License: MIT](https://github.com/ObKo/stm32-cmake/blob/master/LICENSE)
- [ObKo/stm32-cmake on GitHub](https://github.com/ObKo/stm32-cmake)
- [README](https://github.com/ObKo/stm32-cmake/blob/master/README.md)
- [Releases](https://github.com/ObKo/stm32-cmake/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/obko-stm32-cmake
