Hi MikeLemon,
IDF projects are built from components. Each component may contain multiple source and header files. Components may depend on other components. The minimal IDF project consists of the root CMakeLists.txt file and the 'main' component. You can also add more components by creating them inside 'components' subdirectory of the project, or by referencing them using EXTRA_COMPONENT_DIRS, or using the IDF component manager. Every component you create (including the 'main' component) has its own CMakeLists.txt file.
Let's say you are starting from the minimal project:
Code: Select all
project/
- CMakeLists.txt
- main/
- CMakeLists.txt
- main.c
In this case, CMakeLists.txt in the 'main' component directory should contain:
Code: Select all
idf_component_register(SRCS main.c)
Now suppose you need to add another source file. You can do this next to main.c:
Code: Select all
project/
- CMakeLists.txt
- main/
- CMakeLists.txt
- main.c
- helper.c
- helper.h
The new source file has to be added to the sources list:
Code: Select all
idf_component_register(SRCS main.c helper.c)
Now let's say that the code in 'helper.c' becomes self-sufficient and you would like to split it into a separate component. You can change project layout like this:
Code: Select all
project/
- CMakeLists.txt
- main/
- CMakeLists.txt
- main.c
- components/
- helper/
- CMakeLists.txt
- helper.c
- include/
- helper.h
CMakeLists.txt of the 'helper' component becomes:
Code: Select all
idf_component_register(SRCS helper.c INCLUDE_DIRS include)
It's very similar to what we had before, but this time INCLUDE_DIRS specifies a public include directory. This directory will be added to the include directory list when compiling sources of this component, and also of all components which depend on "helper".
The CMakeLists.txt file of the main component becomes:
Code: Select all
idf_component_register(SRCS main.c REQUIRES helper)
This component still has one source file, but this time it declares a dependency on "helper" component. This tells the build system that the include directories and compilation flags of "helper" have to be propagated to the "main" component. If you are using some other components aside from "helper", you have to list them as well.
The main idea of components is that you declare include directories at component level and then specify dependencies between components. If you have to specify an include directory one level above your component directory (such as ../something), this is usually a bad pattern. Try to define include directories at component level instead.
If you are familiar with "modern CMake", you will find the concept very similar. In modern CMake, each library declares its include directories using target_include_directories command, and libraries express dependencies on each other using target_link_libraries. In fact, idf_component_register is just a wrapper for some of these functions. You can still use standard CMake target_include_directories and target_link_libraries, if you like.
The concept of component dependencies is explained in the docs here:
https://docs.espressif.com/projects/esp ... quirements
More on writing component CMakeLists.txt files:
https://docs.espressif.com/projects/esp ... cmakelists
For an IDF example with multiple source files, please see
https://github.com/espressif/esp-idf/bl ... eLists.txt
Hope this helps! If something isn't clear, please don't hesitate to ask.