1# 2# Main Project Makefile 3# This Makefile is included directly from the user project Makefile in order to call the component.mk 4# makefiles of all components (in a separate make process) to build all the libraries, then links them 5# together into the final file. If so, PWD is the project dir (we assume). 6# 7 8# 9# This makefile requires the environment variable IDF_PATH to be set to the top-level esp-idf directory 10# where this file is located. 11# 12 13.PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules size size-components size-files size-symbols list-components 14 15MAKECMDGOALS ?= all 16all: all_binaries | check_python_dependencies 17# see below for recipe of 'all' target 18# 19# # other components will add dependencies to 'all_binaries'. The 20# reason all_binaries is used instead of 'all' is so that the flash 21# target can build everything without triggering the per-component "to 22# flash..." output targets.) 23 24help: 25 @echo "Welcome to Espressif IDF build system. Some useful make targets:" 26 @echo "" 27 @echo "make menuconfig - Configure IDF project" 28 @echo "make defconfig - Set defaults for all new configuration options" 29 @echo "" 30 @echo "make all - Build app, bootloader, partition table" 31 @echo "make flash - Flash app, bootloader, partition table to a chip" 32 @echo "make clean - Remove all build output" 33 @echo "make size - Display the static memory footprint of the app" 34 @echo "make size-components, size-files - Finer-grained memory footprints" 35 @echo "make size-symbols - Per symbol memory footprint. Requires COMPONENT=<component>" 36 @echo "make erase_flash - Erase entire flash contents" 37 @echo "make erase_otadata - Erase ota_data partition; First bootable partition (factory or OTAx) will be used on next boot." 38 @echo " This assumes this project's partition table is the one flashed on the device." 39 @echo "make monitor - Run idf_monitor tool to monitor serial output from app" 40 @echo "make simple_monitor - Monitor serial output on terminal console" 41 @echo "make list-components - List all components in the project" 42 @echo "" 43 @echo "make app - Build just the app" 44 @echo "make app-flash - Flash just the app" 45 @echo "make app-clean - Clean just the app" 46 @echo "make print_flash_cmd - Print the arguments for esptool when flash" 47 @echo "make check_python_dependencies - Check that the required python packages are installed" 48 @echo "" 49 @echo "See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean', " 50 @echo "'make partition_table', etc, etc." 51 52# Non-interactive targets. Mostly, those for which you do not need to build a binary 53NON_INTERACTIVE_TARGET += defconfig clean% %clean help list-components print_flash_cmd check_python_dependencies 54 55# dependency checks 56ifndef MAKE_RESTARTS 57ifeq ("$(filter 4.% 3.81 3.82,$(MAKE_VERSION))","") 58$(warning esp-idf build system only supports GNU Make versions 3.81 or newer. You may see unexpected results with other Makes.) 59endif 60 61ifdef MSYSTEM 62ifneq ("$(MSYSTEM)","MINGW32") 63$(warning esp-idf build system only supports MSYS2 in "MINGW32" mode. Consult the ESP-IDF documentation for details.) 64endif 65endif # MSYSTEM 66 67endif # MAKE_RESTARTS 68 69# can't run 'clean' along with any non-clean targets 70ifneq ("$(filter clean% %clean,$(MAKECMDGOALS))" ,"") 71ifneq ("$(filter-out clean% %clean,$(MAKECMDGOALS))", "") 72$(error esp-idf build system doesn't support running 'clean' targets along with any others. Run 'make clean' and then run other targets separately.) 73endif 74endif 75 76OS ?= 77 78# make IDF_PATH a "real" absolute path 79# * works around the case where a shell character is embedded in the environment variable value. 80# * changes Windows-style C:/blah/ paths to MSYS style /c/blah 81ifeq ("$(OS)","Windows_NT") 82# On Windows MSYS2, make wildcard function returns empty string for paths of form /xyz 83# where /xyz is a directory inside the MSYS root - so we don't use it. 84SANITISED_IDF_PATH:=$(realpath $(IDF_PATH)) 85else 86SANITISED_IDF_PATH:=$(realpath $(wildcard $(IDF_PATH))) 87endif 88 89export IDF_PATH := $(SANITISED_IDF_PATH) 90 91ifndef IDF_PATH 92$(error IDF_PATH variable is not set to a valid directory.) 93endif 94 95ifdef IDF_TARGET 96ifneq ($(IDF_TARGET),esp32) 97$(error GNU Make based build system only supports esp32 target, but IDF_TARGET is set to $(IDF_TARGET)) 98endif 99else 100export IDF_TARGET := esp32 101endif 102 103 104ifneq ("$(IDF_PATH)","$(SANITISED_IDF_PATH)") 105# implies IDF_PATH was overriden on make command line. 106# Due to the way make manages variables, this is hard to account for 107# 108# if you see this error, do the shell expansion in the shell ie 109# make IDF_PATH=~/blah not make IDF_PATH="~/blah" 110$(error If IDF_PATH is overriden on command line, it must be an absolute path with no embedded shell special characters) 111endif 112 113ifneq ("$(IDF_PATH)","$(subst :,,$(IDF_PATH))") 114$(error IDF_PATH cannot contain colons. If overriding IDF_PATH on Windows, use MSYS Unix-style /c/dir instead of C:/dir) 115endif 116 117# disable built-in make rules, makes debugging saner 118MAKEFLAGS_OLD := $(MAKEFLAGS) 119MAKEFLAGS +=-rR 120 121# Default path to the project: we assume the Makefile including this file 122# is in the project directory 123ifndef PROJECT_PATH 124PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) 125export PROJECT_PATH 126endif 127 128# A list of the "common" makefiles, to use as a target dependency 129COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/version.mk $(IDF_PATH)/make/component_wrapper.mk $(firstword $(MAKEFILE_LIST))) 130export COMMON_MAKEFILES 131 132# The directory where we put all objects/libraries/binaries. The project Makefile can 133# configure this if needed. 134ifndef BUILD_DIR_BASE 135BUILD_DIR_BASE := $(PROJECT_PATH)/build 136endif 137export BUILD_DIR_BASE 138 139# Component directories. These directories are searched for components (either the directory is a component, 140# or the directory contains subdirectories which are components.) 141# The project Makefile can override these component dirs, or add extras via EXTRA_COMPONENT_DIRS 142ifndef COMPONENT_DIRS 143EXTRA_COMPONENT_DIRS ?= 144COMPONENT_DIRS := $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(IDF_PATH)/components $(PROJECT_PATH)/main 145endif 146# Make sure that every directory in the list is an absolute path without trailing slash. 147# This is necessary to split COMPONENT_DIRS into SINGLE_COMPONENT_DIRS and MULTI_COMPONENT_DIRS below. 148COMPONENT_DIRS := $(foreach cd,$(COMPONENT_DIRS),$(abspath $(cd))) 149export COMPONENT_DIRS 150 151ifdef SRCDIRS 152$(warning SRCDIRS variable is deprecated. These paths can be added to EXTRA_COMPONENT_DIRS or COMPONENT_DIRS instead.) 153COMPONENT_DIRS += $(abspath $(SRCDIRS)) 154endif 155 156# List of component directories, i.e. directories which contain a component.mk file 157SINGLE_COMPONENT_DIRS := $(abspath $(dir $(dir $(foreach cd,$(COMPONENT_DIRS),\ 158 $(wildcard $(cd)/component.mk))))) 159 160# List of components directories, i.e. directories which may contain components 161MULTI_COMPONENT_DIRS := $(filter-out $(SINGLE_COMPONENT_DIRS),$(COMPONENT_DIRS)) 162 163# The project Makefile can define a list of components, but if it does not do this 164# we just take all available components in the component dirs. 165# A component is COMPONENT_DIRS directory, or immediate subdirectory, 166# which contains a component.mk file. 167# 168# Use the "make list-components" target to debug this step. 169ifndef COMPONENTS 170# Find all component names. The component names are the same as the 171# directories they're in, so /bla/components/mycomponent/component.mk -> mycomponent. 172# We need to do this for MULTI_COMPONENT_DIRS only, since SINGLE_COMPONENT_DIRS 173# are already known to contain component.mk. 174COMPONENTS := $(dir $(foreach cd,$(MULTI_COMPONENT_DIRS),$(wildcard $(cd)/*/component.mk))) \ 175 $(SINGLE_COMPONENT_DIRS) 176COMPONENTS := $(sort $(foreach comp,$(COMPONENTS),$(lastword $(subst /, ,$(comp))))) 177endif 178# After a full manifest of component names is determined, subtract the ones explicitly 179# omitted by the project Makefile. 180EXCLUDE_COMPONENTS ?= 181ifdef EXCLUDE_COMPONENTS 182COMPONENTS := $(filter-out $(subst ",,$(EXCLUDE_COMPONENTS)), $(COMPONENTS)) 183# to keep syntax highlighters happy: ")) 184endif 185export COMPONENTS 186 187# Resolve all of COMPONENTS into absolute paths in COMPONENT_PATHS. 188# For each entry in COMPONENT_DIRS: 189# - either this is directory with multiple components, in which case check that 190# a subdirectory with component name exists, and it contains a component.mk file. 191# - or, this is a directory of a single component, in which case the name of this 192# directory has to match the component name 193# 194# If a component name exists in multiple COMPONENT_DIRS, we take the first match. 195# 196# NOTE: These paths must be generated WITHOUT a trailing / so we 197# can use $(notdir x) to get the component name. 198COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),\ 199 $(firstword $(foreach cd,$(COMPONENT_DIRS),\ 200 $(if $(findstring $(cd),$(MULTI_COMPONENT_DIRS)),\ 201 $(abspath $(dir $(wildcard $(cd)/$(comp)/component.mk))),)\ 202 $(if $(findstring $(cd),$(SINGLE_COMPONENT_DIRS)),\ 203 $(if $(filter $(comp),$(notdir $(cd))),$(cd),),)\ 204 ))) 205export COMPONENT_PATHS 206 207TEST_COMPONENTS ?= 208TEST_EXCLUDE_COMPONENTS ?= 209TESTS_ALL ?= 210 211# If TESTS_ALL set to 1, set TEST_COMPONENTS_LIST to all components. 212# Otherwise, use the list supplied in TEST_COMPONENTS. 213ifeq ($(TESTS_ALL),1) 214TEST_COMPONENTS_LIST := $(filter-out $(TEST_EXCLUDE_COMPONENTS), $(COMPONENTS)) 215else 216TEST_COMPONENTS_LIST := $(TEST_COMPONENTS) 217endif 218 219TEST_COMPONENT_PATHS := $(foreach comp,$(TEST_COMPONENTS_LIST),$(firstword $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/$(comp)/test)))) 220TEST_COMPONENT_NAMES := $(foreach comp,$(TEST_COMPONENT_PATHS),$(lastword $(subst /, ,$(dir $(comp))))_test) 221 222# Set default values that were not previously defined 223CC ?= gcc 224LD ?= ld 225AR ?= ar 226OBJCOPY ?= objcopy 227OBJDUMP ?= objdump 228SIZE ?= size 229 230# Set host compiler and binutils 231HOSTCC := $(CC) 232HOSTLD := $(LD) 233HOSTAR := $(AR) 234HOSTOBJCOPY := $(OBJCOPY) 235HOSTSIZE := $(SIZE) 236export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY SIZE 237 238# Set variables common to both project & component (includes config) 239include $(IDF_PATH)/make/common.mk 240 241# Notify users when some of the required python packages are not installed 242.PHONY: check_python_dependencies 243check_python_dependencies: 244ifndef IS_BOOTLOADER_BUILD 245 $(PYTHON) $(IDF_PATH)/tools/check_python_dependencies.py 246endif 247 248# include the config generation targets (dependency: COMPONENT_PATHS) 249# 250# (bootloader build doesn't need this, config is exported from top-level) 251ifndef IS_BOOTLOADER_BUILD 252include $(IDF_PATH)/make/project_config.mk 253endif 254 255##################################################################### 256# If SDKCONFIG_MAKEFILE hasn't been generated yet (detected if no 257# CONFIG_IDF_TARGET), stop the Makefile pass now to allow config to 258# be created. make will build SDKCONFIG_MAKEFILE and restart, 259# reevaluating everything from the top. 260# 261# This is important so config is present when the 262# component_project_vars.mk files are generated. 263# 264# (After both files exist, if SDKCONFIG_MAKEFILE is updated then the 265# normal dependency relationship will trigger a regeneration of 266# component_project_vars.mk) 267# 268##################################################################### 269ifndef CONFIG_IDF_TARGET 270ifdef IS_BOOTLOADER_BUILD # we expect config to always have been expanded by top level project 271$(error "Internal error: config has not been passed correctly to bootloader subproject") 272endif 273ifdef MAKE_RESTARTS 274$(warning "Config was not evaluated after the first pass of 'make'") 275endif 276else # CONFIG_IDF_TARGET 277##################################################################### 278# Config is valid, can include rest of the Project Makefile 279##################################################################### 280 281 282# Initialise project-wide variables which can be added to by 283# each component. 284# 285# These variables are built up via the component_project_vars.mk 286# generated makefiles (one per component). 287# 288# See docs/build-system.rst for more details. 289COMPONENT_INCLUDES := 290COMPONENT_LDFLAGS := 291COMPONENT_SUBMODULES := 292COMPONENT_LIBRARIES := 293COMPONENT_LDFRAGMENTS := 294 295# COMPONENT_PROJECT_VARS is the list of component_project_vars.mk generated makefiles 296# for each component. 297# 298# Including $(COMPONENT_PROJECT_VARS) builds the COMPONENT_INCLUDES, 299# COMPONENT_LDFLAGS variables and also targets for any inter-component 300# dependencies. 301# 302# See the component_project_vars.mk target in component_wrapper.mk 303COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS) ) $(TEST_COMPONENT_NAMES)) 304COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) 305# this line is -include instead of include to prevent a spurious error message on make 3.81 306-include $(COMPONENT_PROJECT_VARS) 307 308# Also add top-level project include path, for top-level includes 309COMPONENT_INCLUDES += $(abspath $(BUILD_DIR_BASE)/include/) 310 311export COMPONENT_INCLUDES 312 313all: 314ifdef CONFIG_SECURE_BOOT 315 @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" 316ifndef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES 317ifdef SECURE_SIGNED_APPS_ECDSA_SCHEME 318 @echo "App built but not signed. Sign app & partition data before flashing, via espsecure.py:" 319 @echo "espsecure.py sign_data --version 1 --keyfile KEYFILE $(APP_BIN)" 320 @echo "espsecure.py sign_data --version 1 --keyfile KEYFILE $(PARTITION_TABLE_BIN)" 321else 322 @echo "App built but not signed. Sign app & partition data before flashing, via espsecure.py:" 323 @echo "espsecure.py sign_data --version 2 --keyfile KEYFILE $(APP_BIN)" 324endif 325endif 326 @echo "To flash app & partition table, run 'make flash' or:" 327else 328ifdef CONFIG_APP_BUILD_GENERATE_BINARIES 329 @echo "To flash all build output, run 'make flash' or:" 330endif 331endif 332ifdef CONFIG_APP_BUILD_GENERATE_BINARIES 333 @echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) 334else 335 @echo "Binary is not available for flashing" 336endif 337 338 339# If we have `version.txt` then prefer that for extracting IDF version 340ifeq ("$(wildcard ${IDF_PATH}/version.txt)","") 341IDF_VER_T := $(shell cd ${IDF_PATH} && git describe --always --dirty) 342else 343IDF_VER_T := $(shell cat ${IDF_PATH}/version.txt) 344endif 345IDF_VER := $(shell echo "$(IDF_VER_T)" | cut -c 1-31) 346 347# Set default LDFLAGS 348EXTRA_LDFLAGS ?= 349LDFLAGS ?= -nostdlib \ 350 -u call_user_start_cpu0 \ 351 $(EXTRA_LDFLAGS) \ 352 -Wl,--gc-sections \ 353 -Wl,-static \ 354 -Wl,--start-group \ 355 $(COMPONENT_LDFLAGS) \ 356 -lgcc \ 357 -lstdc++ \ 358 -lgcov \ 359 -Wl,--end-group \ 360 -Wl,-EL 361 362# Set default CPPFLAGS, CFLAGS, CXXFLAGS 363# These are exported so that components can use them when compiling. 364# If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile. 365# If you need your component to add CFLAGS/etc globally for all source 366# files, set CFLAGS += in your component's Makefile.projbuild 367# If you need to set CFLAGS/CPPFLAGS/CXXFLAGS at project level, set them in application Makefile 368# before including project.mk. Default flags will be added before the ones provided in application Makefile. 369 370# CPPFLAGS used by C preprocessor 371# If any flags are defined in application Makefile, add them at the end. 372CPPFLAGS ?= 373EXTRA_CPPFLAGS ?= 374CPPFLAGS := -DESP_PLATFORM -D IDF_VER=\"$(IDF_VER)\" -MMD -MP $(CPPFLAGS) $(EXTRA_CPPFLAGS) 375PROJECT_VER ?= 376export IDF_VER 377export PROJECT_NAME 378export PROJECT_VER 379 380# Warnings-related flags relevant both for C and C++ 381COMMON_WARNING_FLAGS = -Wall -Werror=all \ 382 -Wno-error=unused-function \ 383 -Wno-error=unused-but-set-variable \ 384 -Wno-error=unused-variable \ 385 -Wno-error=deprecated-declarations \ 386 -Wextra \ 387 -Wno-unused-parameter -Wno-sign-compare 388 389ifdef CONFIG_COMPILER_DISABLE_GCC8_WARNINGS 390COMMON_WARNING_FLAGS += -Wno-parentheses \ 391 -Wno-sizeof-pointer-memaccess \ 392 -Wno-clobbered \ 393 -Wno-format-overflow \ 394 -Wno-stringop-truncation \ 395 -Wno-misleading-indentation \ 396 -Wno-cast-function-type \ 397 -Wno-implicit-fallthrough \ 398 -Wno-unused-const-variable \ 399 -Wno-switch-unreachable \ 400 -Wno-format-truncation \ 401 -Wno-memset-elt-size \ 402 -Wno-int-in-bool-context 403endif 404 405ifdef CONFIG_COMPILER_WARN_WRITE_STRINGS 406COMMON_WARNING_FLAGS += -Wwrite-strings 407endif #CONFIG_COMPILER_WARN_WRITE_STRINGS 408 409# Flags which control code generation and dependency generation, both for C and C++ 410COMMON_FLAGS = \ 411 -Wno-frame-address \ 412 -ffunction-sections -fdata-sections \ 413 -fstrict-volatile-bitfields \ 414 -mlongcalls \ 415 -nostdlib 416 417ifndef IS_BOOTLOADER_BUILD 418# stack protection (only one option can be selected in menuconfig) 419ifdef CONFIG_COMPILER_STACK_CHECK_MODE_NORM 420COMMON_FLAGS += -fstack-protector 421endif 422ifdef CONFIG_COMPILER_STACK_CHECK_MODE_STRONG 423COMMON_FLAGS += -fstack-protector-strong 424endif 425ifdef CONFIG_COMPILER_STACK_CHECK_MODE_ALL 426COMMON_FLAGS += -fstack-protector-all 427endif 428 429# Optimization flags are set based on menuconfig choice 430ifdef CONFIG_COMPILER_OPTIMIZATION_SIZE 431OPTIMIZATION_FLAGS = -Os -freorder-blocks 432endif 433 434ifdef CONFIG_COMPILER_OPTIMIZATION_DEFAULT 435OPTIMIZATION_FLAGS = -Og 436endif 437 438ifdef CONFIG_COMPILER_OPTIMIZATION_NONE 439OPTIMIZATION_FLAGS = -O0 440endif 441 442ifdef CONFIG_COMPILER_OPTIMIZATION_PERF 443OPTIMIZATION_FLAGS = -O2 444endif 445 446ifdef CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE 447CPPFLAGS += -DNDEBUG 448endif 449 450else # IS_BOOTLOADER_BUILD 451 452ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE 453OPTIMIZATION_FLAGS = -Os -freorder-blocks 454endif 455 456ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG 457OPTIMIZATION_FLAGS = -Og 458endif 459 460ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE 461OPTIMIZATION_FLAGS = -O0 462endif 463 464ifdef CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF 465OPTIMIZATION_FLAGS = -O2 466endif 467 468endif # IS_BOOTLOADER_BUILD 469 470 471# IDF uses some GNU extension from libc 472CPPFLAGS += -D_GNU_SOURCE 473 474# Enable generation of debugging symbols 475# (we generate even in Release mode, as this has no impact on final binary size.) 476DEBUG_FLAGS ?= -ggdb 477 478# List of flags to pass to C compiler 479# If any flags are defined in application Makefile, add them at the end. 480CFLAGS ?= 481EXTRA_CFLAGS ?= 482CFLAGS := $(strip \ 483 -std=gnu99 \ 484 $(OPTIMIZATION_FLAGS) $(DEBUG_FLAGS) \ 485 $(COMMON_FLAGS) \ 486 $(COMMON_WARNING_FLAGS) -Wno-old-style-declaration \ 487 $(CFLAGS) \ 488 $(EXTRA_CFLAGS)) 489 490# List of flags to pass to C++ compiler 491# If any flags are defined in application Makefile, add them at the end. 492CXXFLAGS ?= 493EXTRA_CXXFLAGS ?= 494CXXFLAGS := $(strip \ 495 -std=gnu++11 \ 496 $(OPTIMIZATION_FLAGS) $(DEBUG_FLAGS) \ 497 $(COMMON_FLAGS) \ 498 $(COMMON_WARNING_FLAGS) \ 499 $(CXXFLAGS) \ 500 $(EXTRA_CXXFLAGS)) 501 502ifdef CONFIG_COMPILER_CXX_EXCEPTIONS 503CXXFLAGS += -fexceptions 504else 505CXXFLAGS += -fno-exceptions 506endif 507 508ifdef CONFIG_COMPILER_CXX_RTTI 509CXXFLAGS += -frtti 510else 511CXXFLAGS += -fno-rtti 512LDFLAGS += -fno-rtti 513endif 514 515ARFLAGS := cru 516 517export CFLAGS CPPFLAGS CXXFLAGS ARFLAGS 518 519# Set target compiler. Defaults to whatever the user has 520# configured as prefix + ye olde gcc commands 521CC := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))gcc 522CXX := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))c++ 523LD := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ld 524AR := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))ar 525OBJCOPY := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objcopy 526OBJDUMP := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))objdump 527SIZE := $(call dequote,$(CONFIG_SDK_TOOLPREFIX))size 528export CC CXX LD AR OBJCOPY OBJDUMP SIZE 529 530COMPILER_VERSION_STR := $(shell $(CC) -dumpversion) 531COMPILER_VERSION_NUM := $(subst .,,$(COMPILER_VERSION_STR)) 532 533# the app is the main executable built by the project 534APP_ELF:=$(BUILD_DIR_BASE)/$(PROJECT_NAME).elf 535APP_MAP:=$(APP_ELF:.elf=.map) 536APP_BIN:=$(APP_ELF:.elf=.bin) 537 538# include linker script generation utils makefile 539include $(IDF_PATH)/make/ldgen.mk 540 541$(eval $(call ldgen_create_commands)) 542 543# Include any Makefile.projbuild file letting components add 544# configuration at the project level 545define includeProjBuildMakefile 546ifeq ("$(V)","1") 547$$(info including $(1)/Makefile.projbuild...) 548endif 549COMPONENT_PATH := $(1) 550include $(1)/Makefile.projbuild 551endef 552$(foreach componentpath,$(COMPONENT_PATHS), \ 553 $(if $(wildcard $(componentpath)/Makefile.projbuild), \ 554 $(eval $(call includeProjBuildMakefile,$(componentpath))))) 555 556# ELF depends on the library archive files for COMPONENT_LIBRARIES 557# the rules to build these are emitted as part of GenerateComponentTarget below 558# 559# also depends on additional dependencies (linker scripts & binary libraries) 560# stored in COMPONENT_LINKER_DEPS, built via component.mk files' COMPONENT_ADD_LINKER_DEPS variable 561COMPONENT_LINKER_DEPS ?= 562$(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(COMPONENT_LINKER_DEPS) $(COMPONENT_PROJECT_VARS) 563 $(summary) LD $(patsubst $(PWD)/%,%,$@) 564 $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) 565 566ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME 567SECURE_APPS_SIGNING_SCHEME = "1" 568else ifdef CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME 569SECURE_APPS_SIGNING_SCHEME = "2" 570endif 571 572app: $(APP_BIN) partition_table_get_info 573ifeq ("$(CONFIG_APP_BUILD_GENERATE_BINARIES)","y") 574ifeq ("$(CONFIG_SECURE_BOOT)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image 575 @echo "App built but not signed. Signing step via espsecure.py:" 576 @echo "espsecure.py sign_data --version $(SECURE_APPS_SIGNING_SCHEME) --keyfile KEYFILE $(APP_BIN)" 577 @echo "Then flash app command is:" 578 @echo $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN) 579else 580 @echo "App built. Default flash app command is:" 581 @echo $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN) 582endif 583else 584 @echo "Application in not built and cannot be flashed." 585endif 586 587all_binaries: $(APP_BIN) 588 589$(BUILD_DIR_BASE): 590 mkdir -p $(BUILD_DIR_BASE) 591 592# Macro for the recursive sub-make for each component 593# $(1) - component directory 594# $(2) - component name only 595# 596# Is recursively expanded by the GenerateComponentTargets macro 597define ComponentMake 598+$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk COMPONENT_NAME=$(2) 599endef 600 601# Generate top-level component-specific targets for each component 602# $(1) - path to component dir 603# $(2) - name of component 604# 605define GenerateComponentTargets 606.PHONY: component-$(2)-build component-$(2)-clean 607 608component-$(2)-build: check-submodules $(call prereq_if_explicit, component-$(2)-clean) | $(BUILD_DIR_BASE)/$(2) 609 $(call ComponentMake,$(1),$(2)) build 610 611component-$(2)-clean: | $(BUILD_DIR_BASE)/$(2) $(BUILD_DIR_BASE)/$(2)/component_project_vars.mk 612 $(call ComponentMake,$(1),$(2)) clean 613 614$(BUILD_DIR_BASE)/$(2): 615 @mkdir -p $(BUILD_DIR_BASE)/$(2) 616 617# tell make it can build any component's library by invoking the -build target 618# (this target exists for all components even ones which don't build libraries, but it's 619# only invoked for the targets whose libraries appear in COMPONENT_LIBRARIES and hence the 620# APP_ELF dependencies.) 621$(BUILD_DIR_BASE)/$(2)/lib$(2).a: component-$(2)-build 622 $(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file 623 624# add a target to generate the component_project_vars.mk files that 625# are used to inject variables into project make pass (see matching 626# component_project_vars.mk target in component_wrapper.mk). 627# 628# If any component_project_vars.mk file is out of date, the make 629# process will call this target to rebuild it and then restart. 630# 631$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG_MAKEFILE) | $(BUILD_DIR_BASE)/$(2) 632 $(call ComponentMake,$(1),$(2)) component_project_vars.mk 633endef 634 635$(foreach component,$(COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) 636$(foreach component,$(TEST_COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(lastword $(subst /, ,$(dir $(component))))_test))) 637 638app-clean: $(addprefix component-,$(addsuffix -clean,$(notdir $(COMPONENT_PATHS)))) 639 $(summary) RM $(APP_ELF) 640 rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) 641 642size: $(APP_ELF) | check_python_dependencies 643 $(PYTHON) $(IDF_PATH)/tools/idf_size.py $(APP_MAP) 644 645size-files: $(APP_ELF) | check_python_dependencies 646 $(PYTHON) $(IDF_PATH)/tools/idf_size.py --files $(APP_MAP) 647 648size-components: $(APP_ELF) | check_python_dependencies 649 $(PYTHON) $(IDF_PATH)/tools/idf_size.py --archives $(APP_MAP) 650 651size-symbols: $(APP_ELF) | check_python_dependencies 652ifndef COMPONENT 653 $(error "ERROR: Please enter the component to look symbols for, e.g. COMPONENT=heap") 654else 655 $(PYTHON) $(IDF_PATH)/tools/idf_size.py --archive_details lib$(COMPONENT).a $(APP_MAP) 656endif 657 658# NB: this ordering is deliberate (app-clean & bootloader-clean before 659# _config-clean), so config remains valid during all component clean 660# targets 661config-clean: app-clean bootloader-clean 662clean: app-clean bootloader-clean config-clean ldgen-clean 663 664# phony target to check if any git submodule listed in COMPONENT_SUBMODULES are missing 665# or out of date, and exit if so. Components can add paths to this variable. 666# 667# This only works for components inside IDF_PATH 668# 669# For internal use: 670# IDF_SKIP_CHECK_SUBMODULES may be set in the environment to skip the submodule check. 671# This can be used e.g. in CI when submodules are checked out by different means. 672IDF_SKIP_CHECK_SUBMODULES ?= 0 673 674check-submodules: 675ifeq ($(IDF_SKIP_CHECK_SUBMODULES),1) 676 @echo "skip submodule check on internal CI" 677else 678# Check if .gitmodules exists, otherwise skip submodule check, assuming flattened structure 679ifneq ("$(wildcard ${IDF_PATH}/.gitmodules)","") 680 681# Dump the git status for the whole working copy once, then grep it for each submodule. This saves a lot of time on Windows. 682GIT_STATUS := $(shell cd ${IDF_PATH} && git status --porcelain --ignore-submodules=dirty) 683 684# Generate a target to check this submodule 685# $(1) - submodule directory, relative to IDF_PATH 686define GenerateSubmoduleCheckTarget 687check-submodules: $(IDF_PATH)/$(1)/.git 688$(IDF_PATH)/$(1)/.git: 689 @echo "WARNING: Missing submodule $(1)..." 690 [ -e ${IDF_PATH}/.git ] || { echo "ERROR: esp-idf must be cloned from git to work."; exit 1; } 691 [ -x "$(shell which git)" ] || { echo "ERROR: Need to run 'git submodule init $(1)' in esp-idf root directory."; exit 1; } 692 @echo "Attempting 'git submodule update --init $(1)' in esp-idf root directory..." 693 cd ${IDF_PATH} && git submodule update --init $(1) 694 695# Parse 'git status' output to check if the submodule commit is different to expected 696ifneq ("$(filter $(1),$(GIT_STATUS))","") 697$$(info WARNING: esp-idf git submodule $(1) may be out of date. Run 'git submodule update' in IDF_PATH dir to update.) 698endif 699endef 700 701# filter/subst in expression ensures all submodule paths begin with $(IDF_PATH), and then strips that prefix 702# so the argument is suitable for use with 'git submodule' commands 703$(foreach submodule,$(subst $(IDF_PATH)/,,$(filter $(IDF_PATH)/%,$(COMPONENT_SUBMODULES))),$(eval $(call GenerateSubmoduleCheckTarget,$(submodule)))) 704endif # End check for .gitmodules existence 705endif # End check for IDF_SKIP_CHECK_SUBMODULES 706 707# PHONY target to list components in the build and their paths 708list-components: 709 $(info $(call dequote,$(SEPARATOR))) 710 $(info COMPONENT_DIRS (components searched for here)) 711 $(foreach cd,$(COMPONENT_DIRS),$(info $(cd))) 712 $(info $(call dequote,$(SEPARATOR))) 713 $(info TEST_COMPONENTS (list of test component names)) 714 $(info $(TEST_COMPONENTS_LIST)) 715 $(info $(call dequote,$(SEPARATOR))) 716 $(info TEST_EXCLUDE_COMPONENTS (list of test excluded names)) 717 $(info $(if $(EXCLUDE_COMPONENTS) || $(TEST_EXCLUDE_COMPONENTS),$(EXCLUDE_COMPONENTS) $(TEST_EXCLUDE_COMPONENTS),(none provided))) 718 $(info $(call dequote,$(SEPARATOR))) 719 $(info COMPONENT_PATHS (paths to all components):) 720 $(foreach cp,$(COMPONENT_PATHS),$(info $(cp))) 721 722# print flash command, so users can dump this to config files and download somewhere without idf 723print_flash_cmd: partition_table_get_info blank_ota_data 724 echo $(ESPTOOL_WRITE_FLASH_OPTIONS) $(ESPTOOL_ALL_FLASH_ARGS) | sed -e 's:'$(PWD)/build/'::g' 725 726# Check toolchain version using the output of xtensa-esp32-elf-gcc --version command. 727# The output normally looks as follows 728# xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a) 5.2.0 729# The part in brackets is extracted into TOOLCHAIN_COMMIT_DESC variable 730ifdef CONFIG_SDK_TOOLPREFIX 731ifndef MAKE_RESTARTS 732 733TOOLCHAIN_HEADER := $(shell $(CC) --version | head -1) 734TOOLCHAIN_PATH := $(shell which $(CC)) 735TOOLCHAIN_COMMIT_DESC := $(shell $(CC) --version | sed -E -n 's|.*\(crosstool-NG (.*)\).*|\1|gp') 736TOOLCHAIN_GCC_VER := $(COMPILER_VERSION_STR) 737 738# Officially supported version(s) 739include $(IDF_PATH)/tools/toolchain_versions.mk 740 741ifndef IS_BOOTLOADER_BUILD 742$(info Toolchain path: $(TOOLCHAIN_PATH)) 743endif 744 745ifdef TOOLCHAIN_COMMIT_DESC 746ifeq (,$(findstring $(SUPPORTED_TOOLCHAIN_COMMIT_DESC),$(TOOLCHAIN_COMMIT_DESC))) 747$(info WARNING: Toolchain version is not supported: $(TOOLCHAIN_COMMIT_DESC)) 748$(info Expected to see version: $(SUPPORTED_TOOLCHAIN_COMMIT_DESC)) 749$(info Please check ESP-IDF setup instructions and update the toolchain, or proceed at your own risk.) 750else 751ifndef IS_BOOTLOADER_BUILD 752$(info Toolchain version: $(TOOLCHAIN_COMMIT_DESC)) 753endif 754endif 755ifeq (,$(findstring $(TOOLCHAIN_GCC_VER), $(SUPPORTED_TOOLCHAIN_GCC_VERSIONS))) 756$(info WARNING: Compiler version is not supported: $(TOOLCHAIN_GCC_VER)) 757$(info Expected to see version(s): $(SUPPORTED_TOOLCHAIN_GCC_VERSIONS)) 758$(info Please check ESP-IDF setup instructions and update the toolchain, or proceed at your own risk.) 759else 760ifndef IS_BOOTLOADER_BUILD 761$(info Compiler version: $(TOOLCHAIN_GCC_VER)) 762endif 763endif 764else 765$(info WARNING: Failed to find Xtensa toolchain, may need to alter PATH or set one in the configuration menu) 766endif # TOOLCHAIN_COMMIT_DESC 767 768endif #MAKE_RESTARTS 769endif #CONFIG_SDK_TOOLPREFIX 770 771##################################################################### 772endif #CONFIG_IDF_TARGET 773