Building Firmware with CMake
What this presentation is about and why it matters
How do you turn a firmware build from copy-pasted command lines into something repeatable, portable, and easier to extend? Amar Mahmutbegovic walks through that problem with a hands-on progression, starting from a tiny host-side Hello World project and then moving it onto an STM32 target running in Renode. The talk uses a practical CMake setup to show the moving parts of firmware builds, including source files, include paths, compile definitions, linker options, and platform-specific code. It is a good fit for anyone who wants to understand where CMake sits in the build flow and how to structure a firmware project so it can grow without becoming brittle.
Who will benefit the most from this presentation
- Firmware engineers who are still hand-assembling compiler and linker commands
- Embedded developers who can build for a host machine but struggle to adapt the same project for a microcontroller
- Teams trying to make a firmware build reproducible across local machines and CI environments
- Engineers who want a clearer split between platform code and application code in CMake
What you need to know
Some familiarity with embedded firmware builds will help, especially the basics of compilation and linking.
- Comfort reading simple C or C++ source files
- Awareness of what compiler flags, linker scripts, and startup code do
- Basic understanding of ARM Cortex-M style firmware builds
Glossary (terms used in this talk)
- Linker script: A build-time description that maps code and data sections into physical memory regions. It also defines symbols that startup code can use to copy or clear memory during boot.
- CMake: A build system generator that describes targets, sources, and build settings in a platform-independent way, then generates files for tools such as Make or Ninja. It is commonly used to keep complex builds consistent across machines and toolchains.
- Toolchain file: A configuration file that tells a build system which compiler, linker, and target platform to use. It is especially useful when building for embedded targets that differ from the host machine.
- Configure phase: The step where a build system checks the environment, detects tools, and generates the build files it will use later. This phase often fails early if the target platform is not described well enough.
- Build phase: The step where generated build files are executed to compile, link, and produce the final artifacts. It is separate from configuration so the same generated project can be rebuilt repeatedly.
- Static library: An archive of object files that other targets can link against. It is commonly used to isolate reusable platform code from application code.
- Renode: A simulator for embedded systems that can run firmware images without physical hardware. It is useful for validating embedded builds and basic runtime behavior in a repeatable environment.
Toolbox (mentioned in this talk)
- ARM CMSIS DSP: A set of DSP-oriented routines and intrinsics for ARM Cortex-M and Cortex-A processors. It provides optimized building blocks such as filters, transforms, and matrix operations for embedded signal processing.
- CMake: A cross-platform build system generator that helps define and drive builds across different compilers, IDEs, and platforms.
- GCC: A widely used compiler toolchain for C and C++ and other languages. In embedded development, it is commonly used to build firmware for many microcontrollers.
- Renode: An open-source platform for emulating embedded hardware and connected devices. It is used to run firmware in a simulated hardware environment.
- STM32: A family of microcontrollers commonly used for embedded control and hardware interfacing. They are often used to drive peripherals such as LEDs, motors, and sensors.
- STM32Cube: STMicroelectronics' software development ecosystem for STM32 microcontrollers, including peripheral configuration and generated project code.
Final thoughts
Practical and tutorial-style, this talk gives you a grounded look at how firmware builds are assembled and how CMake can sit in the middle without becoming mysterious. The value here is a clearer mental model of target setup, platform separation, and the step-by-step transition from host build to embedded build. That makes it useful for firmware engineers, CMake newcomers, and anyone trying to make an embedded project easier to repeat and maintain. The pace is calm, but the examples are concrete and directly tied to the build flow.
This overview is AI-generated from the session transcript. Spot an issue? Let us know.








Writing cmake scripts and similar is one of those task that you do intensively at the start of project, and then it's rarely touched the next year or more. Same for next project a.s.o.
This means that it is very hard to remember all those "special secrets" like the name and existence of CMAKE_*** vars to set like
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)If we leave out AI for a moment, can you recommend any sources that help me finding all those variables, without reading the entire manual ;-)?
Or maybe IDE plugins that can help?