]> granicus.if.org Git - esp-idf/blob - docs/build_system.rst
Rename README.buildenv to docs/build_system.rst and ReST-ify it
[esp-idf] / docs / build_system.rst
1 Build System
2 ------------
3
4 This document explains the Espressif IoT Development Framework build system and the
5 concept of "components"
6
7 Read this document if you want to know how to organise a new ESP-IDF project.
8
9 We recommend using the esp-idf-template_ project as a starting point for your project.
10
11 Overview
12 ========
13
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
16 have:
17
18 - The ESP32 base libraries (libc, rom bindings etc)
19 - The WiFi drivers
20 - A TCP/IP stack
21 - The FreeRTOS operating system
22 - A webserver
23 - A driver for an humidity sensor
24 - Main code tying it all together
25
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.
34
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::
38
39     - myProject/ - build/
40                  - components/ - component1/ - component.mk
41                                              - Kconfig
42                                              - src1.c
43                                - component2/ - component.mk
44                                              - Kconfig
45                                              - src1.c
46                  - main/       - src1.c
47                                - src2.c
48                  - Makefile
49
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.
57
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.
62
63 Project makefile variables that can be set by the programmer::
64
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
73           COMPONENT_DIRS.
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.
78
79 Component makefile variables that can be set by the programmer::
80
81     COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to
82             the entire project
83     COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used
84             when compiling this specific component
85     COMPONENT_DEPENDS: Names of any components that need to be compiled before this component.
86     COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME).
87             Add libraries etc in the current directory as $(abspath libwhatever.a)
88     COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and
89             passed to the compiler; please put absolute paths here.
90     COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current
91             directory (the root of the component) only. Use this to specify any subdirectories. Note
92             that specifying this overwrites the default action of compiling everything in the
93             components root dir; to keep this behaviour please also add '.' as a directory in this
94             list.
95     COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files
96             that are found in COMPONENT_SRCDIRS.
97     COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile
98             that also need to be cleaned
99     COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all
100             COMPONENT_OBJS and linking them into lib(componentname).a
101     COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing
102             all built objects and libraries.
103     COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir
104             of the component (where all the .o etc files should be created).
105
106 These variables are already set early on in the Makefile and the values in it will
107 be usable in component or project Makefiles::
108
109     CC, LD, AR, OBJCOPY: Xtensa gcc tools
110     HOSTCC, HOSTLD etc: Host gcc tools
111     LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile
112     PROJECT_NAME: Name of the project, as set in project makefile
113     PROJECT_PATH: Path to the root of the project folder
114     COMPONENTS: Name of the components to be included
115     CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables.
116
117 For components, there also are these defines::
118
119     COMPONENT_PATH: Absolute path to the root of the source tree of the component we're
120             compiling
121     COMPONENT_LIBRARY: The full path to the static library the components compilation pass
122         is supposed to generate
123
124 Make Process
125 ------------
126
127 The Make process is always invoked from the project directory by the
128 user; invoking it anywhere else gives an error. This is what happens if
129 we build a binary:
130
131 The Makefile first determines how it was included. It figures out
132 various paths as well as the components available to it. It will also
133 collect the ldflags and includes that the components specify they need.
134 It does this by running a dummy make on the components with a "get_variable"
135 target that will output these values.
136
137 The Makefile will then create targets to build the lib*.a libraries of
138 all components and make the elf target depend on this. The main Makefile
139 invokes Make on the componen.mk of each components inside a sub-mke: this way
140 the components have full freedom to do whatever is necessary to build
141 the library without influencing other components. By default, the
142 component.mk includes the utility makefile $(IDF_PATH)/make/component_common.mk.
143 This provides default targets and configurations that will work
144 out-of-the-box for most projects.
145
146 KConfig
147 -------
148
149 Each component can also have a Kconfig file, alongside the component.mk, that contains
150 details to add to "menuconfig" for this component.
151
152 Makefile.projbuild
153 ------------------
154
155 For components that have parts that need to be run when building of the
156 project is done, you can create a file called Makefile.projbuild in the
157 component root directory. This  file will be included in the main
158 Makefile.
159
160
161 KConfig.projbuild
162 -----------------
163
164 There's an equivalent to Makefile.projbuild for KConfig: if you want to include
165 options at the top-level, not inside the 'components' submenu then create a Kconfig.projbuild and
166 it will be included in the main menu of menuconfig.
167
168 Take good care when (re)defining stuff here: because it's included with all the other
169 .projbuild files, it's possible to overwrite variables or re-declare targets defined in
170 the ESP-IDF makefile/Kconfig and other .projbuild files. It's generally better to just
171 create a KConfig file, if you can.
172
173
174 Writing Component Makefiles
175 ---------------------------
176
177 A component consists of a directory which doubles as the name for the
178 component: a component named 'httpd' lives in a directory called 'httpd'
179 Because components usually live under the project directory (although
180 they can also reside in an other folder), the path to this may be
181 something like  /home/myuser/projects/myprojects/components/httpd .
182
183 One of the things that most components will have is a component.mk makefile,
184 containing instructions on how to build the component. Because the
185 build environment tries to set reasonable defaults that will work most
186 of the time, component.mk can be very small. 
187
188 Simplest component.mk
189 =====================
190
191 At the  minimum, component.mk will just include the ESP-IDF component "common" makefile,
192 which adds common component functionality::
193
194     include $(IDF_PATH)/make/component_common.mk
195
196 This will take all the .c and .S files in the component root and compile
197 them into  object files, finally linking them into a library.
198
199
200 Adding source directories
201 =========================
202
203 By default, subdirectories are ignored. If your project has sources in subdirectories
204 instead of in the root of the component then you can tell that to the build
205 system by setting COMPONENT_SRCDIRS::
206
207     COMPONENT_SRCDIRS := src1 src2
208     include $(IDF_PATH)/make/component_common.mk
209
210 This will compile all source files in the src1/ and src2/ subdirectories
211 instead.
212
213 Specifying source files
214 =======================
215
216 The standard component.mk logic adds all .S and .c files in the source
217 directories as sources to be compiled unconditionally. It is possible
218 to circumvent that logic and hardcode the objects to be compiled by
219 manually setting the COMPONENT_OBJS variable to the name of the
220 objects that need to be generated::
221
222     COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o
223     include $(IDF_PATH)/make/component_common.mk
224
225
226 Adding conditional configuration
227 ================================
228
229 The configuration system can be used to conditionally compile some files
230 dependending on the options selected in ``make menuconfig``:
231
232 Kconfig::
233     config FOO_ENABLE_BAR
234             bool "Enable the BAR feature."
235         help
236                 This enables the BAR feature of the FOO component.
237
238 Makefile::
239     COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o)
240     include $(IDF_PATH)/make/component_common.mk
241
242
243 Source Code Generation
244 ======================
245
246 Some components will have a situation where a source file isn't supplied
247 with the  component itself but has to be generated from another file. Say
248 our component has a header file that consists of the converted binary
249 data of a BMP file, converted using a hypothetical tool called bmp2h. The
250 header file is then included in as C source file called graphics_lib.c::
251
252     COMPONENT_EXTRA_CLEAN := logo.h
253
254     graphics_lib.o: logo.h
255
256     logo.h: $(COMPONENT_PATH)/logo.bmp
257         bmp2h -i $^ -o $@
258
259     include $(IDF_PATH)/make/component_common.mk
260
261 In this example, graphics_lib.o and logo.h will be generated in the
262 current directory (the build directory) while logo.bmp comes with the
263 component and resides under the component path. Because logo.h is a
264 generated file, it needs to be cleaned when make clean is called which
265 why it is added to the COMPONENT_EXTRA_CLEAN variable.
266
267 Cosmetic Improvements
268 =====================
269
270 The above example will work just fine, but there's one last cosmetic
271 improvement that can be done. The make system tries to make the make
272 process somewhat easier on the  eyes by hiding the commands (unless you
273 run make with the V=1 switch) and this does  not do that yet. Here's an
274 improved version that will output in the same style as  the rest of the
275 make process::
276
277    COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h
278
279    graphics_lib.o: logo.h
280
281     logo.h: $(COMPONENT_PATH)/logo.bmp
282             $(summary) BMP2H $@
283             $(Q) bmp2h -i $^ -o $@
284
285     include $(IDF_PATH)/make/component_common.mk
286
287 Fully Overriding The Component Makefile
288 ---------------------------------------
289
290 Obviously, there are cases where all these recipes are insufficient for a
291 certain component, for example when the component is basically a wrapper
292 around another third-party component not originally intended to be
293 compiled under this build system. In that case, it's possible to forego
294 the build  system entirely by setting COMPONENT_OWNBUILDTARGET and
295 possibly  COMPONENT_OWNCLEANTARGET and defining your own build- and clean
296 target. The build target can do anything as long as it creates
297 $(COMPONENT_LIBRARY) for the main file to link into the project binary,
298 and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable
299 is set, the component can instruct the linker to do anything else as well.
300
301
302 .. _esp-idf-template: https://github.com/espressif/esp-idf-template