Build Systems

ESP-IDF CMake Structure

ESP-IDF leverages CMake heavily to manage its massive codebase. Understanding how ESP-IDF structures its CMakeLists.txt files is the key to adding new files and libraries to your ESP32 projects.


The Component-Based Architecture

ESP-IDF does not compile your project as one giant blob. It treats everything as a Component.

FreeRTOS is a component. The Wi-Fi driver is a component. Your main.c file is also a component!

Every component must have its own CMakeLists.txt file telling the build system what source files it contains, and what other components it depends on.


The Project-Level CMakeLists.txt

At the very root of your ESP-IDF project, there is a tiny CMakeLists.txt file.

cmake
1# The minimum version of CMake required
2cmake_minimum_required(VERSION 3.16)
3
4# Include the massive ESP-IDF build system logic
5include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6
7# Name your project
8project(hello_world)

This file does almost nothing except include the official project.cmake file from the ESP-IDF installation directory. This is the magic script that scans your folders, finds all the components, reads menuconfig, and generates the Ninja build files.


The Component-Level CMakeLists.txt

Inside your main/ folder, you have another CMakeLists.txt. This is the one you will edit the most.

When you add a new .c file to your project (like sensor.c), you must tell CMake about it here!

cmake
1# 1. Define the source files (.c files) this component needs to compile
2set(srcs "main.c" "sensor.c" "wifi_setup.c")
3
4# 2. Register the component with ESP-IDF
5idf_component_register(
6 SRCS ${srcs}
7 INCLUDE_DIRS "." # Where to find the .h files
8 REQUIRES nvs_flash # Other ESP-IDF components this code relies on
9)

The REQUIRES Keyword

By default, your main component automatically has access to the most common ESP-IDF libraries (FreeRTOS, GPIO, UART).

However, if you want to use a more advanced library (like nvs_flash to save data to memory, or esp_http_client to make web requests), you must explicitly list it in the REQUIRES section. This tells CMake to link that specific library to your code.

Adding an External Library

If you download an open-source driver from GitHub, you don't put it in main/. You put it in a new folder called components/.

text
my_project/
├── main/
│   ├── CMakeLists.txt
│   └── main.c
├── components/
│   └── my_cool_sensor/
│       ├── CMakeLists.txt   <-- You must create this!
│       ├── my_sensor.c
│       └── include/
│           └── my_sensor.h

Inside components/my_cool_sensor/CMakeLists.txt, you write:

cmake
1idf_component_register(
2 SRCS "my_sensor.c"
3 INCLUDE_DIRS "include"
4)

ESP-IDF's CMake system will automatically scan the components/ folder, find this file, compile it as a library, and link it to your main.c code without you having to change any other settings!

Previous
Ninja Build System