From d664e32394c3feac5b043c86d3e126ebf71b9310 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 23 Jun 2017 14:08:01 +1000 Subject: [PATCH] build system: Use component.mk for all components, refactor bootloader build For config-only components, component.mk should now contain "COMPONENT_CONFIG_ONLY := 1" Also refactored some of the generation of linker paths, library list. This required cleaning up the way the bootloader project works, it's now mostly independent from the parent. --- components/bootloader/Makefile.projbuild | 45 +++++++------- components/bootloader/component.mk | 7 +++ .../bootloader/{src => subproject}/.gitignore | 0 .../bootloader/{src => subproject}/Makefile | 11 +++- .../main/Makefile.projbuild | 0 .../main/bootloader_config.h | 0 .../main/bootloader_start.c | 0 .../{src => subproject}/main/component.mk | 2 +- .../main/esp32.bootloader.ld | 0 .../main/esp32.bootloader.rom.ld | 0 .../{src => subproject}/main/flash_qio_mode.c | 0 .../{src => subproject}/main/flash_qio_mode.h | 0 components/cxx/component.mk | 2 +- components/esp32/component.mk | 3 +- components/esptool_py/component.mk | 5 ++ components/freertos/component.mk | 2 +- components/newlib/component.mk | 2 +- components/partition_table/Makefile.projbuild | 9 ++- components/partition_table/component.mk | 5 ++ docs/api-guides/build-system.rst | 28 +++++++-- make/component_wrapper.mk | 35 ++++++++--- make/project.mk | 59 ++++++++----------- tools/ci/test_build_system.sh | 2 +- 23 files changed, 139 insertions(+), 78 deletions(-) create mode 100644 components/bootloader/component.mk rename components/bootloader/{src => subproject}/.gitignore (100%) rename components/bootloader/{src => subproject}/Makefile (62%) rename components/bootloader/{src => subproject}/main/Makefile.projbuild (100%) rename components/bootloader/{src => subproject}/main/bootloader_config.h (100%) rename components/bootloader/{src => subproject}/main/bootloader_start.c (100%) rename components/bootloader/{src => subproject}/main/component.mk (85%) rename components/bootloader/{src => subproject}/main/esp32.bootloader.ld (100%) rename components/bootloader/{src => subproject}/main/esp32.bootloader.rom.ld (100%) rename components/bootloader/{src => subproject}/main/flash_qio_mode.c (100%) rename components/bootloader/{src => subproject}/main/flash_qio_mode.h (100%) create mode 100644 components/esptool_py/component.mk create mode 100644 components/partition_table/component.mk diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index be3ec5f88f..a8c10067b5 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -1,15 +1,13 @@ -# -# Bootloader component +# Bootloader component (top-level project parts) # # The bootloader is not a real component that gets linked into the project. -# Instead it is an entire standalone project ( in src/) that gets built in -# the upper projects build directory. This Makefile.projbuild provides the -# glue to build the bootloader project from the original project. It -# basically runs Make in the src/ directory but it needs to zero some variables -# the ESP-IDF project.mk makefile exports first, to not let them interfere. +# Instead it is an entire standalone project (in subproject/) that gets +# built in the upper project's build directory. This Makefile.projbuild provides +# the glue to build the bootloader project from the original project. It +# basically runs Make in the subproject/ directory but it needs to +# zero some variables the ESP-IDF project.mk makefile exports first, to not +# let them interfere. # -ifndef IS_BOOTLOADER_BUILD - BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH) BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader) BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin @@ -22,16 +20,29 @@ export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component BOOTLOADER_OFFSET := 0x1000 # Custom recursive make for bootloader sub-project -BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ - V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) TEST_COMPONENTS= TESTS_ALL= - -.PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) +# +# NB: Some variables are cleared in the environment, not +# overriden, because they need to be re-defined in the child +# project. +BOOTLOADER_MAKE= +\ + PROJECT_PATH= \ + COMPONENT_DIRS= \ + $(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/subproject \ + V=$(V) \ + BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \ + TEST_COMPONENTS= \ + TESTS_ALL= + +.PHONY: bootloader-clean bootloader-flash bootloader-list-components bootloader $(BOOTLOADER_BIN) $(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE) $(BOOTLOADER_MAKE) $@ clean: bootloader-clean +bootloader-list-components: + $(BOOTLOADER_MAKE) list-components + ifndef CONFIG_SECURE_BOOT_ENABLED # If secure boot disabled, bootloader flashing is integrated # with 'make flash' and no warnings are printed. @@ -110,11 +121,3 @@ endif bootloader-clean: $(BOOTLOADER_MAKE) app-clean rm -f $(SECURE_BOOTLOADER_KEY) $(BOOTLOADER_DIGEST_BIN) - -$(BOOTLOADER_BUILD_DIR): - mkdir -p $@ - -else -CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include - -endif diff --git a/components/bootloader/component.mk b/components/bootloader/component.mk new file mode 100644 index 0000000000..b3e40ee2f4 --- /dev/null +++ b/components/bootloader/component.mk @@ -0,0 +1,7 @@ +# bootloader component is special, as bootloader is also a project. +# +# This top-level component is only configuration files for the IDF project. +# +# See Makefile.projbuild for the targets which actually build the bootloader. +COMPONENT_CONFIG_ONLY := 1 + diff --git a/components/bootloader/src/.gitignore b/components/bootloader/subproject/.gitignore similarity index 100% rename from components/bootloader/src/.gitignore rename to components/bootloader/subproject/.gitignore diff --git a/components/bootloader/src/Makefile b/components/bootloader/subproject/Makefile similarity index 62% rename from components/bootloader/src/Makefile rename to components/bootloader/subproject/Makefile index ac71e27876..198f40f0cc 100644 --- a/components/bootloader/src/Makefile +++ b/components/bootloader/subproject/Makefile @@ -2,12 +2,16 @@ # This is a project Makefile. It is assumed the directory this Makefile resides in is a # project subdirectory. # +ifeq ("$(MAKELEVEL)","0") +$(error Bootloader makefile expects to be run as part of 'make bootloader' from a top-level project.) +endif PROJECT_NAME := bootloader +COMPONENTS := esptool_py bootloader_support log spi_flash micro-ecc soc main + #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 soc +CFLAGS += -I $(IDF_PATH)/components/esp32/include # The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included. # @@ -15,6 +19,9 @@ COMPONENTS := esptool_py bootloader bootloader_support log spi_flash micro-ecc s IS_BOOTLOADER_BUILD := 1 export IS_BOOTLOADER_BUILD +# BOOTLOADER_BUILD macro is the same, for source file changes +CFLAGS += -D BOOTLOADER_BUILD=1 + # include the top-level "project" include directory, for sdkconfig.h CFLAGS += -I$(BUILD_DIR_BASE)/../include diff --git a/components/bootloader/src/main/Makefile.projbuild b/components/bootloader/subproject/main/Makefile.projbuild similarity index 100% rename from components/bootloader/src/main/Makefile.projbuild rename to components/bootloader/subproject/main/Makefile.projbuild diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/subproject/main/bootloader_config.h similarity index 100% rename from components/bootloader/src/main/bootloader_config.h rename to components/bootloader/subproject/main/bootloader_config.h diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/subproject/main/bootloader_start.c similarity index 100% rename from components/bootloader/src/main/bootloader_start.c rename to components/bootloader/subproject/main/bootloader_start.c diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/subproject/main/component.mk similarity index 85% rename from components/bootloader/src/main/component.mk rename to components/bootloader/subproject/main/component.mk index 1199005de2..df07108224 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/subproject/main/component.mk @@ -15,6 +15,6 @@ ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH LINKER_SCRIPTS += $(IDF_PATH)/components/esp32/ld/esp32.rom.spiflash.ld endif -COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SCRIPTS)) +COMPONENT_ADD_LDFLAGS += -L $(COMPONENT_PATH) $(addprefix -T ,$(LINKER_SCRIPTS)) COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS) diff --git a/components/bootloader/src/main/esp32.bootloader.ld b/components/bootloader/subproject/main/esp32.bootloader.ld similarity index 100% rename from components/bootloader/src/main/esp32.bootloader.ld rename to components/bootloader/subproject/main/esp32.bootloader.ld diff --git a/components/bootloader/src/main/esp32.bootloader.rom.ld b/components/bootloader/subproject/main/esp32.bootloader.rom.ld similarity index 100% rename from components/bootloader/src/main/esp32.bootloader.rom.ld rename to components/bootloader/subproject/main/esp32.bootloader.rom.ld diff --git a/components/bootloader/src/main/flash_qio_mode.c b/components/bootloader/subproject/main/flash_qio_mode.c similarity index 100% rename from components/bootloader/src/main/flash_qio_mode.c rename to components/bootloader/subproject/main/flash_qio_mode.c diff --git a/components/bootloader/src/main/flash_qio_mode.h b/components/bootloader/subproject/main/flash_qio_mode.h similarity index 100% rename from components/bootloader/src/main/flash_qio_mode.h rename to components/bootloader/subproject/main/flash_qio_mode.h diff --git a/components/cxx/component.mk b/components/cxx/component.mk index 3ce43fc328..5d56384779 100644 --- a/components/cxx/component.mk +++ b/components/cxx/component.mk @@ -1,3 +1,3 @@ # Mark __cxa_guard_dummy as undefined so that implementation of static guards # is taken from cxx_guards.o instead of libstdc++.a -COMPONENT_ADD_LDFLAGS := -l$(COMPONENT_NAME) -u __cxa_guard_dummy +COMPONENT_ADD_LDFLAGS += -u __cxa_guard_dummy diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 666384e73d..8a06c9cd6b 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -28,8 +28,7 @@ endif #ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the #linker will ignore panic_highint_hdl.S as it has no other files depending on any #symbols in it. -COMPONENT_ADD_LDFLAGS := -lesp32 \ - $(COMPONENT_PATH)/libhal.a \ +COMPONENT_ADD_LDFLAGS += $(COMPONENT_PATH)/libhal.a \ -L$(COMPONENT_PATH)/lib \ $(addprefix -l,$(LIBS)) \ -L $(COMPONENT_PATH)/ld \ diff --git a/components/esptool_py/component.mk b/components/esptool_py/component.mk new file mode 100644 index 0000000000..64ca3b1e24 --- /dev/null +++ b/components/esptool_py/component.mk @@ -0,0 +1,5 @@ +# esptool_py component is special, because it doesn't contain any +# IDF source files. It only adds steps via Makefile.projbuild & +# Kconfig.projbuild +COMPONENT_CONFIG_ONLY := 1 + diff --git a/components/freertos/component.mk b/components/freertos/component.mk index 83a4443f69..4496355a0e 100644 --- a/components/freertos/component.mk +++ b/components/freertos/component.mk @@ -2,7 +2,7 @@ # Component Makefile # -COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) -Wl,--undefined=uxTopUsedPriority +COMPONENT_ADD_LDFLAGS += -Wl,--undefined=uxTopUsedPriority COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_PRIV_INCLUDEDIRS := include/freertos diff --git a/components/newlib/component.mk b/components/newlib/component.mk index d6b73f9445..2f46f1dd38 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -7,7 +7,7 @@ endif LIBM_PATH := $(COMPONENT_PATH)/lib/libm.a -COMPONENT_ADD_LDFLAGS := $(LIBC_PATH) $(LIBM_PATH) -lnewlib +COMPONENT_ADD_LDFLAGS += $(LIBC_PATH) $(LIBM_PATH) COMPONENT_ADD_LINKER_DEPS := $(LIBC_PATH) $(LIBM_PATH) diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index 4d548f7e2d..97819aa8d1 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -14,6 +14,9 @@ GEN_ESP32PART := $(PYTHON) $(COMPONENT_PATH)/gen_esp32part.py -q # Has a matching value in bootloader_support esp_flash_partitions.h PARTITION_TABLE_OFFSET := 0x8000 +# if CONFIG_PARTITION_TABLE_FILENAME is unset, means we haven't re-generated config yet... +ifneq ("$(CONFIG_PARTITION_TABLE_FILENAME)","") + ifndef PARTITION_TABLE_CSV_PATH # Path to partition CSV file is relative to project path for custom # partition CSV files, but relative to component dir otherwise.$ @@ -21,7 +24,9 @@ PARTITION_TABLE_ROOT := $(call dequote,$(if $(CONFIG_PARTITION_TABLE_CUSTOM),$(P PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(subst $(quote),,$(CONFIG_PARTITION_TABLE_FILENAME)))) endif -PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(notdir $(PARTITION_TABLE_CSV_PATH:.csv=.bin)) +PARTITION_TABLE_CSV_NAME := $(notdir $(PARTITION_TABLE_CSV_PATH)) + +PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(PARTITION_TABLE_CSV_NAME:.csv=.bin) ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES PARTITION_TABLE_BIN_UNSIGNED := $(PARTITION_TABLE_BIN:.bin=-unsigned.bin) @@ -58,3 +63,5 @@ partition_table-clean: rm -f $(PARTITION_TABLE_BIN) clean: partition_table-clean + +endif diff --git a/components/partition_table/component.mk b/components/partition_table/component.mk new file mode 100644 index 0000000000..7d857daa8a --- /dev/null +++ b/components/partition_table/component.mk @@ -0,0 +1,5 @@ +# partition table component is special, because it doesn't contain any +# IDF source files. It only adds steps via Makefile.projbuild & +# Kconfig.projbuild +COMPONENT_CONFIG_ONLY := 1 + diff --git a/docs/api-guides/build-system.rst b/docs/api-guides/build-system.rst index 2a2800bbc2..9cbe004a89 100644 --- a/docs/api-guides/build-system.rst +++ b/docs/api-guides/build-system.rst @@ -133,7 +133,7 @@ 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 directory that contains a `component.mk` file [#f1]_. +A component is any directory that contains a ``component.mk`` file. Searching for Components ------------------------ @@ -248,10 +248,15 @@ The following variables can be set inside ``component.mk`` to control the 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 +- ``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. +- ``COMPONENT_CONFIG_ONLY``: If set, this flag indicates that the component + produces no built output at all (ie ``COMPONENT_LIBRARY`` is not built), + and most other component variables are ignored. This flag is used for IDF + internal components which contain only ``KConfig.projbuild`` and/or + ``Makefile.projbuild`` files to configure the project, but no source files. - ``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 @@ -369,11 +374,15 @@ Take care when setting variables or targets in this file. As the values are incl KConfig.projbuild ^^^^^^^^^^^^^^^^^ -This is an equivalent to `Makefile.projbuild` for `component configuration` KConfig files. If you want to include +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 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`. +Configuration-Only Components +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some special components which contain no source files, only ``Kconfig.projbuild`` and ``Makefile.projbuild``, may set the flag ``COMPONENT_CONFIG_ONLY`` in the component.mk file. If this flag is set, most other component variables are ignored and no build step is run for the component. Example Component Makefiles --------------------------- @@ -552,12 +561,11 @@ target. The build target can do anything as long as it creates $(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.) +is overridden 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. A component must have at least one of these three files. Custom sdkconfig defaults @@ -575,7 +583,7 @@ There're some scenarios that we want to flash the target board without IDF. For print_flash_cmd: echo $(ESPTOOL_WRITE_FLASH_OPTIONS) $(ESPTOOL_ALL_FLASH_ARGS) | sed -e 's:'$(PWD)/build/'::g' - + the original ESPTOOL_ALL_FLASH_ARGS are absolute file name. Usually we want to save relative file name so we can move the bin folder to somewhere else. For this case we can use ``sed`` to convert to relative file name, like what we did in the example above. When running ``make print_flash_cmd``, it will print the flash arguments:: @@ -586,3 +594,11 @@ Then use flash arguments as the arguemnts for esptool write_flash arguments:: python esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader/bootloader.bin 0x10000 example_app.bin 0x8000 partition_table_unit_test_app.bin +Building the Bootloader +======================= + +The bootloader is built by default as part of "make all", or can be built standalone via "make bootloader-clean". There is also "make bootloader-list-components" to see the components included in the bootloader build. + +The component in IDF components/bootloader is special, as the second stage bootloader is a separate .ELF and .BIN file to the main project. However it shares its configuration and build directory with the main project. + +This is accomplished by adding a subproject under components/bootloader/subproject. This subproject has its own Makefile, but it expects to be called from the project's own Makefile via some glue in the components/bootloader/Makefile.projectbuild file. See these files for more details. diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index 0ed08b6a91..b4e81fe0cc 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -71,11 +71,12 @@ endef include $(COMPONENT_MAKEFILE) - ################################################################################ # 3) Set variables that depend on values that may changed by component.mk ################################################################################ +ifndef COMPONENT_CONFIG_ONLY # Skip steps 3-5 if COMPONENT_CONFIG_ONLY is set + # 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 @@ -112,6 +113,8 @@ COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_I # 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 +# +# (Skipped if COMPONENT_CONFIG_ONLY is set.) ################################################################################ # macro to generate variable-relative paths inside component_project_vars.mk, whenever possible @@ -140,23 +143,23 @@ 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_LDFLAGS += $(call MakeVariablePath,-L$(COMPONENT_BUILD_DIR) $(COMPONENT_ADD_LDFLAGS))' >> $@ @echo 'COMPONENT_LINKER_DEPS += $(call MakeVariablePath,$(call resolvepath,$(COMPONENT_ADD_LINKER_DEPS),$(COMPONENT_PATH)))' >> $@ @echo 'COMPONENT_SUBMODULES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_SUBMODULES)))' >> $@ + @echo 'COMPONENT_LIBRARIES += $(COMPONENT_NAME)' >> $@ @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 +# 5) Where COMPONENT_OWNBUILDTARGET / COMPONENT_OWNCLEANTARGET +# is not set by component.mk, define default build, clean, etc. targets +# +# (Skipped if COMPONENT_CONFIG_ONLY is set.) ################################################################################ -# If COMPONENT_OWNBUILDTARGET is not set, define a phony build target and -# a COMPONENT_LIBRARY link target. +# Default build behaviour: 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) @@ -250,3 +253,19 @@ $(foreach txtfile,$(COMPONENT_EMBED_TXTFILES), $(eval $(call GenerateEmbedTarget # generate targets to create binary embed directories $(foreach bindir,$(sort $(dir $(COMPONENT_EMBED_FILES))), $(eval $(call GenerateBuildDirTarget,$(bindir)))) + + +else # COMPONENT_CONFIG_ONLY is set + +build: + $(details) "No build needed for $(COMPONENT_NAME) (COMPONENT_CONFIG_ONLY)" + +clean: + $(summary) RM component_project_vars.mk + rm -f component_project_vars.mk + +component_project_vars.mk:: # no need to add variables via component.mk + @echo '# COMPONENT_CONFIG_ONLY target sets no variables here' > $@ + +endif # COMPONENT_CONFIG_ONLY + diff --git a/make/project.mk b/make/project.mk index 70abc351f8..cc439a3582 100644 --- a/make/project.mk +++ b/make/project.mk @@ -96,13 +96,17 @@ 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 +ifndef BUILD_DIR_BASE +BUILD_DIR_BASE := $(PROJECT_PATH)/build +endif export BUILD_DIR_BASE # Component directories. These directories are searched for components (either the directory is a component, # or the directory contains subdirectories which are components.) # The project Makefile can override these component dirs, or add extras via EXTRA_COMPONENT_DIRS -COMPONENT_DIRS ?= $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components $(PROJECT_PATH)/main +ifndef COMPONENT_DIRS +COMPONENT_DIRS := $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components $(PROJECT_PATH)/main +endif export COMPONENT_DIRS ifdef SRCDIRS @@ -110,20 +114,17 @@ $(warning SRCDIRS variable is deprecated. These paths can be added to EXTRA_COMP COMPONENT_DIRS += $(abspath $(SRCDIRS)) endif -# 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. A component is any subdirectory of a COMPONENT_DIRS -# directory where the subdirectory contains component.mk, Kconfig.projbuild or Makefile.projbuild. +# 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. A component is COMPONENT_DIRS directory, or immediate subdirectory, +# which contains a component.mk file. # # Use the "make list-components" target to debug this step. ifndef COMPONENTS -COMPONENT_MARKER_FILES := component.mk Kconfig.projbuild Makefile.projbuild - # Find all component names. The component names are the same as the # directories they're in, so /bla/components/mycomponent/component.mk -> mycomponent. COMPONENTS := $(dir $(foreach cd,$(COMPONENT_DIRS), \ - $(foreach marker,$(COMPONENT_MARKER_FILES), \ - $(wildcard $(cd)/*/$(marker)) $(wildcard $(cd)/$(marker)) \ - ))) + $(wildcard $(cd)/*/component.mk) $(wildcard $(cd)/component.mk) \ + )) COMPONENTS := $(sort $(foreach comp,$(COMPONENTS),$(lastword $(subst /, ,$(comp))))) endif export COMPONENTS @@ -136,9 +137,6 @@ export COMPONENTS # can use $(notdir x) to get the component name. COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),$(firstword $(foreach cd,$(COMPONENT_DIRS),$(wildcard $(dir $(cd))$(comp) $(cd)/$(comp))))) -# 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))) - # If TESTS_ALL set to 1, set TEST_COMPONENTS_LIST to all components ifeq ($(TESTS_ALL),1) TEST_COMPONENTS_LIST := $(COMPONENTS) @@ -169,7 +167,7 @@ COMPONENT_SUBMODULES := # dependencies. # # See the component_project_vars.mk target in component_wrapper.mk -COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE) ) $(TEST_COMPONENT_NAMES)) +COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS) ) $(TEST_COMPONENT_NAMES)) 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) @@ -201,7 +199,6 @@ IDF_VER := $(shell cd ${IDF_PATH} && git describe --always --tags --dirty) # Set default LDFLAGS LDFLAGS ?= -nostdlib \ - $(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(TEST_COMPONENT_NAMES)) \ -u call_user_start_cpu0 \ $(EXTRA_LDFLAGS) \ -Wl,--gc-sections \ @@ -308,11 +305,13 @@ APP_BIN:=$(APP_ELF:.elf=.bin) # Include any Makefile.projbuild file letting components add # configuration at the project level define includeProjBuildMakefile -$(if $(V),$(if $(wildcard $(1)/Makefile.projbuild),$(info including $(1)/Makefile.projbuild...))) +$(if $(V),$(info including $(1)/Makefile.projbuild...)) COMPONENT_PATH := $(1) --include $(1)/Makefile.projbuild +include $(1)/Makefile.projbuild endef -$(foreach componentpath,$(COMPONENT_PATHS),$(eval $(call includeProjBuildMakefile,$(componentpath)))) +$(foreach componentpath,$(COMPONENT_PATHS), \ + $(if $(wildcard $(componentpath)/Makefile.projbuild), \ + $(eval $(call includeProjBuildMakefile,$(componentpath))))) # once we know component paths, we can include the config generation targets # @@ -321,22 +320,15 @@ 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 -APP_LIBRARIES = $(patsubst -l%,%,$(filter -l%,$(LDFLAGS))) -COMPONENT_LIBRARIES = $(filter $(notdir $(COMPONENT_PATHS_BUILDABLE)) $(TEST_COMPONENT_NAMES),$(APP_LIBRARIES)) - # ELF depends on the library archive files for COMPONENT_LIBRARIES # the rules to build these are emitted as part of GenerateComponentTarget below # # also depends on additional dependencies (linker scripts & binary libraries) # stored in COMPONENT_LINKER_DEPS, built via component.mk files' COMPONENT_ADD_LINKER_DEPS variable -$(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(COMPONENT_LINKER_DEPS) +$(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(COMPONENT_LINKER_DEPS) $(COMPONENT_PROJECT_VARS) $(summary) LD $(notdir $@) $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) -# Generation of $(APP_BIN) from $(APP_ELF) is added by the esptool -# component's Makefile.projbuild app: $(APP_BIN) ifeq ("$(CONFIG_SECURE_BOOT_ENABLED)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image @echo "App built but not signed. Signing step via espsecure.py:" @@ -367,12 +359,12 @@ endef # $(2) - name of component # define GenerateComponentTargets -.PHONY: $(2)-build $(2)-clean +.PHONY: component-$(2)-build component-$(2)-clean -$(2)-build: check-submodules +component-$(2)-build: check-submodules $(call ComponentMake,$(1),$(2)) build -$(2)-clean: +component-$(2)-clean: $(call ComponentMake,$(1),$(2)) clean $(BUILD_DIR_BASE)/$(2): @@ -382,7 +374,7 @@ $(BUILD_DIR_BASE)/$(2): # (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)/$(2)/lib$(2).a: $(2)-build +$(BUILD_DIR_BASE)/$(2)/lib$(2).a: component-$(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 @@ -396,10 +388,10 @@ $(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAK $(call ComponentMake,$(1),$(2)) component_project_vars.mk endef -$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) +$(foreach component,$(COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) $(foreach component,$(TEST_COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(lastword $(subst /, ,$(dir $(component))))_test))) -app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) +app-clean: $(addprefix component-,$(addsuffix -clean,$(notdir $(COMPONENT_PATHS)))) $(summary) RM $(APP_ELF) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) @@ -450,7 +442,8 @@ $(foreach submodule,$(subst $(IDF_PATH)/,,$(filter $(IDF_PATH)/%,$(COMPONENT_SUB # PHONY target to list components in the build and their paths list-components: - $(info COMPONENT_DIRS (top-level, subdirectories of these are components)) + $(info $(call dequote,$(SEPARATOR))) + $(info COMPONENT_DIRS (components searched for here)) $(foreach cd,$(COMPONENT_DIRS),$(info $(cd))) $(info $(call dequote,$(SEPARATOR))) $(info COMPONENTS (list of component names)) diff --git a/tools/ci/test_build_system.sh b/tools/ci/test_build_system.sh index 0d4f36e4d4..14e4a8ab96 100755 --- a/tools/ci/test_build_system.sh +++ b/tools/ci/test_build_system.sh @@ -71,7 +71,7 @@ function run_tests() print_status "Bootloader source file rebuilds bootloader" take_build_snapshot - touch ${IDF_PATH}/components/bootloader/src/main/bootloader_start.c + touch ${IDF_PATH}/components/bootloader/subproject/main/bootloader_start.c make bootloader || failure "Failed to partial build bootloader" assert_rebuilt ${BOOTLOADER_BINS} bootloader/main/bootloader_start.o assert_not_rebuilt ${APP_BINS} partitions_singleapp.bin -- 2.40.0