diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 2f2efcd4e..3faff53d6 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -13,7 +13,6 @@ ifndef IS_BOOTLOADER_BUILD BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin -BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig # signing key path is resolved relative to the project directory SECURE_BOOT_SIGNING_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOT_SIGNING_KEY))) @@ -21,14 +20,12 @@ export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ - V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \ - BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) IS_BOOTLOADER_BUILD=1 - + V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) -$(BOOTLOADER_BIN): | $(BOOTLOADER_BUILD_DIR)/sdkconfig - $(Q) $(BOOTLOADER_MAKE) $@ +$(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE) + $(BOOTLOADER_MAKE) $@ clean: bootloader-clean @@ -110,21 +107,16 @@ bootloader: @exit 1 endif -bootloader-clean: - $(Q) $(BOOTLOADER_MAKE) app-clean config-clean - $(Q) rm -f $(BOOTLOADER_SDKCONFIG) $(BOOTLOADER_SDKCONFIG).old $(SECURE_BOOTLOADER_KEY) $(BOOTLOADER_DIGEST_BIN) - all_binaries: $(BOOTLOADER_BIN) -# synchronise the project level config to the bootloader's -# config -$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR) - $(Q) cp $< $@ +bootloader-clean: + $(BOOTLOADER_MAKE) app-clean + rm -f $(SECURE_BOOTLOADER_KEY) $(BOOTLOADER_DIGEST_BIN) $(BOOTLOADER_BUILD_DIR): - $(Q) mkdir -p $@ + mkdir -p $@ else -CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include +CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include endif diff --git a/components/bootloader/src/Makefile b/components/bootloader/src/Makefile index 1cfc80c5f..bb4e64d0b 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/src/Makefile @@ -4,6 +4,9 @@ # PROJECT_NAME := bootloader + +#We cannot include the esp32 component directly but we need its includes. +#This is fixed by adding CFLAGS from Makefile.projbuild COMPONENTS := esptool_py bootloader bootloader_support log spi_flash micro-ecc # The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included. @@ -12,7 +15,7 @@ COMPONENTS := esptool_py bootloader bootloader_support log spi_flash micro-ecc IS_BOOTLOADER_BUILD := 1 export IS_BOOTLOADER_BUILD -#We cannot include the esp32 component directly but we need its includes. -#This is fixed by adding CFLAGS from Makefile.projbuild +# include the top-level "project" include directory, for sdkconfig.h +CFLAGS += -I$(BUILD_DIR_BASE)/../include include $(IDF_PATH)/make/project.mk diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 8c8ea4cb6..01b07b949 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -1,12 +1,9 @@ # -# Main Makefile. This is basically the same as a component makefile. +# Main bootloader Makefile. # -# 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. +# This is basically the same as a component makefile, but in the case of the bootloader +# we pull in bootloader-specific linker arguments. # -COMPONENT_ADD_LDFLAGS := -L $(abspath .) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld +COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld -include $(IDF_PATH)/make/component_common.mk diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk index e68949d82..a7e5b849d 100755 --- a/components/bootloader_support/component.mk +++ b/components/bootloader_support/component.mk @@ -1,9 +1,6 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include_priv -# include configuration macros early -include $(IDF_PATH)/make/common.mk - ifdef IS_BOOTLOADER_BUILD # share "private" headers with the bootloader component # eventual goal: all functionality that needs this lives in bootloader_support @@ -36,5 +33,3 @@ COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY) COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY) endif - -include $(IDF_PATH)/make/component_common.mk diff --git a/components/bt/component.mk b/components/bt/component.mk index e88651aa1..91620ddc1 100644 --- a/components/bt/component.mk +++ b/components/bt/component.mk @@ -2,20 +2,16 @@ # Component Makefile # -#COMPONENT_ADD_INCLUDEDIRS := - COMPONENT_ADD_INCLUDEDIRS := include CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses LIBS := btdm_app -COMPONENT_ADD_LDFLAGS := -lbt -L$(abspath lib) \ +COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/lib \ $(addprefix -l,$(LIBS)) \ $(LINKER_SCRIPTS) -include $(IDF_PATH)/make/component_common.mk - ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS)) $(COMPONENT_LIBRARY): $(ALL_LIB_FILES) diff --git a/components/driver/component.mk b/components/driver/component.mk index a19b131ef..a208f6ae2 100644 --- a/components/driver/component.mk +++ b/components/driver/component.mk @@ -1,14 +1,8 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component.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 SDK documents if you need to do this. -# COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include/driver -include $(IDF_PATH)/make/component_common.mk diff --git a/components/esp32/component.mk b/components/esp32/component.mk index c658787d8..3866d3e4b 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -1,12 +1,6 @@ # # Component Makefile # -# 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. -# --include include/config/auto.conf COMPONENT_SRCDIRS := . hwcrypto @@ -15,14 +9,12 @@ LIBS := core net80211 phy rtc pp wpa smartconfig coexist LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld COMPONENT_ADD_LDFLAGS := -lesp32 \ - $(abspath libhal.a) \ - -L$(abspath lib) \ + $(COMPONENT_PATH)/libhal.a \ + -L$(COMPONENT_PATH)/lib \ $(addprefix -l,$(LIBS)) \ - -L $(abspath ld) \ + -L $(COMPONENT_PATH)/ld \ $(LINKER_SCRIPTS) -include $(IDF_PATH)/make/component_common.mk - ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS)) # automatically trigger a git submodule update @@ -44,8 +36,6 @@ $(COMPONENT_LIBRARY): $(ALL_LIB_FILES) # saves us from having to add the target to a Makefile.projbuild $(COMPONENT_LIBRARY): esp32_out.ld -# .. is BUILD_DIR_BASE here, as component makefiles -# are evaluated with CWD=component build dir esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h $(CC) -I ../include -C -P -x c -E $< -o $@ diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index bfbece45e..aa3bb2bfa 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -34,24 +34,24 @@ ifndef IS_BOOTLOADER_BUILD APP_BIN_UNSIGNED := $(APP_BIN:.bin=-unsigned.bin) $(APP_BIN): $(APP_BIN_UNSIGNED) - $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $^ # signed in-place + $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $^ # signed in-place endif endif # non-secure boot (or bootloader), both these files are the same APP_BIN_UNSIGNED ?= $(APP_BIN) $(APP_BIN_UNSIGNED): $(APP_ELF) $(ESPTOOLPY_SRC) - $(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< + $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< flash: all_binaries $(ESPTOOLPY_SRC) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." ifdef CONFIG_SECURE_BOOTLOADER_ENABLED @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" endif - $(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) + $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) @echo "Flashing app to serial port $(ESPPORT), offset $(CONFIG_APP_OFFSET)..." - $(Q) $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) + $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) $(eval $(call SubmoduleCheck,$(ESPTOOLPY_SRC),$(COMPONENT_PATH)/esptool)) diff --git a/components/expat/component.mk b/components/expat/component.mk index 907b358a8..0ee1199d1 100644 --- a/components/expat/component.mk +++ b/components/expat/component.mk @@ -1,15 +1,9 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. 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 SDK documents if you need to do this. -# COMPONENT_ADD_INCLUDEDIRS := port/include include/expat COMPONENT_SRCDIRS := library port CFLAGS += -Wno-unused-function -DHAVE_EXPAT_CONFIG_H -include $(IDF_PATH)/make/component_common.mk diff --git a/components/freertos/component.mk b/components/freertos/component.mk index 6702d1b95..0240ea235 100644 --- a/components/freertos/component.mk +++ b/components/freertos/component.mk @@ -6,4 +6,3 @@ COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) -Wl,--undefined=uxTopUsedPriority COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include/freertos -include $(IDF_PATH)/make/component_common.mk diff --git a/components/json/component.mk b/components/json/component.mk index 311a902f9..2dd6ea8b8 100644 --- a/components/json/component.mk +++ b/components/json/component.mk @@ -1,13 +1,7 @@ # # Component Makefile # -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. 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 SDK documents if you need to do this. -# COMPONENT_ADD_INCLUDEDIRS := include port/include COMPONENT_SRCDIRS := library port -include $(IDF_PATH)/make/component_common.mk diff --git a/components/log/component.mk b/components/log/component.mk index ef497a7ec..c2c4c03a1 100755 --- a/components/log/component.mk +++ b/components/log/component.mk @@ -1,3 +1,5 @@ -COMPONENT_ADD_INCLUDEDIRS := include +# +# Component Makefile +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/components/lwip/component.mk b/components/lwip/component.mk index 5d1502004..49fc644ae 100644 --- a/components/lwip/component.mk +++ b/components/lwip/component.mk @@ -8,4 +8,3 @@ COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/free CFLAGS += -Wno-address -Wno-unused-variable -Wno-unused-but-set-variable -include $(IDF_PATH)/make/component_common.mk diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index 98838d4d7..bd7209a92 100644 --- a/components/mbedtls/component.mk +++ b/components/mbedtls/component.mk @@ -6,4 +6,3 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include COMPONENT_SRCDIRS := library port -include $(IDF_PATH)/make/component_common.mk diff --git a/components/micro-ecc/component.mk b/components/micro-ecc/component.mk index df29f400d..df73f7a3b 100644 --- a/components/micro-ecc/component.mk +++ b/components/micro-ecc/component.mk @@ -4,5 +4,3 @@ COMPONENT_SRCDIRS := micro-ecc COMPONENT_OBJS := micro-ecc/uECC.o COMPONENT_ADD_INCLUDEDIRS := micro-ecc - -include $(IDF_PATH)/make/component_common.mk diff --git a/components/newlib/component.mk b/components/newlib/component.mk index 3731b5ef0..4f567242b 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -1,5 +1,4 @@ -COMPONENT_ADD_LDFLAGS := $(abspath lib/libc.a) $(abspath lib/libm.a) -lnewlib +COMPONENT_ADD_LDFLAGS := $(COMPONENT_PATH)/lib/libc.a $(COMPONENT_PATH)/lib/libm.a -lnewlib COMPONENT_ADD_INCLUDEDIRS := include platform_include -include $(IDF_PATH)/make/component_common.mk diff --git a/components/nghttp/component.mk b/components/nghttp/component.mk index a4dca5cf7..d2cd0455f 100644 --- a/components/nghttp/component.mk +++ b/components/nghttp/component.mk @@ -5,5 +5,3 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include COMPONENT_SRCDIRS := library port - -include $(IDF_PATH)/make/component_common.mk \ No newline at end of file diff --git a/components/nvs_flash/component.mk b/components/nvs_flash/component.mk index 02ff8cf03..a905ca689 100755 --- a/components/nvs_flash/component.mk +++ b/components/nvs_flash/component.mk @@ -6,4 +6,3 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_SRCDIRS := src -include $(IDF_PATH)/make/component_common.mk diff --git a/components/openssl/component.mk b/components/openssl/component.mk index 2dfcc6b38..be40549d2 100644 --- a/components/openssl/component.mk +++ b/components/openssl/component.mk @@ -7,4 +7,3 @@ COMPONENT_PRIV_INCLUDEDIRS := include/internal include/platform include/openssl COMPONENT_SRCDIRS := library platform -include $(IDF_PATH)/make/component_common.mk diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index f8b822ef2..5bd13f766 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -32,7 +32,7 @@ endif $(PARTITION_TABLE_BIN_UNSIGNED): $(PARTITION_TABLE_CSV_PATH) $(SDKCONFIG_MAKEFILE) @echo "Building partitions from $(PARTITION_TABLE_CSV_PATH)..." - $(Q) $(GEN_ESP32PART) $< $@ + $(GEN_ESP32PART) $< $@ all_binaries: $(PARTITION_TABLE_BIN) @@ -42,16 +42,16 @@ ESPTOOL_ALL_FLASH_ARGS += $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_BIN) partition_table: $(PARTITION_TABLE_BIN) @echo "Partition table binary generated. Contents:" @echo $(SEPARATOR) - $(Q) $(GEN_ESP32PART) $< + $(GEN_ESP32PART) $< @echo $(SEPARATOR) @echo "Partition flashing command:" @echo "$(PARTITION_TABLE_FLASH_CMD)" partition_table-flash: $(PARTITION_TABLE_BIN) @echo "Flashing partition table..." - $(Q) $(PARTITION_TABLE_FLASH_CMD) + $(PARTITION_TABLE_FLASH_CMD) partition_table-clean: - $(Q) rm -f $(PARTITION_TABLE_BIN) + rm -f $(PARTITION_TABLE_BIN) clean: partition_table-clean diff --git a/components/spi_flash/component.mk b/components/spi_flash/component.mk index 459da0641..d511eedb8 100755 --- a/components/spi_flash/component.mk +++ b/components/spi_flash/component.mk @@ -5,4 +5,3 @@ ifdef IS_BOOTLOADER_BUILD COMPONENT_OBJS := spi_flash_rom_patch.o endif -include $(IDF_PATH)/make/component_common.mk diff --git a/components/tcpip_adapter/component.mk b/components/tcpip_adapter/component.mk index a57ae0b12..c2c4c03a1 100755 --- a/components/tcpip_adapter/component.mk +++ b/components/tcpip_adapter/component.mk @@ -1,5 +1,5 @@ # # Component Makefile # +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/components/vfs/component.mk b/components/vfs/component.mk index fccf88db8..c2c4c03a1 100755 --- a/components/vfs/component.mk +++ b/components/vfs/component.mk @@ -1 +1,5 @@ -include $(IDF_PATH)/make/component_common.mk +# +# Component Makefile +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/components/wpa_supplicant/component.mk b/components/wpa_supplicant/component.mk index cb6b06652..b01eb83be 100644 --- a/components/wpa_supplicant/component.mk +++ b/components/wpa_supplicant/component.mk @@ -2,5 +2,3 @@ COMPONENT_ADD_INCLUDEDIRS := include port/include COMPONENT_SRCDIRS := src/crypto CFLAGS += -DEMBEDDED_SUPP -D__ets__ -Wno-strict-aliasing - -include $(IDF_PATH)/make/component_common.mk diff --git a/components/xtensa-debug-module/component.mk b/components/xtensa-debug-module/component.mk index a57ae0b12..308f64f0e 100755 --- a/components/xtensa-debug-module/component.mk +++ b/components/xtensa-debug-module/component.mk @@ -1,5 +1,4 @@ # # Component Makefile # - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/docs/build_system.rst b/docs/build_system.rst index 85ebfe46d..8168cb76e 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -8,262 +8,380 @@ 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. +Using the Build System +====================== + +The esp-idf README file contains a description of how to use the build system to build 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: +An ESP-IDF project can be seen as an amalgamation of a number of components. +For example, for a webserver that shows the current humidity, there could be: - 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 +- A driver for the 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. +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) in additional custom component directories. It then +allows the user to configure the ESP-IDF project using a a text-based +menu system to customize each component. After the components in the +project are configured, the build process will compile the project. -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:: +Concepts +-------- - - myProject/ - build/ +- A "project" is a directory that contains all the files and configuration to build a single "app" (executable), as well as additional supporting output such as a partition table, data/filesystem partitions, and a bootloader. + +- "Project configuration" is held in a single file called sdkconfig in the root directory of the project. This configuration file is modified via ``make menuconfig`` to customise the configuration of the project. A single project contains exactly one project configuration. + +- An "app" is an executable which is built by esp-idf. A single project will usually build two apps - a "project app" (the main executable, ie your custom firmware) and a "bootloader app" (the initial bootloader program which launches the project app). + +- "components" are modular pieces of standalone code which are compiled into static libraries (.a files) and linked into an app. Some are provided by esp-idf itself, others may be sourced from other places. + +Some things are not part of the project: + +- "ESP-IDF" is not part of the project. Instead it is standalone, and linked to the project via the ``IDF_PATH`` environment variable which holds the path of the ``esp-idf`` directory. This allows the IDF framework to be decoupled from your project. + +- The toolchain for compilation is not part of the project. The toolchain should be installed in the system command line PATH, or the path to the toolchain can be set as part of the compiler prefix in the project configuration. + + +Example Project +--------------- + +An example project directory tree might look like this:: + - myProject/ + - Makefile + - sdkconfig - components/ - component1/ - component.mk - Kconfig - src1.c - component2/ - component.mk - Kconfig - src1.c + - include/ + - component2.h - main/ - src1.c - src2.c - - Makefile + - component.mk + - build/ -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. +This example "myProject" contains the following elements: -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. +- A top-level project Makefile. This Makefile set the ``PROJECT_NAME`` variable and (optionally) defines + other project-wide make variables. It includes the core ``$(IDF_PATH)/make/project.mk`` makefile which + implements the rest of the ESP-IDF build system. -Project Makefile variables that can be set by the programmer:: +- "sdkconfig" project configuration file. This file is created/updated when "make menuconfig" runs, and holds configuration for all of the components in the project (including esp-idf itself). The "sdkconfig" file may or may not be added to the source control system of the project. - 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. +- Optional "components" directory contains components that are part of the project. A project does not have to contain custom components of this kind, but it can be useful for structuring reusable code or including third party components that aren't part of ESP-IDF. -Component-specific component.mk variables that can be set by the programmer:: +- "main" directory is a special "pseudo-component" that contains source code for the project itself. "main" is a default name, the Makefile variable ``SRCDIRS`` defaults to this but can be set to look for pseudo-components in other directories. - COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to - the entire project. If an include directory is only needed to compile this - specific component, don't add it here. - 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 the entire project. Defaults to -l$(COMPONENT_NAME). - Add libraries etc in the current directory as $(abspath libwhatever.a) - COMPONENT_EXTRA_INCLUDES: Any extra include paths used when compiling the component's - source files. These will be prefixed with '-I' and passed to the compiler. - Similar to COMPONENT_PRIV_INCLUDEDIRS, but these paths are passed as-is instead of - expanded relative to the component directory. - 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). +- "build" directory is where build output is created. After the make process is run, this directory will contain interim object files and libraries as well as final binary output files. This directory is usually not added to source control or distributed with the project source code. -These variables are already set early on in the Makefile and the values in it will -be usable in component or project Makefiles:: +Component directories contain a component makefile - ``component.mk``. This may contain variable definitions +to control the build process of the component, and its integration into the overall project. See `Component Makefiles` for more details. - 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. +Each component may also include a ``Kconfig`` file defining the `component configuration` options that can be set via the project configuration. Some components may also include ``Kconfig.projbuild`` and ``Makefile.projbuild`` files, which are special files for `overriding parts of the project`. -Inside your component's component.mk makefile, you can override or add to these variables -as necessary. The changes are isolated from other components (see Makefile.projbuild below -if you want to share these changes with all other components.) +Project Makefiles +----------------- -For components, there also are these defines:: +Each project has a single Makefile that contains build settings for the entire project. By default, the project Makefile can be quite minimal. - 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 +Minimal Example Makefile +^^^^^^^^^^^^^^^^^^^^^^^^ -Make Process ------------- +:: + PROJECT_NAME := myProject + + include $(IDF_PATH)/make/project.mk -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. +Mandatory Project Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -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. +- ``PROJECT_NAME``: Name of the project. Binary output files will use this name - ie myProject.bin, myProject.elf. -KConfig -------- +Optional Project Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^ -Each component can also have a Kconfig file, alongside the component.mk, that contains -details to add to "menuconfig" for this component. +These variables all have default values that can be overridden for custom behaviour. Look in ``make/project.mk`` for all of the implementation details. + +- ``PROJECT_PATH``: Top-level project directory. Defaults to the directory containing the Makefile. Many other project variables are based on this variable. The project path cannot contain spaces. +- ``BUILD_DIR_BASE``: The build directory for all objects/libraries/binaries. Defaults to ``$(PROJECT_PATH)/build``. +- ``COMPONENT_DIRS``: Directories to search for components. Defaults to `$(IDF_PATH)/components`, `$(PROJECT_PATH)/components` and ``EXTRA_COMPONENT_DIRS``. Override this variable if you don't want to search for components in the esp-idf & project ``components`` directories. +- ``EXTRA_COMPONENT_DIRS``: Optional list of additional directories to search for components. Components themselves are in sub-directories of these directories, this is a top-level directory containing the component directories. +- ``COMPONENTS``: A list of component names to build into the project. Defaults to all components found in the COMPONENT_DIRS directories. +- ``SRCDIRS``: Directories under the main project directory which contain project-specific "pseudo-components". Defaults to 'main'. The difference between specifying a directory here and specifying it under ``EXTRA_COMPONENT_DIRS`` is that a directory in ``SRCDIRS`` is a component itself (contains a file "component.mk"), whereas a directory in ``EXTRA_COMPONENT_DIRS`` contains component directories which contain a file "component.mk". See the `Example Project` for a concrete case of this. + + +Component Makefiles +------------------- + +Each project contains one or more components, which can either be part of esp-idf or added from other component directories. + +A component is any sub-directory that contains a `component.mk` file.[#f1]_. + +Minimal Component Makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The minimal ``component.mk`` file is an empty file(!). If the file is empty, the default component behaviour is set: +- All source files in the same directory as the makefile (*.c, *.cpp, *.S) will be compiled into the component library +- A sub-directory "include" will be added to the global include search path for all other components. +- The component library will be linked into the project app. + +See `example component makefiles` for more complete component makefile examples. + +Note that there is a different between an empty ``component.mk`` file (which invokes default component build behaviour) and no ``component.mk`` file (which means no default component build behaviour will occur.) It is possible for a component to have no `component.mk` file, if it only contains other files which influence the project configuration or build process. + +.. component variables: + +Preset Component Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following component-specific variables are available for use inside ``component.mk``, but should not be modified: + +- ``COMPONENT_PATH``: The component directory. Evaluates to the absolute path of the directory containing ``component.mk``. The component path cannot contain spaces. +- ``COMPONENT_NAME``: Name of the component. Defaults to the name of the component directory. +- ``COMPONENT_BUILD_DIR``: The component build directory. Evaluates to the absolute path of a directory inside `$(BUILD_DIR_BASE)` where this component's source files are to be built. This is also the Current Working Directory any time the component is being built, so relative paths in make targets, etc. will be relative to this directory. +- ``COMPONENT_LIBRARY``: Name of the static library file (relative to the component build directory) that will be built for this component. Defaults to ``$(COMPONENT_NAME).a``. + +The following variables are set at the project level, but exported for use in the component build: + +- ``PROJECT_NAME``: Name of the project, as set in project Makefile +- ``PROJECT_PATH``: Absolute path of the project directory containing the project Makefile. +- ``COMPONENTS``: Name of all components that are included in this build. +- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in make. All names begin with ``CONFIG_``. +- ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. +- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. + +If you modify any of these variables inside ``component.mk`` then this will not prevent other components from building but it may make your component hard to build and/or debug. + +Optional Project-Wide Component Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following variables can be set inside ``component.mk`` to control build settings across the entire project: + +- ``COMPONENT_ADD_INCLUDEDIRS``: Paths, relative to the component + directory, which will be added to the include search path for + all components in the project. Defaults to ``include`` if not overridden. If an include directory is only needed to compile + this specific component, add it to ``COMPONENT_PRIV_INCLUDEDIRS`` instead. +- ``COMPONENT_ADD_LDFLAGS``: Add linker arguments to the LDFLAGS for + the app executable. Defaults to ``-l$(COMPONENT_NAME)``. If + adding pre-compiled libraries to this directory, add them as + absolute paths - ie $(COMPONENT_PATH)/libwhatever.a +- ``COMPONENT_DEPENDS``: Optional list of component names that should + be compiled before this component. This is not necessary for + link-time dependencies, because all component include directories + are available at all times. It is necessary if one component + generates an include file which you then want to include in another + component. Most components do not need to set this variable. + + +Optional Component-Specific Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following variables can be set inside ``component.mk`` to control the build of that component: + +- ``COMPONENT_PRIV_INCLUDEDIRS``: Directory paths, must be relative to + the component directory, which will be added to the include search + path for this component's source files only. +- ``COMPONENT_EXTRA_INCLUDES``: Any extra include paths used when + compiling the component's source files. These will be prefixed with + '-I' and passed as-is to the compiler. Similar to the + ``COMPONENT_PRIV_INCLUDEDIRS`` variable, except these paths are not + expanded relative to the component directory. +- ``COMPONENT_SRCDIRS``: Directory paths, must be relative to the + component directory, which will be searched for source files (*.cpp, + *.c, *.S). Defaults to '.', ie the component directory + itself. Override this to specify a different list of directories + which contain source files. +- ``COMPONENT_OBJS``: Object files to compile. Default value is a .o + file for each source file that is found in ``COMPONENT_SRCDIRS``. + Overriding this list allows you to exclude source files in + ``COMPONENT_SRCDIRS`` that would otherwise be compiled. See + `Specifying source files` +- ``COMPONENT_EXTRA_CLEAN``: Paths, relative to the component build + directory, of any files that are generated using custom make rules + in the component.mk file and which need to be removed as part of + ``make clean``. See `Source Code Generation` for an example. +- ``COMPONENT_OWNBUILDTARGET`` & `COMPONENT_OWNCLEANTARGET`: These + targets allow you to fully override the default build behaviour for + the component. See `Fully Overriding The Component Makefile` for + more details. +- ``CFLAGS``: Flags passed to the C compiler. A default set of + ``CFLAGS`` is defined based on project settings. Component-specific + additions can be made via ``CFLAGS +=``. It is also possible + (although not recommended) to override this variable completely for + a component. +- ``CPPFLAGS``: Flags passed to the C preprocessor (used for .c, .cpp + and .S files). A default set of ``CPPFLAGS`` is defined based on + project settings. Component-specific additions can be made via + ``CPPFLAGS +=``. It is also possible (although not recommended) to + override this variable completely for a component. +- ``CXXFLAGS``: Flags passed to the C++ compiler. A default set of + ``CXXFLAGS`` is defined based on project + settings. Component-specific additions can be made via ``CXXFLAGS + +=``. It is also possible (although not recommended) to override + this variable completely for a component. + +Component Configuration +----------------------- + +Each component can also have a Kconfig file, alongside ``component.mk``. This contains contains +configuration settings to add to the "make menuconfig" for this component. + +These settings are found under the "Component Settings" menu when menuconfig is run. + +To create a component KConfig file, it is easiest to start with one of the KConfig files distributed with esp-idf. + +For an example, see `Adding conditional configuration`. + +Build Process Internals +----------------------- + +Top Level: Project Makefile +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- "make" is always run from the project directory and the project makefile, typically named Makefile. +- The project makefile sets ``PROJECT_NAME`` and optionally customises other `optional project variables` +- The project makefile includes ``$(IDF_PATH)/make/project.mk`` which contains the project-level Make logic. +- ``project.mk`` fills in default project-level make variables and includes make variables from the project configuration. If the generated makefile containing project configuration is out of date, then it is regenerated (via targets in ``project_config.mk``) and then the make process restarts from the top. +- ``project.mk`` builds a list of components to build, based on the default component directories or a custom list of components set in `optional project variables`. +- Each component can set some `optional project-wide component variables`. These are included via generated makefiles named ``component_project_vars.mk`` - there is one per component. These generated makefiles are included into ``project.mk``. If any are missing or out of date, they are regenerated (via a recursive make call to the component makefile) and then the make process restarts from the top. +- `Makefile.projbuild` files from components are included into the make process, to add extra targets or configuration. +- By default, the project makefile also generates top-level build & clean targets for each component and sets up `app` and `clean` targets to invoke all of these sub-targets. +- In order to compile each component, a recursive make is performed for the component makefile. + +To better understand the project make process, have a read through the ``project.mk`` file itself. + +Second Level: Component Makefiles +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Each call to a component makefile goes via the ``$(IDF_PATH)/make/component_wrapper.mk`` wrapper makefile. +- The ``component_wrapper.mk`` is called with the current directory set to the component build directory, and the ``COMPONENT_MAKEFILE`` variable is set to the absolute path to ``component.mk``. +- ``component_wrapper.mk`` sets default values for all `component variables`, then includes the `component.mk` file which can override or modify these. +- If ``COMPONENT_OWNBUILDTARGET`` and ``COMPONENT_OWNCLEANTARGET`` are not defined, default build and clean targets are created for the component's source files and the prerequisite ``COMPONENT_LIBRARY`` static library file. +- The ``component_project_vars.mk`` file has its own target in ``component_wrapper.mk``, which is evaluated from ``project.mk`` if this file needs to be rebuilt due to changes in the component makefile or the project configuration. + +To better understand the component make process, have a read through the ``component_wrapper.mk`` file and some of the ``component.mk`` files included with esp-idf. + +Debugging The Make Process +-------------------------- + +Some tips for debugging the esp-idf build system: + +- Appending ``V=1`` to the make arguments (or setting it as an environment variable) will cause make to echo all commands executed, and also each directory as it is entered for a sub-make. +- Running ``make -w`` will cause make to echo each directory as it is entered for a sub-make - same as ``V=1`` but without also echoing all commands. +- Running ``make --trace`` (possibly in addition to one of the above arguments) will print out every target as it is built, and the dependency which caused it to be built. +- Running ``make -p`` prints a (very verbose) summary of every generated target in each makefile. + +For more debugging tips and general make information, see the `GNU Make Manual`. + +Overriding Parts of the Project +------------------------------- Makefile.projbuild ------------------- +^^^^^^^^^^^^^^^^^^ -For components that have parts that need to be evaluated in the top-level -project context, you can create a file called Makefile.projbuild in the -component root directory. These files is included into the project's -top-level Makefile. +For components that have build requirements that must be evaluated in the top-level +project make pass, you can create a file called ``Makefile.projbuild`` in the +component directory. This makefile is included when ``project.mk`` is evaluated. For example, if your component needs to add to CFLAGS for the entire project (not just for its own source files) then you can set -``CFLAGS +=`` in Makefile.projbuild. Note that this isn't necessary for -adding include directories to the project, you can set -``COMPONENT_ADD_INCLUDEDIRS`` (see above) in the component.mk. +``CFLAGS +=`` in Makefile.projbuild. +``Makefile.projbuild`` files are used heavily inside esp-idf, for defining project-wide build features such as ``esptool.py`` command line arguments and the ``bootloader`` "special app". + +Note that ``Makefile.projbuild`` isn't necessary for the most common component uses - such as adding include directories to the project, or LDFLAGS to the final linking step. These values can be customised via the ``component.mk`` file itself. See `Optional Project-Wide Component Variables` for details. + +Take care when setting variables or targets in this file. As the values are included into the top-level project makefile pass, they can influence or break functionality across all components! 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. +This is an equivalent to `Makefile.projbuild` for `component configuration` KConfig files. If you want to include +configuration options at the top-level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``component.mk`` file. -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. +Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for `component configuration`. -Writing Component Makefiles +Example 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 . +Because the build environment tries to set reasonable defaults that will work most +of the time, component.mk can be very small or even empty (see `Minimal Component Makefile`). However, overriding `component variables` is usually required for some functionality. -Components can have any name (unique to the project) but the name -cannot contain spaces (esp-idf does not support spaces in paths). - -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. +Here are some more advanced examples of ``component.mk`` makefiles: Adding source directories -========================= +^^^^^^^^^^^^^^^^^^^^^^^^^ -By default, subdirectories are ignored. If your project has sources in subdirectories +By default, sub-directories are ignored. If your project has sources in sub-directories instead of in the root of the component then you can tell that to the build -system by setting COMPONENT_SRCDIRS:: +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 +This will compile all source files in the src1/ and src2/ sub-directories 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 +to circumvent that logic and hard-code 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 + COMPONENT_SRCDIRS := . thing anotherthing +Note that ``COMPONENT_SRCDIRS`` must be set as well. Adding conditional configuration -================================ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The configuration system can be used to conditionally compile some files -dependending on the options selected in ``make menuconfig``: +depending on the options selected in ``make menuconfig``: -Kconfig:: +``Kconfig``:: config FOO_ENABLE_BAR - bool "Enable the BAR feature." - help - This enables the BAR feature of the FOO component. + 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 +``component.mk``:: + COMPONENT_OBJS := foo_a.o foo_b.o + + ifdef CONFIG_FOO_BAR + COMPONENT_OBJS += foo_bar.o foo_bar_interface.o + endif + +See the `GNU Make Manual` for conditional syntax that can be used use in makefiles. 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:: +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 @@ -272,7 +390,6 @@ header file is then included in as C source file called graphics_lib.c:: 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 @@ -280,8 +397,23 @@ 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 +^^^^^^^^^^^^^^^^^^^^^ + +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. + +Adding logo.h to the ``graphics_lib.o`` dependencies causes it to be +generated before ``graphics_lib.c`` is compiled. + +If a a source file in another component included ``logo.h``, then this +component's name would have to be added to the other component's +``COMPONENT_DEPENDS`` list to ensure that the components were built +in-order. + Embedding Binary Data -===================== +^^^^^^^^^^^^^^^^^^^^^ Sometimes you have a file with some binary or text data that you'd like to make available to your component - but you don't want to reformat the file as C source. @@ -302,25 +434,6 @@ The names are generated from the full name of the file, as given in COMPONENT_EM For an example of using this technique, see examples/04_https_request - the certificate file contents are loaded from the text .pem file at compile time. -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 --------------------------------------- @@ -329,12 +442,15 @@ 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 +the esp-idf build system entirely by setting COMPONENT_OWNBUILDTARGET and +possibly COMPONENT_OWNCLEANTARGET and defining your own targets named ``build`` and ``clean`` in ``component.mk`` 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. +$(COMPONENT_LIBRARY) for the project make process to link into the app binary. + +(Actually, even this is not strictly necessary - if the COMPONENT_ADD_LDFLAGS variable +is set then the component can instruct the linker to link other binaries instead.) .. _esp-idf-template: https://github.com/espressif/esp-idf-template +.. _GNU Make Manual: https://www.gnu.org/software/make/manual/make.html +.. _[_f1]: Actually, some components in esp-idf are "pure configuration" components that don't have a component.mk file, only a Makefile.projbuild and/or Kconfig.projbuild file. However, these components are unusual and most components have a component.mk file. diff --git a/examples/01_hello_world/main/component.mk b/examples/01_hello_world/main/component.mk index 24356f23e..4d3b30caf 100644 --- a/examples/01_hello_world/main/component.mk +++ b/examples/01_hello_world/main/component.mk @@ -1,10 +1,5 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_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 documents if you need to do this. -# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -include $(IDF_PATH)/make/component_common.mk diff --git a/examples/02_blink/main/component.mk b/examples/02_blink/main/component.mk index 24356f23e..b4fa72791 100644 --- a/examples/02_blink/main/component.mk +++ b/examples/02_blink/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_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 documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/03_http_request/main/component.mk b/examples/03_http_request/main/component.mk index 24356f23e..b4fa72791 100644 --- a/examples/03_http_request/main/component.mk +++ b/examples/03_http_request/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_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 documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/04_https_request/main/component.mk b/examples/04_https_request/main/component.mk index 7fbfcc55d..f4502c25d 100644 --- a/examples/04_https_request/main/component.mk +++ b/examples/04_https_request/main/component.mk @@ -1,9 +1,10 @@ # # Main Makefile. This is basically the same as a component makefile. # +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) # embed files from the "certs" directory as binary data symbols # in the app COMPONENT_EMBED_TXTFILES := server_root_cert.pem -include $(IDF_PATH)/make/component_common.mk + diff --git a/examples/05_ble_adv/main/component.mk b/examples/05_ble_adv/main/component.mk index 24356f23e..b4fa72791 100644 --- a/examples/05_ble_adv/main/component.mk +++ b/examples/05_ble_adv/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_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 documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/06_sntp/main/component.mk b/examples/06_sntp/main/component.mk index 24356f23e..b4fa72791 100644 --- a/examples/06_sntp/main/component.mk +++ b/examples/06_sntp/main/component.mk @@ -1,10 +1,4 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_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 documents if you need to do this. -# - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/make/build_examples.sh b/make/build_examples.sh index d26486287..a522666a9 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -15,16 +15,15 @@ RESULT=0 set -e for example in ${IDF_PATH}/examples/*; do - [ -f ${example}/Makefile ] || continue - echo "Building ${example} as ${EXAMPLE_NUM}..." - mkdir ${EXAMPLE_NUM} - cp -r ${example} ${EXAMPLE_NUM} - pushd ${EXAMPLE_NUM}/`basename ${example}` - # can't do "make defconfig all" as this will trip menuconfig - # sometimes - make defconfig && make || RESULT=$? - popd - EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) + [ -f ${example}/Makefile ] || continue + echo "Building ${example} as ${EXAMPLE_NUM}..." + mkdir ${EXAMPLE_NUM} + cp -r ${example} ${EXAMPLE_NUM} + pushd ${EXAMPLE_NUM}/`basename ${example}` + # build non-verbose first, only build verbose if there's an error + make defconfig all || (RESULT=$?; make V=1) + popd + EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) done exit $RESULT diff --git a/make/common.mk b/make/common.mk index bec8151b5..6e4fa75ab 100644 --- a/make/common.mk +++ b/make/common.mk @@ -1,13 +1,14 @@ -# Functionality common to both top-level project makefile -# and component makefiles +# Functionality common to both top-level project makefile (project.mk) +# and component makefiles (component_wrapper.mk) # -# Include project config file, if it exists. +# Include project config makefile, if it exists. # -# (Note that we only rebuild auto.conf automatically for some targets, -# see project_config.mk for details.) -SDKCONFIG_MAKEFILE := $(BUILD_DIR_BASE)/include/config/auto.conf +# (Note that we only rebuild this makefile automatically for some +# targets, see project_config.mk for details.) +SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) -include $(SDKCONFIG_MAKEFILE) +export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path #Handling of V=1/VERBOSE=1 flag # @@ -15,13 +16,14 @@ SDKCONFIG_MAKEFILE := $(BUILD_DIR_BASE)/include/config/auto.conf # if V is unset or not 1, $(summary) echoes a summary and $(details) does nothing V ?= $(VERBOSE) ifeq ("$(V)","1") -Q := summary := @true details := @echo else -Q := @ summary := @echo details := @true + +# disable echoing of commands, directory names +MAKEFLAGS += --silent endif # Pseudo-target to check a git submodule has been properly initialised @@ -35,8 +37,8 @@ endif define SubmoduleCheck $(1): @echo "WARNING: Missing submodule $(2) for $$@..." - $(Q) [ -d ${IDF_PATH}/.git ] || ( echo "ERROR: esp-idf must be cloned from git to work."; exit 1) - $(Q) [ -x $(which git) ] || ( echo "ERROR: Need to run 'git submodule --init' in esp-idf root directory."; exit 1) + [ -d ${IDF_PATH}/.git ] || ( echo "ERROR: esp-idf must be cloned from git to work."; exit 1) + [ -x $(which git) ] || ( echo "ERROR: Need to run 'git submodule --init' in esp-idf root directory."; exit 1) @echo "Attempting 'git submodule update --init' in esp-idf root directory..." cd ${IDF_PATH} && git submodule update --init $(2) diff --git a/make/component_common.mk b/make/component_common.mk index 70a6f60f0..187e1ed63 100644 --- a/make/component_common.mk +++ b/make/component_common.mk @@ -1,151 +1 @@ -# Component common makefile -# -# This Makefile gets included in the Makefile of all the components to set the correct include paths etc. -# PWD is the build directory of the component and the top Makefile is the one in the -# component source dir. -# -# The way the Makefile differentiates between those two is by looking at the environment -# variable PROJECT_PATH. If this is set (to the basepath of the project), we're building a -# component and its Makefile has included this makefile. If not, we're building the entire project. -# - -# -# This Makefile requires the environment variable IDF_PATH to be set -# to the top-level directory where ESP-IDF is located (the directory -# containing this 'make' directory). -# - -ifeq ("$(PROJECT_PATH)","") -$(error Make was invoked from $(CURDIR). However please do not run make from the sdk or a component directory; invoke make from the project directory. See the ESP-IDF README for details.) -endif - -# Find the path to the component -COMPONENT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) -export COMPONENT_PATH - -include $(IDF_PATH)/make/common.mk - -#Some of these options are overridable by the component's component.mk Makefile - -#Name of the component -COMPONENT_NAME ?= $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH)))) - -#Absolute path of the .a file -COMPONENT_LIBRARY := lib$(COMPONENT_NAME).a - -#Source dirs a component has. Default to root directory of component. -COMPONENT_SRCDIRS ?= . - -#Names of binary files to embed as symbols in the component library -COMPONENT_EMBED_FILES ?= - -#Object files which need to be added to the library -#By default we take all .c/.S files in the component directory. -ifeq ("$(COMPONENT_OBJS)", "") -#Find all source files in all COMPONENT_SRCDIRS -COMPONENT_OBJS := $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.c,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.c))) -COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cpp))) -COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S))) -#Make relative by removing COMPONENT_PATH from all found object paths -COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS)) -endif - -#Object files with embedded binaries to add to the component library -#Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES -COMPONENT_EMBED_OBJS ?= $(addsuffix .bin.o,$(COMPONENT_EMBED_FILES)) $(addsuffix .txt.o,$(COMPONENT_EMBED_TXTFILES)) - -#By default, include only the include/ dir. -COMPONENT_ADD_INCLUDEDIRS ?= include -COMPONENT_ADD_LDFLAGS ?= -l$(COMPONENT_NAME) - -#If we're called to compile something, we'll get passed the COMPONENT_INCLUDES -#variable with all the include dirs from all the components in random order. This -#means we can accidentally grab a header from another component before grabbing our own. -#To make sure that does not happen, re-order the includes so ours come first. -OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS))) -COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES)) - -#This target is used to collect variable values from inside project.mk -# see project.mk GetVariable macro for details. -get_variable: - @echo "$(GET_VARIABLE)=$(call $(GET_VARIABLE)) " - -#Targets for build/clean. Use builtin recipe if component Makefile -#hasn't defined its own. -ifeq ("$(COMPONENT_OWNBUILDTARGET)", "") -build: $(COMPONENT_LIBRARY) - @mkdir -p $(COMPONENT_SRCDIRS) - -#Build the archive. We remove the archive first, otherwise ar will get confused if we update -#an archive when multiple filenames have the same name (src1/test.o and src2/test.o) -$(COMPONENT_LIBRARY): $(COMPONENT_OBJS) $(COMPONENT_EMBED_OBJS) - $(summary) AR $@ - $(Q) rm -f $@ - $(Q) $(AR) cru $@ $^ -endif - -ifeq ("$(COMPONENT_OWNCLEANTARGET)", "") -clean: - $(summary) RM $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EMBED_OBJS) $(COMPONENT_EXTRA_CLEAN) - $(Q) rm -f $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EMBED_OBJS) $(COMPONENT_EXTRA_CLEAN) -endif - -#Include all dependency files already generated --include $(COMPONENT_OBJS:.o=.d) - -#This pattern is generated for each COMPONENT_SRCDIR to compile the files in it. -define GenerateCompileTargets -# $(1) - directory containing source files, relative to $(COMPONENT_PATH) -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1) - $$(summary) CC $$@ - $$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ - -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1) - $$(summary) CXX $$@ - $$(Q) $$(CXX) $$(CXXFLAGS) $(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ - -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1) - $$(summary) AS $$@ - $$(Q) $$(CC) $$(CFLAGS) $(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ - -endef - -define GenerateBuildDirTarget -# CWD is build dir, create the build subdirectory $(1) if it doesn't exist -$(1): - @mkdir -p $(1) -endef - -#Generate all the compile target recipes & the build directory recipes -$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir))) $(eval $(call GenerateBuildDirTarget,$(srcdir)))) - -## Support for embedding binary files into the ELF as symbols - -OBJCOPY_EMBED_ARGS := --input binary --output elf32-xtensa-le --binary-architecture xtensa --rename-section .data=.rodata.embedded - -# Generate pattern for embedding text or binary files into the app -# $(1) is name of file (as relative path inside component) -# $(2) is txt or bin depending on file contents -# -# txt files are null-terminated before being embedded (otherwise -# identical behaviour.) -# -# Files are temporarily copied to the build directory before objcopy, -# because objcopy generates the symbol name from the full command line -# path to the input file. -define GenerateEmbedTarget -$(1).$(2).o: $(call resolvepath,$(1),$(COMPONENT_PATH)) | $$(dir $(1)) - $$(summary) EMBED $$@ - $$(Q) $(if $(filter-out $$(notdir $$(abspath $$<)),$$(abspath $$(notdir $$<))), cp $$< $$(notdir $$<) ) # copy input file to build dir, unless already in build dir - $$(Q) $(if $(subst bin,,$(2)),echo -ne '\0' >> $$(notdir $$<) ) # trailing NUL byte on text output - $$(Q) $$(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ - $$(Q) rm $$(notdir $$<) -endef - -# generate targets to embed binary & text files -$(foreach binfile,$(COMPONENT_EMBED_FILES), $(eval $(call GenerateEmbedTarget,$(binfile),bin))) - -$(foreach txtfile,$(COMPONENT_EMBED_TXTFILES), $(eval $(call GenerateEmbedTarget,$(txtfile),txt))) - -# generate targets to create binary embed directories -$(foreach bindir,$(sort $(dir $(COMPONENT_EMBED_FILES))), $(eval $(call GenerateBuildDirTarget,$(bindir)))) +$(warning Deprecated feature: No longer necessary to include component_common.mk from $(COMPONENT_PATH)/component.mk) diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk new file mode 100644 index 000000000..55a135158 --- /dev/null +++ b/make/component_wrapper.mk @@ -0,0 +1,209 @@ +# Component wrapper makefile +# +# This makefile gets called recursively from the project make, once for each component. +# COMPONENT_MAKEFILE is set to point at the component.mk file for the component itself, +# which is included as part of this process (after default variables are defined). +# +# This makefile comprises multiple stages, marked in blocked comments below. +# +# CWD is the build directory of the component. + +ifndef PROJECT_PATH +$(error Make was invoked from $(CURDIR). However please do not run make from the sdk or a component directory; invoke make from the project directory. See the ESP-IDF README for details.) +endif + + +################################################################################ +# 1) Set default variables for the component build (including configuration +# loaded from sdkconfig.) +################################################################################ + +# Find the path to the component +COMPONENT_PATH := $(abspath $(dir $(COMPONENT_MAKEFILE))) +export COMPONENT_PATH + +# COMPONENT_BUILD_DIR is otherwise known as CWD for the build +COMPONENT_BUILD_DIR := $(abspath .) + +# include elements common to both project & component makefiles +# (includes project configuration set via menuconfig) +include $(IDF_PATH)/make/common.mk + +# Some of the following defaults may be overriden by the component's component.mk makefile, +# during the next step: + +# Name of the component +COMPONENT_NAME := $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH)))) + +# Absolute path of the .a file +COMPONENT_LIBRARY = lib$(COMPONENT_NAME).a + +# Source dirs a component has. Default to root directory of component. +COMPONENT_SRCDIRS = . + +#Names of binary & text files to embed as raw content in the component library +COMPONENT_EMBED_FILES ?= +COMPONENT_EMBED_TXTFILES ?= + +# By default, include only the include/ dir. +COMPONENT_ADD_INCLUDEDIRS = include +COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) + + +################################################################################ +# 2) Include the component.mk for the specific component (COMPONENT_MAKEFILE) to +# override variables & optionally define custom targets. +################################################################################ + +include $(COMPONENT_MAKEFILE) + + +################################################################################ +# 3) Set variables that depend on values that may changed by component.mk +################################################################################ + +# Object files which need to be linked into the library +# By default we take all .c, .cpp & .S files in COMPONENT_SRCDIRS. +ifndef COMPONENT_OBJS +# Find all source files in all COMPONENT_SRCDIRS +COMPONENT_OBJS := $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.c,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.c))) +COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.cpp))) +COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S))) +# Make relative by removing COMPONENT_PATH from all found object paths +COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS)) +endif + +# Object files with embedded binaries to add to the component library +# Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES +COMPONENT_EMBED_OBJS ?= $(addsuffix .bin.o,$(COMPONENT_EMBED_FILES)) $(addsuffix .txt.o,$(COMPONENT_EMBED_TXTFILES)) + + +# If we're called to compile something, we'll get passed the COMPONENT_INCLUDES +# variable with all the include dirs from all the components in random order. This +# means we can accidentally grab a header from another component before grabbing our own. +# To make sure that does not happen, re-order the includes so ours come first. +OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS))) +COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES)) + + +################################################################################ +# 4) Define a target to generate component_project_vars.mk Makefile which +# contains common per-component settings which are included directly in the +# top-level project make +################################################################################ + +# macro to generate variable-relative paths inside component_project_vars.mk, whenever possible +# ie put literal $(IDF_PATH), $(PROJECT_PATH) and $(BUILD_DIR_BASE) into the generated +# makefiles where possible. +# +# This means if directories move (breaking absolute paths), don't need to 'make clean' +define MakeVariablePath +$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),\$$(BUILD_DIR_BASE),$(1)))) +endef + +# component_project_vars.mk target for the component. This is used to +# take component.mk variables COMPONENT_ADD_INCLUDEDIRS, +# COMPONENT_ADD_LDFLAGS and COMPONENT_DEPENDS and inject those into +# the project make pass. +# +# The target here has no dependencies, as the parent target in +# project.mk evaluates dependencies before calling down to here. See +# GenerateComponentTargets macro in project.mk. +# +# If you are thinking of editing the output of this target for a +# component-specific feature, please don't! What you want is a +# Makefile.projbuild for your component (see docs/build-system.rst for +# more.) +component_project_vars.mk:: + $(details) "Building component project variables list $(abspath $@)" + @echo '# Automatically generated build file. Do not edit.' > $@ + @echo 'COMPONENT_INCLUDES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS)))' >> $@ + @echo 'COMPONENT_LDFLAGS += $(call MakeVariablePath,$(COMPONENT_ADD_LDFLAGS))' >> $@ + @echo '$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))' >> $@ + + +################################################################################ +# 5) If COMPONENT_OWNBUILDTARGET / COMPONENT_OWNCLEANTARGET is not set by component.mk, +# define default build, clean, etc. targets +################################################################################ + +# If COMPONENT_OWNBUILDTARGET is not set, define a phony build target and +# a COMPONENT_LIBRARY link target. +ifndef COMPONENT_OWNBUILDTARGET +.PHONY: build +build: $(COMPONENT_LIBRARY) + @mkdir -p $(COMPONENT_SRCDIRS) + +# Build the archive. We remove the archive first, otherwise ar will get confused if we update +# an archive when multiple filenames have the same name (src1/test.o and src2/test.o) +$(COMPONENT_LIBRARY): $(COMPONENT_OBJS) $(COMPONENT_EMBED_OBJS) + $(summary) AR $@ + rm -f $@ + $(AR) cru $@ $^ +endif + +# If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target +ifndef COMPONENT_OWNCLEANTARGET +CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EMBED_OBJS) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk +.PHONY: clean +clean: + $(summary) RM $(CLEAN_FILES) + rm -f $(CLEAN_FILES) +endif + +# Include all dependency files already generated +-include $(COMPONENT_OBJS:.o=.d) + +# This pattern is generated for each COMPONENT_SRCDIR to compile the files in it. +define GenerateCompileTargets +# $(1) - directory containing source files, relative to $(COMPONENT_PATH) +$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1) + $$(summary) CC $$@ + $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + +$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1) + $$(summary) CXX $$@ + $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + +$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1) + $$(summary) AS $$@ + $$(CC) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + +# CWD is build dir, create the build subdirectory if it doesn't exist +$(1): + @mkdir -p $(1) +endef + +# Generate all the compile target patterns +$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir)))) + +## Support for embedding binary files into the ELF as symbols + +OBJCOPY_EMBED_ARGS := --input binary --output elf32-xtensa-le --binary-architecture xtensa --rename-section .data=.rodata.embedded + +# Generate pattern for embedding text or binary files into the app +# $(1) is name of file (as relative path inside component) +# $(2) is txt or bin depending on file contents +# +# txt files are null-terminated before being embedded (otherwise +# identical behaviour.) +# +# Files are temporarily copied to the build directory before objcopy, +# because objcopy generates the symbol name from the full command line +# path to the input file. +define GenerateEmbedTarget +$(1).$(2).o: $(call resolvepath,$(1),$(COMPONENT_PATH)) | $$(dir $(1)) + $(summary) EMBED $$@ + $$(if $$(filter-out $$(notdir $$(abspath $$<)),$$(abspath $$(notdir $$<))), cp $$< $$(notdir $$<) ) # copy input file to build dir, unless already in build dir + $$(if $$(subst bin,,$(2)),echo -ne '\0' >> $$(notdir $$<) ) # trailing NUL byte on text output + $(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ + rm $$(notdir $$<) +endef + +# generate targets to embed binary & text files +$(foreach binfile,$(COMPONENT_EMBED_FILES), $(eval $(call GenerateEmbedTarget,$(binfile),bin))) + +$(foreach txtfile,$(COMPONENT_EMBED_TXTFILES), $(eval $(call GenerateEmbedTarget,$(txtfile),txt))) + +# generate targets to create binary embed directories +$(foreach bindir,$(sort $(dir $(COMPONENT_EMBED_FILES))), $(eval $(call GenerateBuildDirTarget,$(bindir)))) diff --git a/make/project.mk b/make/project.mk index 1765a157e..08c7dd89a 100644 --- a/make/project.mk +++ b/make/project.mk @@ -36,104 +36,92 @@ help: @echo "See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean', " @echo "'make partition_table', etc, etc." +# dependency checks +ifndef MAKE_RESTARTS +ifeq ("$(filter 4.% 3.81 3.82,$(MAKE_VERSION))","") +$(warning "esp-idf build system only supports GNU Make versions 3.81 or newer. You may see unexpected results with other Makes.") +endif +endif + # disable built-in make rules, makes debugging saner MAKEFLAGS_OLD := $(MAKEFLAGS) MAKEFLAGS +=-rR -# Figure out PROJECT_PATH if not set -ifeq ("$(PROJECT_PATH)","") -#The path to the project: we assume the Makefile including this file resides -#in the root of that directory. +# Default path to the project: we assume the Makefile including this file +# is in the project directory +ifndef PROJECT_PATH PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) export PROJECT_PATH endif -#The directory where we put all objects/libraries/binaries. The project Makefile can -#configure this if needed. +# A list of the "common" makefiles, to use as a target dependency +COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/component_wrapper.mk) +export COMMON_MAKEFILES + +# The directory where we put all objects/libraries/binaries. The project Makefile can +# configure this if needed. BUILD_DIR_BASE ?= $(PROJECT_PATH)/build export BUILD_DIR_BASE -#Component directories. These directories are searched for components. -#The project Makefile can override these component dirs, or define extra component directories. +# Component directories. These directories are searched for components. +# The project Makefile can override these component dirs, or define extra component directories. COMPONENT_DIRS ?= $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components export COMPONENT_DIRS -#The project Makefile can define a list of components, but if it does not do this we just take -#all available components in the component dirs. -ifeq ("$(COMPONENTS)","") -#Find all component names. The component names are the same as the -#directories they're in, so /bla/components/mycomponent/ -> mycomponent. We later use -#the COMPONENT_DIRS bit to find back the component path. +# Source directories of the project itself (a special, project-specific component.) Defaults to only "main". +SRCDIRS ?= main + +# The project Makefile can define a list of components, but if it does not do this we just take +# all available components in the component dirs. +ifndef COMPONENTS +# Find all component names. The component names are the same as the +# directories they're in, so /bla/components/mycomponent/ -> mycomponent. We then use +# COMPONENT_DIRS to build COMPONENT_PATHS with the full path to each component. COMPONENTS := $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/*)) COMPONENTS := $(sort $(foreach comp,$(COMPONENTS),$(lastword $(subst /, ,$(comp))))) endif export COMPONENTS -#Sources default to only "main" -SRCDIRS ?= main - -#Here, we resolve and add all the components and source paths into absolute paths. -#If a component exists in multiple COMPONENT_DIRS, we take the first match. -#WARNING: These directories paths must be generated WITHOUT a trailing / so we -#can use $(notdir x) to get the component name. +# Resolve all of COMPONENTS into absolute paths in COMPONENT_PATHS. +# +# If a component name exists in multiple COMPONENT_DIRS, we take the first match. +# +# NOTE: These paths must be generated WITHOUT a trailing / so we +# can use $(notdir x) to get the component name. 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 component.mk makefile; we assume that a -# 'make -C $(component dir) -f component.mk build' results in a lib$(componentname).a +# A component is buildable if it has a component.mk makefile in it 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. +# Initialise a project-wide list of include dirs (COMPONENT_INCLUDES), +# and LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component. +# +# These variables are built up via the component_project_vars.mk +# generated makefiles (one per component). COMPONENT_INCLUDES := COMPONENT_LDFLAGS := -# -# Also add any inter-component dependencies for each component. -# Extract a variable from a child make process +# COMPONENT_PROJECT_VARS is the list of component_project_vars.mk generated makefiles +# for each component. # -# $(1) - path to directory to invoke make in -# $(2) - name of variable to print via the get_variable target (passed in GET_VARIABLE) +# Including $(COMPONENT_PROJECT_VARS) builds the COMPONENT_INCLUDES, +# COMPONENT_LDFLAGS variables and also targets for any inter-component +# dependencies. # -# needs 'sed' processing of stdout because make sometimes echoes other stuff on stdout, -# even if asked not to. -# -# 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) -f component.mk get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) IS_BOOTLOADER_BUILD=$(IS_BOOTLOADER_BUILD) | sed -En "s/^$(2)=(.+)/\1/p" ) -endef +# See the component_project_vars.mk target in component_wrapper.mk +COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE))) +COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) +# this line is -include instead of include to prevent a spurious error message on make 3.81 +-include $(COMPONENT_PROJECT_VARS) -COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(addprefix $(comp)/, \ - $(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS)))) - -#Also add project include path, for sdk includes +# Also add top-level project include path, for top-level includes COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) + export COMPONENT_INCLUDES -#COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected -#in the same way as COMPONENT_INCLUDES is. -COMPONENT_LDFLAGS := $(foreach comp,$(COMPONENT_PATHS_BUILDABLE), \ - $(call GetVariable,$(comp),COMPONENT_ADD_LDFLAGS)) -export COMPONENT_LDFLAGS - -# Generate component dependency targets from dependencies lists -# each component gains a target of its own -build with dependencies -# of the names of any other components (-build) that need building first -# -# the actual targets (that invoke submakes) are generated below by -# GenerateComponentTarget macro. -define GenerateComponentDependencies -# $(1) = component path -.PHONY: $$(notdir $(1)) -$$(notdir $(1))-build: $(addsuffix -build,$(call GetVariable,$(1),COMPONENT_DEPENDS)) -endef -$(foreach comp,$(COMPONENT_PATHS_BUILDABLE), $(eval $(call GenerateComponentDependencies,$(comp)))) - -#Make sure submakes can also use this. -export PROJECT_PATH - -#Include functionality common to both project & component --include $(IDF_PATH)/make/common.mk +# Set variables common to both project & component +include $(IDF_PATH)/make/common.mk all: ifdef CONFIG_SECURE_BOOTLOADER_ENABLED @@ -220,15 +208,15 @@ CXXFLAGS := $(strip \ export CFLAGS CPPFLAGS CXXFLAGS -#Set host compiler and binutils +# Set host compiler and binutils HOSTCC := $(CC) HOSTLD := $(LD) HOSTAR := $(AR) HOSTOBJCOPY := $(OBJCOPY) export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY -#Set target compiler. Defaults to whatever the user has -#configured as prefix + yer olde gcc commands +# Set target compiler. Defaults to whatever the user has +# configured as prefix + ye olde gcc commands CC := $(call dequote,$(CONFIG_TOOLPREFIX))gcc CXX := $(call dequote,$(CONFIG_TOOLPREFIX))c++ LD := $(call dequote,$(CONFIG_TOOLPREFIX))ld @@ -252,8 +240,12 @@ COMPONENT_PATH := $(1) endef $(foreach componentpath,$(COMPONENT_PATHS),$(eval $(call includeProjBuildMakefile,$(componentpath)))) -# once we know component paths, we can include the config +# once we know component paths, we can include the config generation targets +# +# (bootloader build doesn't need this, config is exported from top-level) +ifndef IS_BOOTLOADER_BUILD include $(IDF_PATH)/make/project_config.mk +endif # A "component" library is any library in the LDFLAGS where # the name of the library is also a name of the component @@ -264,7 +256,7 @@ COMPONENT_LIBRARIES = $(filter $(notdir $(COMPONENT_PATHS_BUILDABLE)),$(APP_LIBR # the rules to build these are emitted as part of GenerateComponentTarget below $(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(summary) LD $(notdir $@) - $(Q) $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) + $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) # Generation of $(APP_BIN) from $(APP_ELF) is added by the esptool # component's Makefile.projbuild @@ -277,35 +269,59 @@ all_binaries: $(APP_BIN) $(BUILD_DIR_BASE): mkdir -p $(BUILD_DIR_BASE) -define GenerateComponentPhonyTarget -# $(1) - path to component dir -# $(2) - target to generate (build, clean) -.PHONY: $(notdir $(1))-$(2) -$(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1)) - $(Q) +$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2) +# Macro for the recursive sub-make for each component +# $(1) - component directory +# $(2) - component name only +# +# Is recursively expanded by the GenerateComponentTargets macro +define ComponentMake ++$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk endef -define GenerateComponentTargets +# Generate top-level component-specific targets for each component # $(1) - path to component dir -$(BUILD_DIR_BASE)/$(notdir $(1)): - @mkdir -p $(BUILD_DIR_BASE)/$(notdir $(1)) +# $(2) - name of component +# +define GenerateComponentTargets +.PHONY: $(2)-build $(2)-clean -# tell make it can build any component's library by invoking the recursive -build target +$(2)-build: + $(call ComponentMake,$(1),$(2)) build + +$(2)-clean: + $(call ComponentMake,$(1),$(2)) clean + +$(BUILD_DIR_BASE)/$(2): + @mkdir -p $(BUILD_DIR_BASE)/$(2) + +# tell make it can build any component's library by invoking the -build target # (this target exists for all components even ones which don't build libraries, but it's # 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 +$(BUILD_DIR_BASE)/$(2)/lib$(2).a: $(2)-build $(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file + +# add a target to generate the component_project_vars.mk files that +# are used to inject variables into project make pass (see matching +# component_project_vars.mk target in component_wrapper.mk). +# +# If any component_project_vars.mk file is out of date, the make +# process will call this target to rebuild it and then restart. +# +# Note: $(SDKCONFIG) is a normal prereq as we need to rebuild these +# files whenever the config changes. $(SDKCONFIG_MAKEFILE) is an +# order-only prereq because if it hasn't been rebuilt, we need to +# build it first - but including it as a normal prereq can lead to +# infinite restarts as the conf process will keep updating it. +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) $(SDKCONFIG_MAKEFILE) + $(call ComponentMake,$(1),$(2)) component_project_vars.mk endef -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component)))) - -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),build))) -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentPhonyTarget,$(component),clean))) +$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) - $(Q) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) + rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) # NB: this ordering is deliberate (app-clean before config-clean), # so config remains valid during all component clean targets diff --git a/make/project_config.mk b/make/project_config.mk index 56a05090b..a32c74a38 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -21,24 +21,28 @@ KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfi COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" -menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) +menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(summary) MENUCONFIG - $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig + $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig ifeq ("$(wildcard $(SDKCONFIG))","") -#No sdkconfig found. Need to run menuconfig to make this if we need it. +ifeq ("$(filter defconfig,$(MAKECMDGOALS))","") +# if not configuration is present and defconfig is not a target, run makeconfig $(SDKCONFIG): menuconfig +else +$(SDKCONFIG): defconfig +endif endif defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) $(summary) DEFCONFIG - $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config - $(Q) $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + mkdir -p $(BUILD_DIR_BASE)/include/config + $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig # Work out of whether we have to build the Kconfig makefile # (auto.conf), or if we're in a situation where we don't need it -NON_CONFIG_TARGETS := clean %-clean get_variable help menuconfig defconfig -AUTO_CONF_REGEN_TARGET := $(BUILD_DIR_BASE)/include/config/auto.conf +NON_CONFIG_TARGETS := clean %-clean help menuconfig defconfig +AUTO_CONF_REGEN_TARGET := $(SDKCONFIG_MAKEFILE) # disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets # (and not building default target) @@ -46,15 +50,15 @@ ifneq ("$(MAKECMDGOALS)","") ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS)) AUTO_CONF_REGEN_TARGET := # dummy target -$(BUILD_DIR_BASE)/include/config/auto.conf: +$(SDKCONFIG_MAKEFILE): endif endif $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG - $(Q) mkdir -p $(BUILD_DIR_BASE)/include/config - $(Q) cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - $(Q) touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h + mkdir -p $(BUILD_DIR_BASE)/include/config + cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig + touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h # touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) @@ -63,4 +67,4 @@ $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $( config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean - $(Q) rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h + rm -rf $(BUILD_DIR_BASE)/include/config $(BUILD_DIR_BASE)/include/sdkconfig.h diff --git a/tools/kconfig/Makefile b/tools/kconfig/Makefile index fee5a6931..9680b7410 100644 --- a/tools/kconfig/Makefile +++ b/tools/kconfig/Makefile @@ -41,13 +41,13 @@ nconfig: nconf $< $(silent) $(Kconfig) silentoldconfig: conf - $(Q)mkdir -p include/config include/generated + mkdir -p include/config include/generated $< $(silent) --$@ $(Kconfig) localyesconfig localmodconfig: streamline_config.pl conf - $(Q)mkdir -p include/config include/generated - $(Q)perl $< --$@ . $(Kconfig) > .tmp.config - $(Q)if [ -f .config ]; then \ + mkdir -p include/config include/generated + perl $< --$@ . $(Kconfig) > .tmp.config + if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ mv -f .tmp.config .config; \ @@ -57,7 +57,7 @@ localyesconfig localmodconfig: streamline_config.pl conf mv -f .tmp.config .config; \ conf $(silent) --silentoldconfig $(Kconfig); \ fi - $(Q)rm -f .tmp.config + rm -f .tmp.config # These targets map 1:1 to the commandline options of 'conf' @@ -84,22 +84,22 @@ ifeq ($(KBUILD_DEFCONFIG),) else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" - $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + $< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) else @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" - $(Q) $(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) + $(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) endif endif %_defconfig: conf - $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + $< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) %.config: conf $(if $(call configfiles),, $(error No configuration exists for this target on this architecture)) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) - +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig + $(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) + +yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig PHONY += kvmconfig kvmconfig: kvm_guest.config @@ -111,7 +111,7 @@ xenconfig: xen.config PHONY += tinyconfig tinyconfig: - $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config + $(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config # Help text used by make help help: @@ -181,7 +181,7 @@ clean-files += $(conf-objs) $(mconf-objs) conf mconf $(lxdialog) PHONY += dochecklxdialog $(addprefix ,$(lxdialog)): dochecklxdialog dochecklxdialog: - $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(CC) $(CFLAGS) $(LOADLIBES_mconf) + $(CONFIG_SHELL) $(check-lxdialog) -check $(CC) $(CFLAGS) $(LOADLIBES_mconf) always := dochecklxdialog @@ -285,7 +285,7 @@ quiet_cmd_moc = MOC $@ # Extract gconf menu items for i18n support gconf.glade.h: gconf.glade - $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ + intltool-extract --type=gettext/glade --srcdir=$(srctree) \ gconf.glade