4 This document explains the Espressif IoT Development Framework build system and the
5 concept of "components"
7 Read this document if you want to know how to organise a new ESP-IDF project.
9 We recommend using the esp-idf-template_ project as a starting point for your project.
14 An ESP-IDF project can be seen as an almagation of a number of components.
15 For example, for a webserver that shows the current humidity, we would
18 - The ESP32 base libraries (libc, rom bindings etc)
21 - The FreeRTOS operating system
23 - A driver for an humidity sensor
24 - Main code tying it all together
26 ESP-IDF makes these components explicit and configurable. To do that, when a project
27 is compiled, the build environment will look up all the components in the
28 ESP-IDF directories, the project directories and optionally custom other component
29 directories. It then allows the user to configure compile-time options using
30 a friendly text-based menu system to customize the ESP-IDF as well as other components
31 to the requirements of the project. After the components are customized, the
32 build process will compile everything into an output file, which can then be uploaded
33 into a board in a way that can also be defined by components.
35 A project in this sense is defined as a directory under which all the files required
36 to build it live, excluding the ESP-IDF files and the toolchain. A simple project
37 tree might look like this::
40 - components/ - component1/ - component.mk
43 - component2/ - component.mk
50 As we can see, a project consists of a components/ subdirectory containing its
51 components as well as one or more directories containing the project-specific
52 sources; by default a single directory called 'main' is assumed. The project
53 directory will also have a Makefile where the projects name as well as optionally
54 other options are defined. After compilation, the project directory will contain
55 a 'build'-directory containing all of the objects, libraries and other generated
56 files as well as the final binary.
58 Components also have a custom makefile - ``component.mk``. This contains various definititions
59 influencing the build process of the component as well as the project it's used
60 in. Components may also include a Kconfig file defining the compile-time options that are
61 settable by means of the menu system.
63 Project Makefile variables that can be set by the programmer::
65 PROJECT_NAME: Mandatory. Name for the project
66 BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in.
67 Defaults to $(PROJECT_PATH)/build
68 COMPONENT_DIRS: Search path for components. Defaults to the component/ directories
69 in the ESP-IDF path and the project path.
70 COMPONENTS: A list of component names. Defaults to all the component found in the
71 COMPONENT_DIRS directory
72 EXTRA_COMPONENT_DIRS: Defaults to unset. Use this to add directories to the default
74 SRCDIRS: Directories under the project dir containing project-specific sources.
75 Defaults to 'main'. These are treated as 'lite' components: they do not have
76 include directories that are passed to the compilation pass of all components and
77 they do not have a Kconfig option.
79 Component-specific component.mk variables that can be set by the programmer::
81 COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to
82 the entire project. If an include directory is only needed to compile this
83 specific component, don't add it here.
84 COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used
85 when compiling this specific component.
86 COMPONENT_DEPENDS: Names of any components that need to be compiled before this component.
87 COMPONENT_ADD_LDFLAGS: LD flags to add for the entire project. Defaults to -l$(COMPONENT_NAME).
88 Add libraries etc in the current directory as $(abspath libwhatever.a)
89 COMPONENT_EXTRA_INCLUDES: Any extra include paths used when compiling the component's
90 source files. These will be prefixed with '-I' and passed to the compiler.
91 Similar to COMPONENT_PRIV_INCLUDEDIRS, but these paths are passed as-is instead of
92 expanded relative to the component directory.
93 COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current
94 directory (the root of the component) only. Use this to specify any subdirectories. Note
95 that specifying this overwrites the default action of compiling everything in the
96 components root dir; to keep this behaviour please also add '.' as a directory in this
98 COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files
99 that are found in COMPONENT_SRCDIRS.
100 COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile
101 that also need to be cleaned
102 COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all
103 COMPONENT_OBJS and linking them into lib(componentname).a
104 COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing
105 all built objects and libraries.
106 COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir
107 of the component (where all the .o etc files should be created).
109 These variables are already set early on in the Makefile and the values in it will
110 be usable in component or project Makefiles::
112 CC, LD, AR, OBJCOPY: Xtensa gcc tools
113 HOSTCC, HOSTLD etc: Host gcc tools
114 LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile
115 PROJECT_NAME: Name of the project, as set in project makefile
116 PROJECT_PATH: Path to the root of the project folder
117 COMPONENTS: Name of the components to be included
118 CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables.
120 Inside your component's component.mk makefile, you can override or add to these variables
121 as necessary. The changes are isolated from other components (see Makefile.projbuild below
122 if you want to share these changes with all other components.)
124 For components, there also are these defines::
126 COMPONENT_PATH: Absolute path to the root of the source tree of the component we're
128 COMPONENT_LIBRARY: The full path to the static library the components compilation pass
129 is supposed to generate
134 The Make process is always invoked from the project directory by the
135 user; invoking it anywhere else gives an error. This is what happens if
138 The Makefile first determines how it was included. It figures out
139 various paths as well as the components available to it. It will also
140 collect the ldflags and includes that the components specify they need.
141 It does this by running a dummy make on the components with a "get_variable"
142 target that will output these values.
144 The Makefile will then create targets to build the lib*.a libraries of
145 all components and make the elf target depend on this. The main Makefile
146 invokes Make on the componen.mk of each components inside a sub-mke: this way
147 the components have full freedom to do whatever is necessary to build
148 the library without influencing other components. By default, the
149 component.mk includes the utility makefile $(IDF_PATH)/make/component_common.mk.
150 This provides default targets and configurations that will work
151 out-of-the-box for most projects.
156 Each component can also have a Kconfig file, alongside the component.mk, that contains
157 details to add to "menuconfig" for this component.
162 For components that have parts that need to be evaluated in the top-level
163 project context, you can create a file called Makefile.projbuild in the
164 component root directory. These files is included into the project's
167 For example, if your component needs to add to CFLAGS for the entire
168 project (not just for its own source files) then you can set
169 ``CFLAGS +=`` in Makefile.projbuild. Note that this isn't necessary for
170 adding include directories to the project, you can set
171 ``COMPONENT_ADD_INCLUDEDIRS`` (see above) in the component.mk.
177 There's an equivalent to Makefile.projbuild for KConfig: if you want to include
178 options at the top-level, not inside the 'components' submenu then create a Kconfig.projbuild and
179 it will be included in the main menu of menuconfig.
181 Take good care when (re)defining stuff here: because it's included with all the other
182 .projbuild files, it's possible to overwrite variables or re-declare targets defined in
183 the ESP-IDF makefile/Kconfig and other .projbuild files. It's generally better to just
184 create a KConfig file, if you can.
187 Writing Component Makefiles
188 ---------------------------
190 A component consists of a directory which doubles as the name for the
191 component: a component named 'httpd' lives in a directory called 'httpd'
192 Because components usually live under the project directory (although
193 they can also reside in an other folder), the path to this may be
194 something like /home/myuser/projects/myprojects/components/httpd .
196 One of the things that most components will have is a component.mk makefile,
197 containing instructions on how to build the component. Because the
198 build environment tries to set reasonable defaults that will work most
199 of the time, component.mk can be very small.
201 Simplest component.mk
202 =====================
204 At the minimum, component.mk will just include the ESP-IDF component "common" makefile,
205 which adds common component functionality::
207 include $(IDF_PATH)/make/component_common.mk
209 This will take all the .c and .S files in the component root and compile
210 them into object files, finally linking them into a library.
213 Adding source directories
214 =========================
216 By default, subdirectories are ignored. If your project has sources in subdirectories
217 instead of in the root of the component then you can tell that to the build
218 system by setting COMPONENT_SRCDIRS::
220 COMPONENT_SRCDIRS := src1 src2
221 include $(IDF_PATH)/make/component_common.mk
223 This will compile all source files in the src1/ and src2/ subdirectories
226 Specifying source files
227 =======================
229 The standard component.mk logic adds all .S and .c files in the source
230 directories as sources to be compiled unconditionally. It is possible
231 to circumvent that logic and hardcode the objects to be compiled by
232 manually setting the COMPONENT_OBJS variable to the name of the
233 objects that need to be generated::
235 COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o
236 include $(IDF_PATH)/make/component_common.mk
239 Adding conditional configuration
240 ================================
242 The configuration system can be used to conditionally compile some files
243 dependending on the options selected in ``make menuconfig``:
246 config FOO_ENABLE_BAR
247 bool "Enable the BAR feature."
249 This enables the BAR feature of the FOO component.
252 COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o)
253 include $(IDF_PATH)/make/component_common.mk
256 Source Code Generation
257 ======================
259 Some components will have a situation where a source file isn't supplied
260 with the component itself but has to be generated from another file. Say
261 our component has a header file that consists of the converted binary
262 data of a BMP file, converted using a hypothetical tool called bmp2h. The
263 header file is then included in as C source file called graphics_lib.c::
265 COMPONENT_EXTRA_CLEAN := logo.h
267 graphics_lib.o: logo.h
269 logo.h: $(COMPONENT_PATH)/logo.bmp
272 include $(IDF_PATH)/make/component_common.mk
274 In this example, graphics_lib.o and logo.h will be generated in the
275 current directory (the build directory) while logo.bmp comes with the
276 component and resides under the component path. Because logo.h is a
277 generated file, it needs to be cleaned when make clean is called which
278 why it is added to the COMPONENT_EXTRA_CLEAN variable.
280 Cosmetic Improvements
281 =====================
283 The above example will work just fine, but there's one last cosmetic
284 improvement that can be done. The make system tries to make the make
285 process somewhat easier on the eyes by hiding the commands (unless you
286 run make with the V=1 switch) and this does not do that yet. Here's an
287 improved version that will output in the same style as the rest of the
290 COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h
292 graphics_lib.o: logo.h
294 logo.h: $(COMPONENT_PATH)/logo.bmp
296 $(Q) bmp2h -i $^ -o $@
298 include $(IDF_PATH)/make/component_common.mk
300 Fully Overriding The Component Makefile
301 ---------------------------------------
303 Obviously, there are cases where all these recipes are insufficient for a
304 certain component, for example when the component is basically a wrapper
305 around another third-party component not originally intended to be
306 compiled under this build system. In that case, it's possible to forego
307 the build system entirely by setting COMPONENT_OWNBUILDTARGET and
308 possibly COMPONENT_OWNCLEANTARGET and defining your own build- and clean
309 target. The build target can do anything as long as it creates
310 $(COMPONENT_LIBRARY) for the main file to link into the project binary,
311 and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable
312 is set, the component can instruct the linker to do anything else as well.
315 .. _esp-idf-template: https://github.com/espressif/esp-idf-template