The Build System
Zephyr uses CMake as its build system generator and Ninja as the build tool. You almost never write CMake directly — West handles it for you.
Build output files
After west build, everything lands in the build/zephyr/ directory:
| File | What it's for |
|---|---|
zephyr.elf | ELF binary with debug symbols — used by GDB |
zephyr.hex | Intel HEX format for flashing |
zephyr.bin | Raw binary |
zephyr.dts | Merged, final devicetree — read this to debug DT issues |
.config | Final resolved Kconfig — read this to debug config issues |
zephyr.map | Linker map — shows flash and RAM usage per symbol |
Checking memory usage
After a build, check how much flash and RAM your firmware uses:
west build -b esp32s3_devkitc/esp32s3/procpu . && \
cat build/zephyr/zephyr.stat
Or with the size tool:
arm-zephyr-eabi-size build/zephyr/zephyr.elf
Example output:
text data bss dec hex filename
42312 312 6248 48872 bf08 build/zephyr/zephyr.elf
| Field | Meaning |
|---|---|
text | Flash used by code and read-only data |
data | RAM used by initialized variables (also stored in flash) |
bss | RAM used by zero-initialized variables |
Useful build flags
# Force a full clean rebuild
west build --pristine
# Build with a custom overlay file
west build -b esp32s3_devkitc/esp32s3/procpu . -- \
-DDTC_OVERLAY_FILE=boards/esp32s3_devkitc_esp32s3_procpu.overlay
# Override a Kconfig value without editing prj.conf
west build -b esp32s3_devkitc/esp32s3/procpu . -- \
-DCONFIG_LOG_DEFAULT_LEVEL=4
# Build with verbose output (see every compiler command)
west build -b esp32s3_devkitc/esp32s3/procpu . -- -DCMAKE_VERBOSE_MAKEFILE=ON
-- separates west build arguments from CMake arguments. Everything after -- is passed directly to CMake.
Build-time vs. runtime errors
| Error type | When it happens | How to debug |
|---|---|---|
| Kconfig error | west build fails | Check the depends on chain in the driver's Kconfig file |
| DTS error | west build fails | Read build/zephyr/zephyr.dts after fixing |
| Linker error | west build fails | Usually a missing CONFIG_ or wrong target_sources() |
| Runtime panic | Board crashes after flash | Use Serial Monitor or west debug + GDB |
The first thing to check is always build/zephyr/.config (Kconfig) and build/zephyr/zephyr.dts (devicetree). The build system writes these intermediate files before compilation — they show exactly what Zephyr assembled from your project.
🎉 You're ready!
Welcome to Zephyr RTOS 🚀
You've just completed the full embedded development loop.
From zero to firmware running on real hardware — that's no small thing.
Here's what you accomplished:
✅ Set up a cross-platform Zephyr development environment
✅ Installed west and initialized a workspace with Zephyr v4.4.0
✅ Built and flashed your first firmware binary
✅ Read live output from your board over serial
What's next — the real Zephyr:
Describe your hardware in code. The heart of Zephyr.
Control exactly what gets compiled into your firmware.
GPIO, I2C, SPI, UART, BLE — all with one unified API.
Semaphores, message queues, timers — real-time done right.
Every embedded engineer who works with Zephyr started exactly where you are right now. The tools are set up, the workspace is ready — now go build something real. 💪