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