`esw.cubemx`
Drives STM32CubeMX headlessly and renders the CMake files for a generated project. This is what
scripts/new.sh is built on.
esw.cubemx
Section titled “esw.cubemx”get_installation()run_cubemx_script(script_content: str, return_output_on_failure: bool = False)get_installation resolves STM32CubeMX on PATH, raising RuntimeError if absent. Cached.
run_cubemx_script writes a script to a temporary file and runs STM32CubeMX -q <file>. CubeMX
reports failure by printing KO rather than by exit code, so both are checked. Returns a bool, or
(bool, output) when return_output_on_failure is set.
esw.cubemx.generation
Section titled “esw.cubemx.generation”generate_project(name: str, path: Path, mcu: str) -> NoneCreates a CubeMX project in two passes.
The first pass generates the project with a CMake toolchain and GCC:
load STM32G431CBTx # or: loadboard NUCLEO-G431RB nomodeproject name <name>project path <path>project toolchain CMakeproject compiler GCCSetCopyLibrary copy as referenceproject generateexitA target starting with STM32 is loaded as an MCU; anything else (NUCLEO-*, DISCO-*) is
loaded as a board.
The second pass patches the generated .ioc, replacing LibraryCopy=0 with LibraryCopy=2
(“copy as reference”), deletes the vendored Drivers/ directory, and regenerates. That is what
stops CubeMX from copying a private copy of the HAL into every project. This repo builds the HAL
once from the STM32CubeG4 submodule instead.
esw.cubemx.cmake
Section titled “esw.cubemx.cmake”configure_cmake(name: str, path: Path, root: Path, ctx: Path, libs: list[str]) -> Noneconfigure_clang(path: Path, ctx: Path) -> Noneconfigure_cmake
Section titled “configure_cmake”Deletes and re-renders a project’s build files. In order:
- Removes
.clangd,CMakeLists.txt,CMakePresets.jsonandcmake/stm32cubemx/CMakeLists.txt. - Discovers the source directory (
Src/orCore/Src/), the include directory (Inc/orCore/Inc/), and the startup assembly file. Exactly one*.smust exist at the project root, otherwise it raises. - Computes the relative path from the project to
lib/, which is what makesadd_subdirectory(../../lib fwlib)come out right at any nesting depth. - Renders three templates from
ctx(alwayslib/stm32g4):CMakeLists.txt.j2,CMakePresets.json.j2and.clangd.j2.
The toolchain files under cmake/ are not touched; they come from CubeMX and stay as they are.
configure_clang
Section titled “configure_clang”Renders .clangd only, and no-ops if the file already exists. scripts/build.sh calls this on
every build so a fresh checkout gets a working clangd configuration without a separate step.
It locates the newest CubeCLT install by globbing /opt/st/stm32cubeclt_* and picking by
modification time rather than by name, because name sorting puts 1.9.0 above 1.20.0. It needs
three include paths and warns if it cannot find all three.
Normally through the wrapper:
./scripts/new.sh --board NUCLEO-G431RB --src src/example --lib stm32 --lib dbcDirectly, to re-render an existing project:
uv run --project tools python tools/scripts/update_cmake_cfg.py \ --src src/example --root . --ctx lib/stm32g4 --lib stm32 --lib dbc