Build Script Internals
scripts/build.sh is the entry point for every build, local and CI. This page covers what it does
under the hood; for everyday usage see Build Tools.
| Flag | Default | Meaning |
|---|---|---|
-s, --src | required | project directory |
-p, --preset | Debug | Debug or Release |
-t, --target | basename of --src | CMake target, if it differs from the directory name |
-f, --flash | off | flash the ELF after a successful build |
-c, --clean | off | remove build artifacts and exit |
-h, --help | usage |
Three environment variables tune flashing:
| Variable | Default | Passed to |
|---|---|---|
PORT | swd | STM32_Programmer_CLI --connect port= |
FREQ | 8000 | freq= |
RESET | HWrst | reset= |
Sequence
Section titled “Sequence”-
Dependency check.
cmake,ninjaanduvmust be onPATH;STM32_Programmer_CLIis required only with--flash. -
Submodule check.
lib/stm32g4/STM32CubeG4/.gitmust exist, otherwise it prints thegit submodule update --init --recursivehint and exits. -
Clean, if asked.
--cleanremoves three things and exits without building: the project’sbuild/<preset>directory,tools/.venv, and the sharedlib/dbc/build. -
Configure, only if needed. CMake runs only when
build/<preset>/build.ninjais absent:Terminal window cmake --preset "$PRESET"No
-Dflags are passed; the preset supplies the generator, build directory, toolchain file and build type. Ninja re-runs CMake itself when aCMakeLists.txtchanges, so skipping is safe. A genuinely stale cache is what--cleanis for. -
Build.
Terminal window cmake --build --target "$TARGET_NAME" --preset "$PRESET"Parallelism comes from
CMAKE_BUILD_PARALLEL_LEVELin the environment; the script sets no-jof its own. -
Flash, if asked.
Terminal window STM32_Programmer_CLI --connect port=$PORT freq=$FREQ reset=$RESET \--write <elf> --verify --start -
.clangd. If the project has no.clangd, one is generated:Terminal window uv run --quiet --project tools python tools/scripts/clangd.py \--src "$SRC_DIR" --ctx lib/stm32g4This uses
uv runrather than the venv Python directly so it works before any venv exists. The file is gitignored and contains machine-specific include paths, so it is per-developer.
Why the Target Name Matters
Section titled “Why the Target Name Matters”The build is target-scoped, so --target must match CMAKE_PROJECT_NAME in the generated
CMakeLists.txt. For projects created by scripts/new.sh the directory name and the target name
are the same and you can omit the flag.