
Zephyr build failures due to missing device tree overlays are a common hurdle for firmware developers configuring board variants, peripheral shields, or application-specific pinouts. The error typically surfaces during the CMake configuration phase invoked by west build, terminating with a fatal “File not found” or “No such file or directory” error before compilation even begins.
This guide provides an exhaustive, root-cause investigation into how Zephyr’s build system processes overlays, explains why missing overlay errors occur in CMake, and demonstrates deterministic fixes to ensure reliable builds.
When initiating a build with west build, the CMake configuration phase halts abruptly. The console output typically presents one of two error patterns:
-- Found BOARD.dts: /zephyrproject/zephyr/boards/arm/stm32f4_discovery/stm32f4_discovery.dtsCMake Error at /zephyrproject/zephyr/cmake/modules/dts.cmake:189 (message):File not found: /workspace/app/boards/stm32f4_disco.overlayCall Stack (most recent call first):/zephyrproject/zephyr/cmake/modules/zephyr_default.cmake:132 (include)/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)CMakeLists.txt:4 (find_package)
Error: /workspace/app/custom.overlay: No such file or directoryFATAL ERROR: Unable to parse input treeCMake Error at /zephyrproject/zephyr/cmake/modules/dts.cmake:265 (message):command failed with return code: 1
These diagnostics indicate that Zephyr’s build pipeline was explicitly instructed—or implicitly configured via cache—to consume an overlay file that does not exist at the target filesystem path.
To resolve overlay build failures, it is critical to understand how Zephyr’s CMake scripts process devicetree inputs. A central tenet of Zephyr architecture is that application developers must never edit board .dts files directly, nor should they add #include "some.overlay" directives inside board DTS files. Overlays are managed entirely at the build system level.
dts.cmakeDuring the configuration step, /zephyr/cmake/modules/dts.cmake builds the unified devicetree using the following sequence:
<board>.dts.app.overlay.boards/ directory for <board>.overlay or <board>_<revision>.overlay.--shield <shield_name> is supplied, CMake resolves <shield_name>.overlay from standard shield directories.DTC_OVERLAY_FILE and EXTRA_DTC_OVERLAY_FILE.if(NOT EXISTS ${file}). If any file is absent, CMake terminates with a fatal File not found error..dts concatenated with all verified .overlay files into the C Preprocessor (gcc -E -P -x assembler-with-cpp).dtc into build/zephyr/zephyr.dts.scripts/dts/gen_defines.py) to generate C preprocessor macros in build/zephyr/include/generated/devicetree_generated.h.CMakeCache.txt: When an overlay is discovered or passed on the command line, CMake stores the file path in CMakeCache.txt under DTC_OVERLAY_FILE. If you rename or delete that file (for example, switching from custom.overlay to app.overlay), subsequent incremental west build runs still inspect the cached path and immediately abort.-DEXTRA_DTC_OVERLAY_FILE are resolved relative to the current working directory of the shell or CMake invocation, not necessarily the application source tree unless an absolute path or ${APPLICATION_SOURCE_DIR} is used.--shield my_sensor_shield when the actual shield definition file is boards/shields/my_sensor/my_sensor.overlay will trigger a missing overlay failure.STM32F4_Discovery.overlay and stm32f4_discovery.overlay causes immediate file lookup failure.Check the exact file path reported in the error message. Note whether the path is absolute or relative, and confirm whether it points to:
app.overlay)boards/<board>.overlay)EXTRA_DTC_OVERLAY_FILE)If the overlay was deleted, renamed, or relocated, the cached variable in build/CMakeCache.txt must be purged. Execute a pristine build using the -p always flag:
west build -p always -b stm32f4_discovery
This clears the entire build directory, forcing CMake to scan the directory tree afresh.
When specifying overlays manually via the command line, separate multiple overlay paths with semicolons (the standard CMake list separator) and use valid filesystem paths:
# Using relative path from application directorywest build -b stm32f4_discovery -- -DEXTRA_DTC_OVERLAY_FILE="dts/sensors.overlay"# Using absolute pathwest build -b stm32f4_discovery -- -DEXTRA_DTC_OVERLAY_FILE="$PWD/dts/sensors.overlay"
In CMakeLists.txt, always anchor paths to ${APPLICATION_SOURCE_DIR}:
# Recommended CMakeLists.txt overlay inclusionlist(APPEND EXTRA_DTC_OVERLAY_FILE "${APPLICATION_SOURCE_DIR}/custom.overlay")
To minimize configuration overhead, leverage Zephyr’s automatic overlay discovery. Structure your application directory as follows:
my_zephyr_app/├── CMakeLists.txt├── prj.conf├── app.overlay <-- Automatically applied to ALL boards├── boards/│ ├── stm32f4_discovery.overlay <-- Applied ONLY when -b stm32f4_discovery│ └── nucleo_f401re.overlay <-- Applied ONLY when -b nucleo_f401re└── src/└── main.c
When files are placed in these standard locations, omit -DEXTRA_DTC_OVERLAY_FILE. CMake will automatically locate and merge them.
Here is a complete walkthrough resolving a missing overlay error and successfully modifying hardware definitions.
The developer attempts to compile an application with an external SPI sensor overlay:
$ west build -b stm32f4_discovery -- -DEXTRA_DTC_OVERLAY_FILE="overlay/spi_sensor.overlay"
Output:
CMake Error at /zephyrproject/zephyr/cmake/modules/dts.cmake:191 (message):File not found: overlay/spi_sensor.overlay
Checking the directory reveals the folder was named overlays/ (plural), not overlay/:
$ ls overlays/spi_sensor.overlay
Rather than passing lengthy command-line arguments, move the overlay into boards/:
$ mkdir -p boards$ cp overlays/spi_sensor.overlay boards/stm32f4_discovery.overlay
The content of boards/stm32f4_discovery.overlay:
/* Enable SPI1 and attach an external sensor */&spi1 {status = "okay";pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>;pinctrl-names = "default";cs-gpios = <&gpioc 4 GPIO_ACTIVE_LOW>;sensor: sensor@0 {compatible = "bosch,bme280";reg = <0>;spi-max-frequency = <10000000>;};};
Rebuild with cache flush:
$ west build -p always -b stm32f4_discovery
Console confirms overlay inclusion:
-- Found BOARD.dts: .../stm32f4_discovery/stm32f4_discovery.dts-- Found devicetree overlay: .../my_zephyr_app/boards/stm32f4_discovery.overlay-- Generating zephyr.dts-- Generated zephyr.dts: .../my_zephyr_app/build/zephyr/zephyr.dts[100%] Built target zephyr_final
Verify that the final device tree incorporates the changes:
$ grep -A 10 "sensor@0" build/zephyr/zephyr.dts
+-------------------------+ +-------------------------+ +-------------------------+| Base Board DTS | | Automatic Overlays | | Command-Line / CMake || (stm32f4_discovery.dts) | | (app.overlay, | | EXTRA_DTC_OVERLAY_ || | | boards/<board>.overlay) | | FILE / Shields |+------------+------------+ +------------+------------+ +------------+------------+| | |+-------------------------------+-------------------------------+|v+-----------------------------------------------------------------------------------------+| zephyr/cmake/modules/dts.cmake || || 1. Validate all overlay paths via if(NOT EXISTS <file>) || 2. If missing -> emit fatal CMake Error "File not found" || 3. If valid -> compile aggregated devicetree source list |+--------------------------------------------+--------------------------------------------+|v+-----------------------------------------------------------------------------------------+| C Preprocessor (gcc -E -P) || Includes DTS headers, macros, and pre-processes hardware nodes |+--------------------------------------------+--------------------------------------------+|v+-----------------------------------------------------------------------------------------+| dtc (Device Tree Compiler) || Checks syntax, resolves node labels, & outputs pre-compiled DTS |+--------------------------------------------+--------------------------------------------+|v+----------------------+----------------------+| |v v+-------------------------------+ +-------------------------------+| Final Device Tree | | Generated C Macro Header || build/zephyr/zephyr.dts | | build/zephyr/include/ || | | generated/ || | | devicetree_generated.h |+-------------------------------+ +-------------------------------+
#include for .overlay files: Overlays are dynamic CMake inputs. Incorporating .overlay files directly into .dts sources violates Zephyr component modularity.west build -p always to eliminate stale paths in CMakeCache.txt.app.overlay for cross-board changes and boards/<board>.overlay for board-specific pinouts.build/zephyr/zephyr.dts: Always verify that your overlay nodes and property modifications correctly merged into the final generated devicetree.Quick Links
Legal Stuff





