diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 225b48f94..15a1db2fc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,6 +18,10 @@ build_template_app: script: - git clone https://github.com/espressif/esp-idf-template.git - cd esp-idf-template + # Try to use the same branch name for esp-idf-template that we're + # using on esp-idf. If it doesn't exist then just stick to the default + # branch + - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." - make defconfig - make all diff --git a/README.buildenv b/README.buildenv deleted file mode 100644 index fd6830005..000000000 --- a/README.buildenv +++ /dev/null @@ -1,265 +0,0 @@ -The build structure of the Espressif IoT Development Framework explained. - -An ESP-IDF project can be seen as an almagation of a number of components. -For example, for a webserver that shows the current humidity, we would -have: -- The ESP32 base libraries (libc, rom bindings etc) -- The WiFi drivers -- A TCP/IP stack -- The FreeRTOS operating system -- A webserver -- A driver for an humidity sensor -- Main code tying it all together - -ESP-IDF makes these components explicit and configurable. To do that, when a project -is compiled, the build environment will look up all the components in the -ESP-IDF directories, the project directories and optionally custom other component -directories. It then allows the user to configure compile-time options using -a friendly text-based menu system to customize the ESP-IDF as well as other components -to the requirements of the project. After the components are customized, the -build process will compile everything into an output file, which can then be uploaded -into a board in a way that can also be defined by components. - -A project in this sense is defined as a directory under which all the files required -to build it live, excluding the ESP-IDF files and the toolchain. A simple project -tree looks like this: - -- myProject/ - build/ - - components/ - component1/ - Makefile - - Kconfig - - src1.c - - component2/ - Makefile - - Kconfig - - src1.c - - main/ - src1.c - - src2.c - - Makefile - - -As we can see, a project consists of a components/ subdirectory containing its -components as well as one or more directories containing the project-specific -sources; by default a single directory called 'main' is assumed. The project -directory will also have a Makefile where the projects name as well as optionally -other options are defined. After compilation, the project directory will contain -a 'build'-directory containing all of the objects, libraries and other generated -files as well as the final binary. - -Components also have a Makefile containing various definititions influencing -the build process of the component as well as the project it's used in, as -well as a Kconfig file defining the compile-time options that are settable -by means of the menu system. - - -Project makefile variables that can be set by the programmer: -PROJECT_NAME: Mandatory. Name for the project -BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in. - Defaults to $(PROJECT_PATH)/build -COMPONENT_DIRS: Search path for components. Defaults to the component/ directories - in the ESP-IDF path and the project path. -COMPONENTS: A list of component names. Defaults to all the component found in the - COMPONENT_DIRS directory -EXTRA_COMPONENT_DIRS: Defaults to unset. Use this to add directories to the default - COMPONENT_DIRS. -SRCDIRS: Directories under the project dir containing project-specific sources. - Defaults to 'main'. These are treated as 'lite' components: they do not have - include directories that are passed to the compilation pass of all components and - they do not have a Kconfig option. - - -Component makefile variables that can be set by the programmer: -COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to - the entire project -COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used - when compiling this specific component -COMPONENT_DEPENDS: Names of any components that need to be compiled before this component. -COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME). - Add libraries etc in the current directory as $(abspath libwhatever.a) -COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and - passed to the compiler; please put absolute paths here. -COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current - directory (the root of the component) only. Use this to specify any subdirectories. Note - that specifying this overwrites the default action of compiling everything in the - components root dir; to keep this behaviour please also add '.' as a directory in this - list. -COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files - that are found in COMPONENT_SRCDIRS. -COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile - that also need to be cleaned -COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all - COMPONENT_OBJS and linking them into lib(componentname).a -COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing - all built objects and libraries. -COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir - of the component (where all the .o etc files should be created). - - -These variables are already set early on in the Makefile and the values in it will -be usable in component or project Makefiles: -CC, LD, AR, OBJCOPY: Xtensa gcc tools -HOSTCC, HOSTLD etc: Host gcc tools -LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile -PROJECT_NAME: Name of the project, as set in project makefile -PROJECT_PATH: Path to the root of the project folder -COMPONENTS: Name of the components to be included -CONFIG_*: Values set by 'make menuconfig' also have corresponding Makefile variables. - -For components, there also are these defines: -COMPONENT_PATH: Absolute path to the root of the source tree of the component we're - compiling -COMPONENT_LIBRARY: The full path to the static library the components compilation pass - is supposed to generate - - -How this works: -The Make process is always invoked from the project directory by the -user; invoking it anywhere else gives an error. This is what happens if -we build a binary: - -The Makefile first determines how it was included. It determines it was -included as a project file in this case and will continue to figure out -various paths as well as the components available to it. It will also -collect the ldflags and includes that the components specify they need. -It does this by running a dummy Make on the components with a target that -will output these values. - -The Makefile will then create targets to build the lib*.a libraries of -all components and make the elf target depend on this. The targets -invoke Make on the makefiles of the components in a subshell: this way -the components have full freedom to do whatever is necessary to build -the library without influencing other components. By default, the -component includes the utility makefile $(IDF_PATH)/make/component.mk. -This provides default targets and configurations that will work -out-of-the-box for most projects. - -For components that have parts that need to be run when building of the -project is done, you can create a file called Makefile.projbuild in the -component root directory. This file will be included in the main -Makefile. For the menu, there's an equivalent: if you want to include -options not in the 'components' submenu, create a Kconfig.projbuild and -it will be included in the main menu of menuconfig. Take good care when -(re)defining stuff here: because it's included with all the other -.projbuild files, it's possible to overwrite variables or re-declare -targets defined in the ESP-IDF makefile/Kconfig and other .projbuild files - - -WRITING COMPONENT MAKEFILES - -A component consists of a directory which doubles as the name for the -component: a component named 'httpd' lives in a directory called 'httpd' -Because components usually live under the project directory (although -they can also reside in an other folder), the path to this may be -something like /home/myuser/projects/myprojects/components/httpd . - -One of the things that most components will have is a Makefile, -containing instructions on how to build the component. Because the -build environment tries to set reasonable defaults that will work most -of the time, a component Makefile can be pretty small. At the absolute -minimum, it will just include the ESP-IDF component makefile, which adds -component functionality: - -----8<---- -include $(IDF_PATH)/make/component.mk ----->8---- - -This will take all the .c and .S files in the component root and compile -them into object files, finally linking them into a library. -Subdirectories are ignored; if your project has sources in subdirectories -instead of in the root of the component, you can tell that to the build -system by setting COMPONENT_SRCDIRS: - -----8<---- -COMPONENT_SRCDIRS := src1 src2 -include $(IDF_PATH)/make/component.mk ----->8---- - -This will compile all source files in the src1/ and src2/ subdirectories -instead. - -The standard component.mk logic adds all .S and .c files in the source -directories as sources to be compiled unconditionally. It is possible -to circumvent that logic and hardcode the objects to be compiled by -manually setting the COMPONENT_OBJS variable to the name of the -objects that need to be generated: - -----8<---- -COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o -include $(IDF_PATH)/make/component.mk ----->8---- - -This can also be used in order to conditionally compile some files -dependent on the options selected in the Makefile: - -Kconfig: -----8<---- -config FOO_ENABLE_BAR - bool "Enable the BAR feature." - help - This enables the BAR feature of the FOO component. ----->8---- - -Makefile: -----8<---- -COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o) -include $(IDF_PATH)/make/component.mk ----->8---- - -Some components will have a situation where a source file isn't supplied -with the component itself but has to be generated from another file. Say -our component has a header file that consists of the converted binary -data of a BMP file, converted using a hypothetical tool called bmp2h. The -header file is then included in as C source file called graphics_lib.c. - -----8<---- -COMPONENT_EXTRA_CLEAN := logo.h - -graphics_lib.o: logo.h - -logo.h: $(COMPONENT_PATH)/logo.bmp - bmp2h -i $^ -o $@ - -include $(IDF_PATH)/make/component.mk ----->8---- - -In this example, graphics_lib.o and logo.h will be generated in the -current directory (the build directory) while logo.bmp comes with the -component and resides under the component path. Because logo.h is a -generated file, it needs to be cleaned when make clean is called which -why it is added to the COMPONENT_EXTRA_CLEAN variable. - - -This will work just fine, but there's one last cosmetic improvement that -can be done. The make system tries to make the make process somewhat -easier on the eyes by hiding the commands (unless you run make with the -V=1 switch) and this does not do that yet. Here's an improved version -that will output in the same style as the rest of the make process: - -----8<---- -COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h - -graphics_lib.o: logo.h - -logo.h: $(COMPONENT_PATH)/logo.bmp - $(summary) BMP2H $@ - $(Q) bmp2h -i $^ -o $@ - -include $(IDF_PATH)/make/component.mk ----->8---- - -Obviously, there are cases where all these recipes are insufficient for a -certain component, for example when the component is basically a wrapper -around another third-party component not originally intended to be -compiled under this build system. In that case, it's possible to forego -the build system entirely by setting COMPONENT_OWNBUILDTARGET and -possibly COMPONENT_OWNCLEANTARGET and defining your own build- and clean -target. The build target can do anything as long as it creates -$(COMPONENT_LIBRARY) for the main file to link into the project binary, -and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable -is set, the component can instruct the linker to do anything else as well. - - - - - - - - diff --git a/README.md b/README.md index 0c7d437e2..10fd72a3c 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,11 @@ The simplest way to use the partition table is to `make menuconfig` and choose o In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table. For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file. + +# Resources + +* The [docs directory of the esp-idf repository](https://github.com/espressif/esp-idf/tree/master/docs) contains esp-idf documentation. + +* The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources. + +* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one. diff --git a/components/bootloader/src/main/Makefile b/components/bootloader/src/main/component.mk similarity index 86% rename from components/bootloader/src/main/Makefile rename to components/bootloader/src/main/component.mk index 2bb773b9c..1671095f1 100644 --- a/components/bootloader/src/main/Makefile +++ b/components/bootloader/src/main/component.mk @@ -1,7 +1,7 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(IDF_PATH)/make/component.mk. By default, +# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default, # this will take the sources in the src/ directory, compile them and link them into # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, # please read the esp-idf build system document if you need to do this. @@ -10,4 +10,4 @@ COMPONENT_ADD_LDFLAGS := -L $(abspath .) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld COMPONENT_EXTRA_INCLUDES := $(IDF_PATH)/components/esp32/include -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/components/esp32/Makefile b/components/esp32/component.mk similarity index 96% rename from components/esp32/Makefile rename to components/esp32/component.mk index 95647c2eb..338f6b4b6 100644 --- a/components/esp32/Makefile +++ b/components/esp32/component.mk @@ -1,7 +1,7 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(IDF_PATH)/make/component.mk. By default, +# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default, # this will take the sources in this directory, compile them and link them into # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, # please read the esp-idf build system document if you need to do this. @@ -35,7 +35,7 @@ COMPONENT_ADD_LDFLAGS := -lesp32 \ -L $(abspath ld) \ $(LINKER_SCRIPTS) -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS)) diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 958911cb8..3da802296 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -48,7 +48,7 @@ config ESPTOOLPY_COMPRESSED choice ESPTOOLPY_FLASHMODE prompt "Flash SPI mode" - default ESPTOOLPY_FLASHMODE_QIO + default ESPTOOLPY_FLASHMODE_DIO help Mode the flash chip is flashed in, as well as the default mode for the binary to run in. diff --git a/components/freertos/Makefile b/components/freertos/component.mk similarity index 80% rename from components/freertos/Makefile rename to components/freertos/component.mk index e4003eb14..6702d1b95 100644 --- a/components/freertos/Makefile +++ b/components/freertos/component.mk @@ -6,4 +6,4 @@ COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) -Wl,--undefined=uxTopUsedPriority COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include/freertos -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/components/lwip/Makefile b/components/lwip/component.mk similarity index 85% rename from components/lwip/Makefile rename to components/lwip/component.mk index cf9c361f5..a605355d2 100644 --- a/components/lwip/Makefile +++ b/components/lwip/component.mk @@ -8,4 +8,4 @@ COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/free EXTRA_CFLAGS := -Wno-error=address -Waddress -DLWIP_ESP8266 -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/components/mbedtls/Makefile b/components/mbedtls/component.mk similarity index 79% rename from components/mbedtls/Makefile rename to components/mbedtls/component.mk index cb3ee2c56..ed8f117ff 100644 --- a/components/mbedtls/Makefile +++ b/components/mbedtls/component.mk @@ -8,4 +8,4 @@ COMPONENT_SRCDIRS := library port EXTRA_CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"' -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/components/newlib/Makefile b/components/newlib/component.mk similarity index 77% rename from components/newlib/Makefile rename to components/newlib/component.mk index 970461698..7c8c74deb 100644 --- a/components/newlib/Makefile +++ b/components/newlib/component.mk @@ -5,4 +5,4 @@ define COMPONENT_BUILDRECIPE #Nothing to do; this does not generate a library. endef -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/components/nvs_flash/Makefile b/components/nvs_flash/component.mk similarity index 66% rename from components/nvs_flash/Makefile rename to components/nvs_flash/component.mk index 58232cc89..02ff8cf03 100755 --- a/components/nvs_flash/Makefile +++ b/components/nvs_flash/component.mk @@ -6,4 +6,4 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_SRCDIRS := src -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/components/spi_flash/Makefile b/components/spi_flash/Makefile deleted file mode 100755 index fc41e5f43..000000000 --- a/components/spi_flash/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -COMPONENT_ADD_INCLUDEDIRS := include - -include $(IDF_PATH)/make/component.mk diff --git a/components/spi_flash/component.mk b/components/spi_flash/component.mk new file mode 100755 index 000000000..ef497a7ec --- /dev/null +++ b/components/spi_flash/component.mk @@ -0,0 +1,3 @@ +COMPONENT_ADD_INCLUDEDIRS := include + +include $(IDF_PATH)/make/component_common.mk diff --git a/components/tcpip_adapter/Makefile b/components/tcpip_adapter/component.mk similarity index 56% rename from components/tcpip_adapter/Makefile rename to components/tcpip_adapter/component.mk index 4028caf4a..cb863d1b7 100755 --- a/components/tcpip_adapter/Makefile +++ b/components/tcpip_adapter/component.mk @@ -4,4 +4,4 @@ EXTRA_CFLAGS := -DLWIP_ESP8266 -include $(IDF_PATH)/make/component.mk +include $(IDF_PATH)/make/component_common.mk diff --git a/docs/build_system.rst b/docs/build_system.rst new file mode 100644 index 000000000..24381019b --- /dev/null +++ b/docs/build_system.rst @@ -0,0 +1,302 @@ +Build System +------------ + +This document explains the Espressif IoT Development Framework build system and the +concept of "components" + +Read this document if you want to know how to organise a new ESP-IDF project. + +We recommend using the esp-idf-template_ project as a starting point for your project. + +Overview +======== + +An ESP-IDF project can be seen as an almagation of a number of components. +For example, for a webserver that shows the current humidity, we would +have: + +- The ESP32 base libraries (libc, rom bindings etc) +- The WiFi drivers +- A TCP/IP stack +- The FreeRTOS operating system +- A webserver +- A driver for an humidity sensor +- Main code tying it all together + +ESP-IDF makes these components explicit and configurable. To do that, when a project +is compiled, the build environment will look up all the components in the +ESP-IDF directories, the project directories and optionally custom other component +directories. It then allows the user to configure compile-time options using +a friendly text-based menu system to customize the ESP-IDF as well as other components +to the requirements of the project. After the components are customized, the +build process will compile everything into an output file, which can then be uploaded +into a board in a way that can also be defined by components. + +A project in this sense is defined as a directory under which all the files required +to build it live, excluding the ESP-IDF files and the toolchain. A simple project +tree might look like this:: + + - myProject/ - build/ + - components/ - component1/ - component.mk + - Kconfig + - src1.c + - component2/ - component.mk + - Kconfig + - src1.c + - main/ - src1.c + - src2.c + - Makefile + +As we can see, a project consists of a components/ subdirectory containing its +components as well as one or more directories containing the project-specific +sources; by default a single directory called 'main' is assumed. The project +directory will also have a Makefile where the projects name as well as optionally +other options are defined. After compilation, the project directory will contain +a 'build'-directory containing all of the objects, libraries and other generated +files as well as the final binary. + +Components also have a custom makefile - ``component.mk``. This contains various definititions +influencing the build process of the component as well as the project it's used +in. Components may also include a Kconfig file defining the compile-time options that are +settable by means of the menu system. + +Project makefile variables that can be set by the programmer:: + + PROJECT_NAME: Mandatory. Name for the project + BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in. + Defaults to $(PROJECT_PATH)/build + COMPONENT_DIRS: Search path for components. Defaults to the component/ directories + in the ESP-IDF path and the project path. + COMPONENTS: A list of component names. Defaults to all the component found in the + COMPONENT_DIRS directory + EXTRA_COMPONENT_DIRS: Defaults to unset. Use this to add directories to the default + COMPONENT_DIRS. + SRCDIRS: Directories under the project dir containing project-specific sources. + Defaults to 'main'. These are treated as 'lite' components: they do not have + include directories that are passed to the compilation pass of all components and + they do not have a Kconfig option. + +Component makefile variables that can be set by the programmer:: + + COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to + the entire project + COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used + when compiling this specific component + COMPONENT_DEPENDS: Names of any components that need to be compiled before this component. + COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME). + Add libraries etc in the current directory as $(abspath libwhatever.a) + COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and + passed to the compiler; please put absolute paths here. + COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current + directory (the root of the component) only. Use this to specify any subdirectories. Note + that specifying this overwrites the default action of compiling everything in the + components root dir; to keep this behaviour please also add '.' as a directory in this + list. + COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files + that are found in COMPONENT_SRCDIRS. + COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile + that also need to be cleaned + COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all + COMPONENT_OBJS and linking them into lib(componentname).a + COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing + all built objects and libraries. + COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir + of the component (where all the .o etc files should be created). + +These variables are already set early on in the Makefile and the values in it will +be usable in component or project Makefiles:: + + CC, LD, AR, OBJCOPY: Xtensa gcc tools + HOSTCC, HOSTLD etc: Host gcc tools + LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile + PROJECT_NAME: Name of the project, as set in project makefile + PROJECT_PATH: Path to the root of the project folder + COMPONENTS: Name of the components to be included + CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables. + +For components, there also are these defines:: + + COMPONENT_PATH: Absolute path to the root of the source tree of the component we're + compiling + COMPONENT_LIBRARY: The full path to the static library the components compilation pass + is supposed to generate + +Make Process +------------ + +The Make process is always invoked from the project directory by the +user; invoking it anywhere else gives an error. This is what happens if +we build a binary: + +The Makefile first determines how it was included. It figures out +various paths as well as the components available to it. It will also +collect the ldflags and includes that the components specify they need. +It does this by running a dummy make on the components with a "get_variable" +target that will output these values. + +The Makefile will then create targets to build the lib*.a libraries of +all components and make the elf target depend on this. The main Makefile +invokes Make on the componen.mk of each components inside a sub-mke: this way +the components have full freedom to do whatever is necessary to build +the library without influencing other components. By default, the +component.mk includes the utility makefile $(IDF_PATH)/make/component_common.mk. +This provides default targets and configurations that will work +out-of-the-box for most projects. + +KConfig +------- + +Each component can also have a Kconfig file, alongside the component.mk, that contains +details to add to "menuconfig" for this component. + +Makefile.projbuild +------------------ + +For components that have parts that need to be run when building of the +project is done, you can create a file called Makefile.projbuild in the +component root directory. This file will be included in the main +Makefile. + + +KConfig.projbuild +----------------- + +There's an equivalent to Makefile.projbuild for KConfig: if you want to include +options at the top-level, not inside the 'components' submenu then create a Kconfig.projbuild and +it will be included in the main menu of menuconfig. + +Take good care when (re)defining stuff here: because it's included with all the other +.projbuild files, it's possible to overwrite variables or re-declare targets defined in +the ESP-IDF makefile/Kconfig and other .projbuild files. It's generally better to just +create a KConfig file, if you can. + + +Writing Component Makefiles +--------------------------- + +A component consists of a directory which doubles as the name for the +component: a component named 'httpd' lives in a directory called 'httpd' +Because components usually live under the project directory (although +they can also reside in an other folder), the path to this may be +something like /home/myuser/projects/myprojects/components/httpd . + +One of the things that most components will have is a component.mk makefile, +containing instructions on how to build the component. Because the +build environment tries to set reasonable defaults that will work most +of the time, component.mk can be very small. + +Simplest component.mk +===================== + +At the minimum, component.mk will just include the ESP-IDF component "common" makefile, +which adds common component functionality:: + + include $(IDF_PATH)/make/component_common.mk + +This will take all the .c and .S files in the component root and compile +them into object files, finally linking them into a library. + + +Adding source directories +========================= + +By default, subdirectories are ignored. If your project has sources in subdirectories +instead of in the root of the component then you can tell that to the build +system by setting COMPONENT_SRCDIRS:: + + COMPONENT_SRCDIRS := src1 src2 + include $(IDF_PATH)/make/component_common.mk + +This will compile all source files in the src1/ and src2/ subdirectories +instead. + +Specifying source files +======================= + +The standard component.mk logic adds all .S and .c files in the source +directories as sources to be compiled unconditionally. It is possible +to circumvent that logic and hardcode the objects to be compiled by +manually setting the COMPONENT_OBJS variable to the name of the +objects that need to be generated:: + + COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o + include $(IDF_PATH)/make/component_common.mk + + +Adding conditional configuration +================================ + +The configuration system can be used to conditionally compile some files +dependending on the options selected in ``make menuconfig``: + +Kconfig:: + config FOO_ENABLE_BAR + bool "Enable the BAR feature." + help + This enables the BAR feature of the FOO component. + +Makefile:: + COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o) + include $(IDF_PATH)/make/component_common.mk + + +Source Code Generation +====================== + +Some components will have a situation where a source file isn't supplied +with the component itself but has to be generated from another file. Say +our component has a header file that consists of the converted binary +data of a BMP file, converted using a hypothetical tool called bmp2h. The +header file is then included in as C source file called graphics_lib.c:: + + COMPONENT_EXTRA_CLEAN := logo.h + + graphics_lib.o: logo.h + + logo.h: $(COMPONENT_PATH)/logo.bmp + bmp2h -i $^ -o $@ + + include $(IDF_PATH)/make/component_common.mk + +In this example, graphics_lib.o and logo.h will be generated in the +current directory (the build directory) while logo.bmp comes with the +component and resides under the component path. Because logo.h is a +generated file, it needs to be cleaned when make clean is called which +why it is added to the COMPONENT_EXTRA_CLEAN variable. + +Cosmetic Improvements +===================== + +The above example will work just fine, but there's one last cosmetic +improvement that can be done. The make system tries to make the make +process somewhat easier on the eyes by hiding the commands (unless you +run make with the V=1 switch) and this does not do that yet. Here's an +improved version that will output in the same style as the rest of the +make process:: + + COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h + + graphics_lib.o: logo.h + + logo.h: $(COMPONENT_PATH)/logo.bmp + $(summary) BMP2H $@ + $(Q) bmp2h -i $^ -o $@ + + include $(IDF_PATH)/make/component_common.mk + +Fully Overriding The Component Makefile +--------------------------------------- + +Obviously, there are cases where all these recipes are insufficient for a +certain component, for example when the component is basically a wrapper +around another third-party component not originally intended to be +compiled under this build system. In that case, it's possible to forego +the build system entirely by setting COMPONENT_OWNBUILDTARGET and +possibly COMPONENT_OWNCLEANTARGET and defining your own build- and clean +target. The build target can do anything as long as it creates +$(COMPONENT_LIBRARY) for the main file to link into the project binary, +and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable +is set, the component can instruct the linker to do anything else as well. + + +.. _esp-idf-template: https://github.com/espressif/esp-idf-template diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index 07c8c2538..21d83a7f0 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -39,9 +39,9 @@ Project Properties *Windows users only, follow these two additional steps:* -* On the same Environment property page, edit the PATH environment variable and append ``;C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` to the end of the default value. (If you installed msys32 to a different directory then you'll need to change these paths to match.) +* On the same Environment property page, edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match). -* Click on the "C/C++ Build" top-level properties page then uncheck "Use default build command" and enter this for the custom build command: ``bash ${IDF_PATH}/bin/eclipse_windows_make.sh``. +* Click on the "C/C++ Build" top-level properties page then uncheck "Use default build command" and enter this for the custom build command: ``bash ${IDF_PATH}/tools/windows/eclipse_make.sh``. *All users, continue with these steps:* @@ -60,7 +60,7 @@ Flash from Eclipse You can integrate the "make flash" target into your Eclipse project to flash using esptool.py from the Eclipse UI: -* Right-click your project in Project Explorer (important to make sure you don't select a subdirectory of the project or Eclipse may find the wrong Makefile.) +* Right-click your project in Project Explorer (important to make sure you select the project, not a directory in the project, or Eclipse may find the wrong Makefile.) * Select Make Targets -> Create from the context menu. @@ -73,3 +73,8 @@ Note that you will need to use "make menuconfig" to set the serial port and othe Follow the same steps to add ``bootloader`` and ``partition_table`` targets, if necessary. .. _eclipse.org: http://www.eclipse.org/ + +Eclipse Troubleshooting +----------------------- + +* ``*** Make was invoked from ... However please do not run make from the sdk or a component directory; ...`` - Eclipse will detect any directory with a Makefile in it as being a possible directory to run "make" in. All component directories also contain a Makefile (the wrong one), so it is important when using Project -> Make Target to always select the top-level project directory in Project Explorer. diff --git a/make/component.mk b/make/component_common.mk similarity index 100% rename from make/component.mk rename to make/component_common.mk diff --git a/make/project.mk b/make/project.mk index ac2b3e59d..ca80697cb 100644 --- a/make/project.mk +++ b/make/project.mk @@ -1,13 +1,13 @@ # # Main Project Makefile -# This Makefile is included directly from the user project Makefile in order to call the Makefiles of all the -# components (in a separate make process) to build all the libraries, then links them together -# into the final file. If so, PWD is the project dir (we assume). +# This Makefile is included directly from the user project Makefile in order to call the component.mk +# makefiles of all components (in a separate make process) to build all the libraries, then links them +# together into the final file. If so, PWD is the project dir (we assume). # # -# This Makefile requires the environment variable IDF_PATH to be set to the directory where this -# Makefile is located. +# This makefile requires the environment variable IDF_PATH to be set to the top-level esp-idf directory +# where this file is located. # .PHONY: build-components menuconfig defconfig all build clean all_binaries @@ -77,9 +77,9 @@ SRCDIRS ?= main COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),$(firstword $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/$(comp))))) COMPONENT_PATHS += $(abspath $(SRCDIRS)) -#A component is buildable if it has a Makefile; we assume that a 'make -C $(component dir) build' results in a -#lib$(componentname).a. -COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/Makefile),$(cp))) +#A component is buildable if it has a component.mk makefile; we assume that a +# 'make -C $(component dir) -f component.mk build' results in a lib$(componentname).a +COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/component.mk),$(cp))) # Assemble global list of include dirs (COMPONENT_INCLUDES), and # LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component. @@ -98,7 +98,7 @@ COMPONENT_LDFLAGS := # # Debugging this? Replace $(shell with $(error and you'll see the full command as-run. define GetVariable -$(shell "$(MAKE)" -s --no-print-directory -C $(1) get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" ) +$(shell "$(MAKE)" -s --no-print-directory -C $(1) -f component.mk get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" ) endef COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(addprefix $(comp)/, \ @@ -193,7 +193,7 @@ define GenerateComponentPhonyTarget # $(2) - target to generate (build, clean) .PHONY: $(notdir $(1))-$(2) $(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1)) - @+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/Makefile COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) + @+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) endef define GenerateComponentTargets @@ -206,7 +206,7 @@ $(BUILD_DIR_BASE)/$(notdir $(1)): # only invoked for the targets whose libraries appear in COMPONENT_LIBRARIES and hence the # APP_ELF dependencies.) $(BUILD_DIR_BASE)/$(notdir $(1))/lib$(notdir $(1)).a: $(notdir $(1))-build - $(details) echo "$$^ responsible for $$@" # echo which build target built this file + $(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file endef $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component)))) diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 5de216dea..cb42356f0 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -26,9 +26,10 @@ function run_tests() print_status "Checking prerequisites" [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2 - print_status "Cloning template..." + print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..." git clone ${ESP_IDF_TEMPLATE_GIT} template cd template + git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." print_status "Updating template config..." make defconfig || exit $? diff --git a/bin/eclipse_windows_make.sh b/tools/windows/eclipse_make.sh similarity index 92% rename from bin/eclipse_windows_make.sh rename to tools/windows/eclipse_make.sh index 115ecac2f..200d798ff 100755 --- a/bin/eclipse_windows_make.sh +++ b/tools/windows/eclipse_make.sh @@ -5,5 +5,5 @@ # process uses MinGW paths of the form /c/dir/dir/file. So parse these out... # # (regexp deliberate only matches after a space character to try and avoid false-positives.) -echo "Running make in $(dirname $0)" +echo "Running make in $(pwd)" make $@ V=1 | sed -E "s@ /([a-z])/(.+)/@ \1:/\2/@g" | sed -E "s@-I/([a-z])/(.+)/@-I\1:/\2/@g" | sed -E "s@-L/([a-z])/(.+)/@-L\1:/\2/@g"