build_system.rst 13 KB

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