MATCH_MAKE_VERSION = 4.% MAKEFLAGS += --no-builtin-rules ifeq (,$(filter $(MATCH_MAKE_VERSION),$(MAKE_VERSION))) $(error GNU Make $(MAKE_VERSION) is not supported by RIOT since release \ 2020.01. Please upgrade your system to use GNU Make \ $(MATCH_MAKE_VERSION) or later.) endif # # enable second expansion of prerequisites. # # Doing that here enables it globally for all applications. # # See https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html # for what it can be used for. .SECONDEXPANSION: # Will evaluate to the absolute path of the Makefile it's evaluated in.ยน # # This variable MUST be immediately evaluated (tmp_var := $(LAST_MAKEFILEDIR)) # unless it is used directly. # # [1] Note that this will in fact return the path of the last Makefile that # was included, so it must be evaluated before any subsequent includes. LAST_MAKEFILEDIR = $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) # 'Makefile.include' directory, must be evaluated before other 'include' _riotbase := $(LAST_MAKEFILEDIR) # include RIOT_MAKEFILES_GLOBAL_PRE configuration files # allows setting user specific system wide configuration parsed before the body # of $(RIOTBASE)/Makefile.include include $(RIOT_MAKEFILES_GLOBAL_PRE) # Globally set default goal to `all` .DEFAULT_GOAL := all # include Makefile.local if it exists -include Makefile.local # set undefined variables RIOTBASE ?= $(_riotbase) RIOTCPU ?= $(RIOTBASE)/cpu # Deprecated to set RIOTBOARD, use EXTERNAL_BOARD_DIRS RIOTBOARD ?= $(RIOTBASE)/boards EXTERNAL_BOARD_DIRS ?= RIOTMAKE ?= $(RIOTBASE)/makefiles RIOTKCONFIG ?= $(RIOTBASE)/kconfigs RIOTPKG ?= $(RIOTBASE)/pkg EXTERNAL_PKG_DIRS ?= RIOTTOOLS ?= $(RIOTBASE)/dist/tools RIOTPROJECT ?= $(shell git rev-parse --show-toplevel 2>/dev/null || pwd) BUILD_DIR ?= $(RIOTBASE)/build APPDIR ?= $(CURDIR) BINDIRBASE ?= $(APPDIR)/bin BINDIR ?= $(BINDIRBASE)/$(BOARD) PKGDIRBASE ?= $(BUILD_DIR)/pkg DLCACHE ?= $(RIOTTOOLS)/dlcache/dlcache.sh DLCACHE_DIR ?= $(RIOTBASE)/.dlcache RIOT_VERSION_DUMMY_CODE ?= RIOT_VERSION_NUM\(2042,5,23,0\) # include CI info such as BOARD_INSUFFICIENT_MEMORY, if existing -include Makefile.ci __DIRECTORY_VARIABLES := \ RIOTBASE \ RIOTCPU \ RIOTMAKE \ RIOTPKG \ RIOTTOOLS \ RIOTPROJECT \ APPDIR \ BUILD_DIR \ BINDIRBASE \ BINDIR \ PKGDIRBASE \ DLCACHE_DIR \ # # In GNU make command line is supposed to override the value set in makefile # These variables can be overridden even when set from command line __OVERRIDE_DIRECTORY_VARIABLES := $(__DIRECTORY_VARIABLES) # Use absolute paths in recursive "make" even if overridden on command line. MAKEOVERRIDES += $(foreach v,$(__OVERRIDE_DIRECTORY_VARIABLES),$(v)=$($(v))) # Setting EXTERNAL_BOARD_DIRS and EXTERNAL_MODULE_DIRS as command line argument # is too messy to handle: Even when every path in EXTERNAL_BOARD_DIRS is turned # into an absolute path using override, sub-makes will still get the original # value. Using MAKEOVERRIDES has issues with spaces in the values, which are # used as separator in EXTERNAL_BOARD_DIRS. So we just enforce setting the value # either in a Makefile, or as environment variable. ifeq ($(INSIDE_DOCKER),0) # In Docker absolute paths are always given, so only fail when not in docker ifeq ($(origin EXTERNAL_BOARD_DIRS),command line) $(error EXTERNAL_BOARD_DIRS must be passed as environment variable, and not as command line argument) endif ifeq ($(origin EXTERNAL_MODULE_DIRS),command line) $(error EXTERNAL_MODULE_DIRS must be passed as environment variable, and not as command line argument) endif ifeq ($(origin EXTERNAL_PKG_DIRS),command line) $(error EXTERNAL_PKG_DIRS must be passed as environment variable, and not as command line argument) endif endif # Deprecation of configuring 'RIOTBOARD' ifneq ($(abspath $(RIOTBASE)/boards),$(abspath $(RIOTBOARD))) $(warning overriding RIOTBOARD for external boards is deprecated, use EXTERNAL_BOARD_DIRS instead) override RIOTBOARD := $(abspath $(RIOTBOARD)) __DIRECTORY_VARIABLES += RIOTBOARD endif # Only warn users, not the CI. ifneq ($(RIOT_CI_BUILD),1) # Do not warn when set from sub-make ifeq ($(MAKELEVEL),0) ifneq (,$(BOARDSDIR)) $(warning Using BOARDSDIR is deprecated use EXTERNAL_BOARD_DIRS instead) endif endif endif # Needed for backward compatibility: ifneq (,$(BOARDSDIR)) EXTERNAL_BOARD_DIRS += $(BOARDSDIR) endif # Make all paths absolute. override RIOTBASE := $(abspath $(RIOTBASE)) override RIOTCPU := $(abspath $(RIOTCPU)) override RIOTMAKE := $(abspath $(RIOTMAKE)) override RIOTPKG := $(abspath $(RIOTPKG)) override RIOTTOOLS := $(abspath $(RIOTTOOLS)) override RIOTPROJECT := $(abspath $(RIOTPROJECT)) override APPDIR := $(abspath $(APPDIR)) override BUILD_DIR := $(abspath $(BUILD_DIR)) override BINDIRBASE := $(abspath $(BINDIRBASE)) override BINDIR := $(abspath $(BINDIR)) override PKGDIRBASE := $(abspath $(PKGDIRBASE)) override DLCACHE_DIR := $(abspath $(DLCACHE_DIR)) EXTERNAL_BOARD_DIRS := $(foreach dir,\ $(EXTERNAL_BOARD_DIRS),\ $(abspath $(dir))) EXTERNAL_MODULE_DIRS := $(foreach dir,\ $(EXTERNAL_MODULE_DIRS),\ $(abspath $(dir))) EXTERNAL_PKG_DIRS := $(foreach dir,\ $(EXTERNAL_PKG_DIRS),\ $(abspath $(dir))) # Ensure that all directories are set and don't contain spaces. ifneq (, $(filter-out 1, $(foreach v,$(__DIRECTORY_VARIABLES),$(words $($(v)))))) $(info Aborting compilation for your safety.) $(info Related variables = $(__DIRECTORY_VARIABLES)) $(error Make sure no path override is empty or contains spaces!) endif # Path to the current directory relative to RIOTPROJECT # trailing '/' is important when RIOTPROJECT == CURDIR BUILDRELPATH ?= $(patsubst $(RIOTPROJECT)/%,%,$(CURDIR)/) # Set CLEAN to "clean" if that target was requested. # Allows recipes to be run after cleaning, without triggering it implicitly: # # all: | $(CLEAN) # CLEAN = $(filter clean, $(MAKECMDGOALS)) # include makefiles utils tools include $(RIOTMAKE)/utils/variables.mk include $(RIOTMAKE)/utils/strings.mk # include nimble makefile tools include $(RIOTMAKE)/pkg/nimble.adv.mk # UNAME is always needed so use simple variable expansion so only evaluated once UNAME := $(shell uname -m -s) OS = $(word 1, $(UNAME)) OS_ARCH = $(word 2, $(UNAME)) # set python path, e.g. for tests PYTHONPATH := $(RIOTBASE)/dist/pythonlibs/:$(PYTHONPATH) # Basic utilities included before anything else include $(RIOTMAKE)/utils/checks.mk # Include Docker settings near the top because we need to build the environment # command line before some of the variable origins are overwritten below when # using abspath, strip etc. include $(RIOTMAKE)/docker.inc.mk # include color echo macros include $(RIOTMAKE)/utils/ansi.mk include $(RIOTMAKE)/color.inc.mk # include concurrency helpers include $(RIOTMAKE)/info-nproc.inc.mk # List of boards variables include $(RIOTMAKE)/boards.inc.mk # Debug targets for build system migration include $(RIOTMAKE)/dependencies_debug.inc.mk # Use TOOLCHAIN environment variable to select the toolchain to use. ifeq ($(BOARD),native) ifeq ($(OS),Darwin) $(shell $(COLOR_ECHO) "$(COLOR_RED)"Buildin on macOS is not supported."\ "We recommend vagrant for building:$(COLOR_RESET)"\ "https://github.com/RIOT-OS/RIOT/blob/master/dist/tools/vagrant/README.md 1>&2) endif endif # Use override so that we can redefine a variable set on the command line (as # opposed to one set in the environment) ifeq (clang,$(TOOLCHAIN)) # TOOLCHAIN = clang is an alias for TOOLCHAIN = llvm override TOOLCHAIN := llvm endif ifeq (gcc,$(TOOLCHAIN)) # TOOLCHAIN = gcc is an alias for TOOLCHAIN = gnu override TOOLCHAIN := gnu endif ifeq (,$(TOOLCHAIN)) override TOOLCHAIN := gnu endif include $(RIOTMAKE)/cargo-settings.inc.mk GLOBAL_GOALS += buildtest \ buildtest-indocker \ info-boards-features-blacklisted \ info-boards-features-conflicting \ info-boards-features-missing \ info-boards-supported \ info-buildsizes info-buildsizes-diff \ generate-Makefile.ci \ # ifneq (, $(filter $(GLOBAL_GOALS), $(MAKECMDGOALS))) include $(RIOTMAKE)/info-global.inc.mk include $(RIOTMAKE)/buildtests.inc.mk else all: link # Folders to search: First the external boards, than the official BOARDSDIRS := $(EXTERNAL_BOARD_DIRS) $(RIOTBOARD) # Take the first folder in $(BOARDSDIRS) that contains a folder named $(BOARD) BOARDDIR := $(word 1,$(foreach dir,$(BOARDSDIRS),$(wildcard $(dir)/$(BOARD)/.))) # Sanitize folder BOARDDIR := $(abspath $(BOARDDIR)) # Also provide BOARDSDIR for compatibility and for accessing common folders # (e.g. include $(BOARDSDIR)/common/external_common/Makefile.dep) BOARDSDIR := $(dir $(BOARDDIR)) ifeq (,$(BOARDDIR)) $(info Folders searched for the board: $(BOARDSDIRS)) $(error The specified board $(BOARD) does not exist.) endif include $(RIOTMAKE)/info.inc.mk # Static code analysis tools provided by LLVM include $(RIOTMAKE)/scan-build.inc.mk export RIOTBUILD_CONFIG_HEADER_C = $(BINDIR)/riotbuild/riotbuild.h # When testing Kconfig's module modelling we need to run Kconfig ifeq (1,$(TEST_KCONFIG)) SHOULD_RUN_KCONFIG = 1 endif ifeq ($(OS),Darwin) OPEN := open else OPEN := xdg-open endif QUIET ?= 1 QUIETER ?= 0 ifeq ($(QUIET),1) Q=@ MAKEFLAGS += --no-print-directory else Q= endif # Set this to 1 to enable pretty-printing the assert location in addition # to the address of the failing assert. # This saves you to resolve the address manually with addr2line at the cost # of greater ROM consumption. VERBOSE_ASSERT ?= 0 ifeq ($(VERBOSE_ASSERT),1) CFLAGS += -DDEBUG_ASSERT_VERBOSE DEVELHELP := 1 endif # Set this to 1 to enable code in RIOT that does safety checking # which is not needed in a production environment but helps in the # development process: DEVELHELP ?= 0 ifeq ($(DEVELHELP),1) CFLAGS += -DDEVELHELP endif # Set this to 1 to enable thread names THREAD_NAMES ?= 0 ifeq ($(THREAD_NAMES),1) CFLAGS += -DCONFIG_THREAD_NAMES endif # Override LOG_LEVEL if variable is set and if CFLAGS doesn't already contain # a LOG_LEVEL config ifdef LOG_LEVEL ifeq (,$(filter -DLOG_LEVEL=%,$(CFLAGS))) CFLAGS += -DLOG_LEVEL=$(LOG_LEVEL) endif endif # Fail on warnings. Can be overridden by `make WERROR=0`. WERROR ?= 1 ifeq ($(WERROR),1) CFLAGS += -Werror endif WPEDANTIC ?= 0 ifeq ($(WPEDANTIC),1) CFLAGS += -Wpedantic endif # Provide a shallow sanity check. You cannot call `make` in a module directory. export __RIOTBUILD_FLAG := RIOT BOARD := $(strip $(BOARD)) APPLICATION := $(strip $(APPLICATION)) # provide common external programs for `Makefile.include`s ifeq (,$(and $(DOWNLOAD_TO_STDOUT),$(DOWNLOAD_TO_FILE))) ifeq (,$(WGET)) ifeq (0,$(shell which wget > /dev/null 2>&1 ; echo $$?)) WGET = $(call memoized,WGET,$(shell which wget)) endif endif ifeq (,$(CURL)) ifeq (0,$(shell which curl > /dev/null 2>&1 ; echo $$?)) CURL = $(call memoized,CURL,$(shell which curl)) endif endif ifeq (,$(WGET)$(CURL)) $(warning Neither wget nor curl is installed!) endif ifeq (,$(DOWNLOAD_TO_STDOUT)) DOWNLOAD_TO_STDOUT ?= $(if $(CURL),$(CURL) -s,$(WGET) -q -O-) endif ifeq (,$(DOWNLOAD_TO_FILE)) DOWNLOAD_TO_FILE ?= $(if $(WGET),$(WGET) -nv -c -O,$(CURL) -s -o) endif endif ifeq (,$(UNZIP_HERE)) ifeq (0,$(shell which unzip > /dev/null 2>&1 ; echo $$?)) UNZIP_HERE = $(call memoized,UNZIP_HERE,$(shell which unzip) -q) else ifeq (0,$(shell which 7z > /dev/null 2>&1 ; echo $$?)) UNZIP_HERE = $(call memoized,UNZIP_HERE,$(shell which 7z) x -bd) else $(warning Neither unzip nor 7z is installed.) endif endif endif # Tool saving stdin to a file only on content update. # It keeps the file timestamp if it would end up the same. LAZYSPONGE ?= $(RIOTTOOLS)/lazysponge/lazysponge.py LAZYSPONGE_FLAGS ?= $(if $(filter 1,$(QUIET)),,--verbose) ifeq (, $(APPLICATION)) $(error An application name must be specified as APPLICATION.) endif # default toolchain prefix, defaults to target triple followed by a dash, you # will most likely not need to touch this. export PREFIX ?= $(if $(TARGET_ARCH),$(TARGET_ARCH)-) # set default PROGRAMMER value if flashing a board on IoT-LAB # This must be done before parsing the Makefile.include of the board and cannot # be done in makefile.iotlab.single.inc.mk which is included after. ifneq (,$(IOTLAB_NODE)) PROGRAMMER ?= iotlab # iotlab uses ELFFILE by default for flashing boards. FLASHFILE ?= $(ELFFILE) # Disable IOTLAB_NODE if inside Docker to avoid including the # iotlab.single.inc.mk file which is useless there: it's only useful for # flashing and this is done outside of Docker. ifeq (1,$(INSIDE_DOCKER)) IOTLAB_NODE := endif endif # Add standard include directories INCLUDES += -I$(RIOTBASE)/core/lib/include INCLUDES += -I$(RIOTBASE)/core/include INCLUDES += -I$(RIOTBASE)/drivers/include INCLUDES += -I$(RIOTBASE)/sys/include # process provided features include $(RIOTBASE)/Makefile.features ifneq ($(RIOT_CI_BUILD),1) # Warn about used deprecated boards include $(RIOTMAKE)/deprecated_boards.inc.mk include $(RIOTMAKE)/deprecated_cpus.inc.mk endif # mandatory includes! include $(RIOTMAKE)/pseudomodules.inc.mk include $(RIOTMAKE)/defaultmodules_regular.inc.mk # Include Kconfig functionalities include $(RIOTMAKE)/kconfig.mk # For testing, use TEST_KCONFIG as a switch between Makefile.dep and Kconfig ifeq (1,$(TEST_KCONFIG)) ifneq ($(RIOT_CI_BUILD),1) $(info === [ATTENTION] Testing Kconfig dependency modelling ===) endif KCONFIG_MODULES := $(call lowercase,$(patsubst CONFIG_MODULE_%,%,$(filter CONFIG_MODULE_%,$(.VARIABLES)))) USEMODULE := $(KCONFIG_MODULES) KCONFIG_PACKAGES := $(call lowercase,$(patsubst CONFIG_PACKAGE_%,%,$(filter CONFIG_PACKAGE_%,$(.VARIABLES)))) USEPKG := $(KCONFIG_PACKAGES) # Locate used packages in $(RIOTPKG) or $(EXTERNAL_PKG_DIRS). PKGDIRS := $(RIOTPKG) $(EXTERNAL_PKG_DIRS) PKG_PATHS := $(sort $(foreach dir,$(PKGDIRS),\ $(foreach pkg,$(USEPKG),$(dir $(wildcard $(dir)/$(pkg)/Makefile))))) EXTERNAL_MODULE_PATHS := $(dir $(EXTERNAL_MODULE_KCONFIGS)) else # always select provided architecture features FEATURES_REQUIRED += $(filter arch_%,$(FEATURES_PROVIDED)) # always select CPU core features FEATURES_REQUIRED += $(filter cpu_core_%,$(FEATURES_PROVIDED)) # check if required features are provided and update $(FEATURES_USED) include $(RIOTMAKE)/features_check.inc.mk # handle removal of default modules USEMODULE += $(filter-out $(DISABLE_MODULE), $(DEFAULT_MODULE)) # avoid recursive expansion USEMODULE := $(sort $(USEMODULE)) # process dependencies include $(RIOTMAKE)/dependency_resolution.inc.mk endif # Include dfu-util configuration when using riotboot_dfu bootloader before # including the board's Makefile.include which could define dfu-util # configuration for other DFU bootloaders in use. include $(RIOTMAKE)/boot/riotboot_dfu-util.mk # Include Board and CPU configuration INCLUDES += $(addprefix -I,$(wildcard $(BOARDDIR)/include)) include $(BOARDDIR)/Makefile.include INCLUDES += -I$(RIOTCPU)/$(CPU)/include include $(RIOTCPU)/$(CPU)/Makefile.include # Include common serial logic to define TERMPROG, TERMFLAGS variables based on # the content of RIOT_TERMINAL include $(RIOTMAKE)/tools/serial.inc.mk # Include emulator code when required and if available ifeq (1,$(EMULATE)) # Use renode as default emulator RIOT_EMULATOR ?= renode -include $(RIOTMAKE)/tools/$(RIOT_EMULATOR).inc.mk TERMDEPS += $(EMULATORDEPS) DEBUGDEPS += $(EMULATORDEPS) endif # Include common programmer logic if available -include $(RIOTMAKE)/tools/$(PROGRAMMER).inc.mk # Check if programmer is supported by the board, only if PROGRAMMERS_SUPPORTED # is set and if programmer is not iotlab ifneq ($(RIOT_CI_BUILD),1) ifneq (iotlab,$(PROGRAMMER)) ifneq (,$(PROGRAMMERS_SUPPORTED)) ifeq (,$(filter $(PROGRAMMER),$(PROGRAMMERS_SUPPORTED))) $(info '$(PROGRAMMER)' programmer is not supported by this board. \ Supported programmers: '$(PROGRAMMERS_SUPPORTED)') endif endif endif endif # Assume GCC/GNU as supported toolchain if CPU's Makefile.include doesn't # provide this macro TOOLCHAINS_SUPPORTED ?= gnu # Import all toolchain settings include $(RIOTMAKE)/toolchain/$(TOOLCHAIN).inc.mk # Append ldscript path after importing CPU and board makefiles to allow # overriding the core ldscripts LINKFLAGS += -L$(RIOTBASE)/core/ldscripts # include undefined behaviour sanitizer (UBSAN) support include $(RIOTMAKE)/ubsan.inc.mk # Tell ccache to pass the original file to the compiler, instead of passing the # preprocessed code. Without this setting, the compilation will fail with # -Wimplicit-fallthrough warnings even when the fall through case is properly # commented because the preprocessor has stripped the comments from the code. # This also fixes some other false warnings when compiling with LLVM/Clang. # The environment variable only affects builds with ccache (e.g. on CI/Murdock). # Non cached builds are not affected in any way. # For more information, see http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html export CCACHE_CPP2=yes ifeq ($(strip $(MCU)),) MCU = $(CPU) endif # set some settings useful for continuous integration builds ifeq ($(RIOT_CI_BUILD),1) RIOT_VERSION ?= buildtest # set a dummy version number RIOT_VERSION_CODE ?= $(RIOT_VERSION_DUMMY_CODE) ifneq ($(filter $(BOARD_INSUFFICIENT_MEMORY), $(BOARD)),) RIOTNOLINK:=1 endif # be more quiet when building for CI QUIETER=1 endif ifeq ($(QUIETER),1) QQ=@ else QQ= endif # if you want to publish the board into the sources as an uppercase #define BOARDDEF = $(call uppercase_and_underscore,$(BOARD)) CPUDEF = $(call uppercase_and_underscore,$(CPU)) MCUDEF = $(call uppercase_and_underscore,$(MCU)) CFLAGS += -DRIOT_APPLICATION=\"$(APPLICATION)\" CFLAGS += -DBOARD_$(BOARDDEF)=\"$(BOARD)\" -DRIOT_BOARD=BOARD_$(BOARDDEF) CFLAGS += -DCPU_$(CPUDEF)=\"$(CPU)\" -DRIOT_CPU=CPU_$(CPUDEF) CFLAGS += -DMCU_$(MCUDEF)=\"$(MCU)\" -DRIOT_MCU=MCU_$(MCUDEF) # Feature test default CFLAGS and LINKFLAGS for the set compiled. include $(RIOTMAKE)/cflags.inc.mk # Include VERSION for releases -include $(RIOTBASE)/VERSION -include $(RIOTBASE)/EXTRAVERSION include $(RIOTMAKE)/git_version.inc.mk RIOT_VERSION ?= $(or $(GIT_VERSION),'UNKNOWN (builddir: $(RIOTBASE))') RIOT_EXTRAVERSION ?= 0 # Deprecate using RIOT_VERSION_OVERRIDE but currently keep the behavior ifneq (,$(RIOT_VERSION_OVERRIDE)) $(warning 'RIOT_VERSION_OVERRIDE' is deprecated, it can now be set with 'RIOT_VERSION' directly.) RIOT_VERSION = $(RIOT_VERSION_OVERRIDE) endif # Generate machine readable RIOT VERSION macro RIOT_VERSION_CODE ?= $(shell echo $(RIOT_VERSION) | \ sed -E 's/([0-9]+)\.([0-9]+)\.?([0-9]+)?.*/RIOT_VERSION_NUM\\\(\1,\2,0\3,$(RIOT_EXTRAVERSION)\\\)/' | \ grep RIOT_VERSION_NUM || echo "$(RIOT_VERSION_DUMMY_CODE)") # Set module by prepending APPLICATION name with 'application_'. # It prevents conflict with application and modules with the same name. APPLICATION_MODULE ?= application_$(APPLICATION) # the binaries to link BASELIBS += $(APPLICATION_MODULE).module BASELIBS += $(APPDEPS) # add extra include paths for packages in $(USEMODULE) USEMODULE_INCLUDES = include $(RIOTBASE)/sys/Makefile.include # add default board_init() DIRS += $(RIOTBASE)/boards/common/init # include Makefile.includes of each driver modules if they exist -include $(USEMODULE:%=$(RIOTBASE)/drivers/%/Makefile.include) # include Makefile.includes for packages in $(PKG_PATHS) -include $(PKG_PATHS:%=%Makefile.include) # include external modules configuration -include $(EXTERNAL_MODULE_PATHS:%=%Makefile.include) # Deduplicate includes without sorting them # see https://stackoverflow.com/questions/16144115/makefile-remove-duplicate-words-without-sorting define uniq $(eval seen :=) $(foreach _,$1,$(if $(filter $_,$(seen)),,$(eval seen += $_))) $(seen) endef USEMODULE_INCLUDES_ = $(strip $(call uniq,$(USEMODULE_INCLUDES))) INCLUDES += $(USEMODULE_INCLUDES_:%=-I%) # include bindist target include $(RIOTMAKE)/bindist.inc.mk # Add all USEMODULE modules to CFLAGS and populate BASELIBS include $(RIOTMAKE)/modules.inc.mk .PHONY: all link clean flash flash-only termdeps term doc debug debug-server reset objdump help info-modules .PHONY: print-size elffile lstfile binfile hexfile flashfile cosy .PHONY: ..in-docker-container # Targets that depend on FORCE will always be rebuilt. Contrary to a .PHONY # target, they are considered real files and the modification timestamp is taken # into account. # # FORCE is useful for goals that may keep outputs unchanged (for example, if it # depends on environment or configuration variables). If the goal were .PHONY, it # would trigger a rebuild of all its dependents regardless of file modification. # # As general rule, use .PHONY only for non-file targets. # # For more information, see: # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html # https://www.gnu.org/software/make/manual/html_node/Force-Targets.html .PHONY: FORCE ifneq (,$(IOTLAB_NODE)) # iot-lab archi mapping include $(RIOTBASE)/dist/testbed-support/makefile.iotlab.archi.inc.mk ifneq (,$(IOTLAB_ARCHI)) # iot-lab serial and flasher include $(RIOTBASE)/dist/testbed-support/makefile.iotlab.single.inc.mk else $(info $(COLOR_YELLOW)Board "$(BOARD)" incompatible with IOTLAB_NODE variable$(COLOR_RESET)) endif endif ELFFILE ?= $(BINDIR)/$(APPLICATION).elf HEXFILE ?= $(ELFFILE:.elf=.hex) BINFILE ?= $(ELFFILE:.elf=.bin) HASHFILE ?= $(BINFILE) MAPFILE ?= $(ELFFILE:.elf=.map) LSTFILE ?= $(ELFFILE:.elf=.lst) ifneq (,$(filter suit,$(USEMODULE))) include $(RIOTMAKE)/suit.base.inc.mk endif # include bootloaders support. It should be included early to allow using # variables defined in `riotboot.mk` for `FLASHFILE` before it is evaluated. # It should be included after defining 'BINFILE' for 'riotboot.bin' handling. include $(RIOTMAKE)/boot/riotboot.mk # include suit targets ifneq (,$(filter suit,$(USEMODULE))) include $(RIOTMAKE)/suit.inc.mk endif # elf file used for the debugger, must include bootloader offset DEBUG_ELFFILE ?= $(ELFFILE) # Targets to get given file elffile: $(ELFFILE) hexfile: $(HEXFILE) binfile: $(BINFILE) lstfile: $(LSTFILE) # FLASHFILE is the file used by the flasher # Usually set to $(ELFFILE), $(HEXFILE) or $(BINFILE) in the board/flasher # or application specific files flashfile: $(FLASHFILE) ifeq (,$(FLASHFILE)) $(error FLASHFILE is not defined for this board: $(BOARD)) endif BUILD_FILES += $(ELFFILE) $(BINFILE) $(FLASHFILE) $(HASHFILE) # variables used to compile and link c++ ifneq (,$(filter cpp,$(USEMODULE))) CPPMIX ?= 1 endif # We assume $(LINK) to be gcc-like. Use `LINKFLAGPREFIX :=` for ld-like linker options. LINKFLAGPREFIX ?= -Wl, # Also build external modules DIRS += $(EXTERNAL_MODULE_PATHS) # Define dependencies required for building (headers, downloading source files,) BUILDDEPS += $(RIOTBUILD_CONFIG_HEADER_C) BUILDDEPS += pkg-prepare BUILDDEPS += $(APPDEPS) BUILDDEPS += $(MODULE_LIST_DIR) BUILDDEPS += $(BUILD_DIR)/CACHEDIR.TAG # Build dependencies depend on clean (if a make goal), as clean may wipe them. # Without them depending on clean parallel builds occasionally fail due to # clean removing dependencies that make previously considered as up to date. $(BUILDDEPS): $(CLEAN) # Save value to verify it is not modified later _BASELIBS_VALUE_BEFORE_USAGE := $(BASELIBS) # Linker rule # Only use --start-group when archives are defined ARCHIVES_GROUP = $(if $(ARCHIVES),$(LINKFLAGPREFIX)--start-group $(ARCHIVES) -lm $(LINKFLAGPREFIX)--end-group, -lm) $(ELFFILE): FORCE ifeq ($(BUILDOSXNATIVE),1) _LINK = $(if $(CPPMIX),$(LINKXX),$(LINK)) $$(find $(BASELIBS:%.module=$(BINDIR)/%/) -name "*.o" 2> /dev/null | sort) $(ARCHIVES_GROUP) $(LINKFLAGS) $(LINKFLAGPREFIX)-no_pie else _LINK = $(if $(CPPMIX),$(LINKXX),$(LINK)) $$(find $(BASELIBS:%.module=$(BINDIR)/%/) -name "*.o" 2> /dev/null | sort) $(ARCHIVES_GROUP) $(LINKFLAGS) $(LINKFLAGPREFIX)-Map=$(BINDIR)/$(APPLICATION).map endif # BUILDOSXNATIVE COMPILE_COMMANDS_PATH ?= $(if $(findstring $(RIOTBASE),$(APPDIR)),$(RIOTBASE)/compile_commands.json, $(APPDIR)/compile_commands.json) COMPILE_COMMANDS_FLAGS ?= --clangd .PHONY: compile-commands compile-commands: $(BUILDDEPS) $(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \ "$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk compile-commands $(Q)$(RIOTTOOLS)/compile_commands/compile_commands.py $(COMPILE_COMMANDS_FLAGS) $(BINDIR) \ > $(COMPILE_COMMANDS_PATH) ifeq ($(BUILD_IN_DOCKER),1) link: ..in-docker-container else ifeq (,$(RIOTNOLINK)) link: ..compiler-check ..build-message $(BUILD_FILES) print-size ..module-check else link: ..compiler-check ..build-message $(BASELIBS) $(ARCHIVES) ..module-check endif # RIOTNOLINK $(ELFFILE): $(BASELIBS) $(ARCHIVES) $(LD_SCRIPTS) $(Q)$(_LINK) -o $@ .PHONY: $(APPLICATION_MODULE).module ..module-check: $(BASELIBS) @[ -z "$(strip $(NON_GENERATED_MODULES))" ] || \ ($(COLOR_ECHO) "$(COLOR_RED)Error - using unknown modules: $(COLOR_RESET)$(NON_GENERATED_MODULES)" && false) $(APPLICATION_MODULE).module: pkg-build $(BUILDDEPS) $(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \ "$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk $(APPLICATION_MODULE).module: FORCE # Other modules are built by application.inc.mk and packages building _SUBMAKE_LIBS = $(filter-out $(APPLICATION_MODULE).module $(APPDEPS), $(BASELIBS) $(ARCHIVES)) $(_SUBMAKE_LIBS): $(APPLICATION_MODULE).module pkg-build # 'print-size' triggers a rebuild. Use 'info-buildsize' if you do not need to rebuild. print-size: $(ELFFILE) $(Q)$(SIZE) $(SIZEFLAGS) $< $(BUILD_DIR)/CACHEDIR.TAG: $(Q)mkdir -p "$(BUILD_DIR)" $(Q)echo "Signature: 8a477f597d28d172789f06886806bc55" > "$@" $(Q)echo "# This folder contains RIOT's build cache" >> "$@" %.hex: %.elf $(Q)$(OBJCOPY) $(OFLAGS) -Oihex $< $@ %.bin: %.elf $(Q)$(OBJCOPY) $(OFLAGS) -Obinary $< $@ %.lst: %.elf $(Q)$(OBJDUMP) --disassemble-all --file-headers --file-offsets \ --section-headers --line-numbers --private-headers --source --wide \ --disassemble-zeroes $< > $@ endif # BUILD_IN_DOCKER # Check given command is available in the path # check_cmd 'command' 'description' define check_cmd @command -v $1 >/dev/null 2>&1 || \ { $(COLOR_ECHO) \ '$(COLOR_RED)$2 $1 is required but not found in PATH. Aborting.$(COLOR_RESET)'; \ exit 1;} endef # Check if setsid command is available on the system for debug target # This is not the case on MacOSX, so it must be built on the fly ifeq ($(OS),Darwin) ifneq (,$(filter debug, $(MAKECMDGOALS))) ifneq (0,$(shell command -v setsid > /dev/null 2>&1 ; echo $$?)) SETSID = $(RIOTTOOLS)/setsid/setsid $(call target-export-variables,debug,$(SETSID)) DEBUGDEPS += $(SETSID) endif endif endif ..compiler-check: $(call check_cmd,$(CC),Compiler) ..build-message: $(if $(SHOULD_RUN_KCONFIG), check-kconfig-errors) @$(COLOR_ECHO) '$(COLOR_GREEN)Building application "$(APPLICATION)" for "$(BOARD)" with MCU "$(MCU)".$(COLOR_RESET)' @$(COLOR_ECHO) # The `clean` needs to be serialized before everything else. all $(BASELIBS) $(ARCHIVES) $(BUILDDEPS) ..in-docker-container: | $(CLEAN) .PHONY: pkg-prepare pkg-build pkg-prepare: -@$(foreach dir,$(PKG_PATHS),"$(MAKE)" -C $(dir) prepare $(NEWLINE)) pkg-build: $(BUILDDEPS) $(foreach dir,$(PKG_PATHS),$(QQ)"$(MAKE)" -C $(dir) $(NEWLINE)) clean: ifndef MAKE_RESTARTS -@$(foreach dir,$(PKG_PATHS),"$(MAKE)" -C $(dir) clean $(NEWLINE)) -@rm -rf $(BINDIR) -@rm -rf $(SCANBUILD_OUTPUTDIR) endif # Remove intermediates, but keep the .elf, .hex and .map etc. clean-intermediates: -@$(foreach dir,$(PKG_PATHS),"$(MAKE)" -C $(dir) distclean $(NEWLINE)) -@rm -rf $(BINDIR)/*.a $(BINDIR)/*/ clean-pkg: -@$(foreach dir,$(PKG_PATHS),"$(MAKE)" -C $(dir) distclean $(NEWLINE)) distclean: -@$(foreach dir,$(PKG_PATHS),"$(MAKE)" -C $(dir) distclean $(NEWLINE)) -@rm -rf $(BINDIRBASE) # Include PROGRAMMER_FLASH/PROGRAMMER_RESET variables include $(RIOTMAKE)/tools/programmer.inc.mk # Define flash-recipe with a default value define default-flash-recipe $(call check_cmd,$(FLASHER),Flash program) $(PROGRAMMER_FLASH) endef flash-recipe ?= $(default-flash-recipe) # Do not add dependencies to "flash" directly, use FLASHDEPS, as this is shared # with flash-only too flash: all $(FLASHDEPS) $(flash-recipe) flash-only: $(FLASHDEPS) $(flash-recipe) preflash: $(BUILD_BEFORE_FLASH) $(PREFLASHER_PREFIX)$(PREFLASHER) $(PREFFLAGS) # graphical memory usage analyzer COSY_TOOL ?= $(PKGDIRBASE)/cosy/cosy.py COSY_PORT ?= 12345 cosy: $(ELFFILE) $(COSY_TOOL) $(COSY_TOOL) --port $(COSY_PORT) --riot-base $(RIOTBASE) $(APPDIR) $(BOARD) $(ELFFILE) $(MAPFILE) ifneq (,$(TERMLOG)$(TERMTEE)) TERMTEE ?= | tee -a $(TERMLOG) endif TERMFLASHDEPS ?= $(filter flash flash-only,$(MAKECMDGOALS)) # Add TERMFLASHDEPS to TERMDEPS so it also applies to `test` TERMDEPS += $(TERMFLASHDEPS) termdeps: $(TERMDEPS) term: $(TERMDEPS) $(call check_cmd,$(TERMPROG),Terminal program) ${TERMENV} $(TERMPROG) $(TERMFLAGS) $(TERMTEE) # Term without the pyterm added logging # PYTERMFLAGS must be exported for `jlink.sh term-rtt`. cleanterm: export PYTERMFLAGS += --no-reconnect --noprefix --no-repeat-command-on-empty-line cleanterm: $(TERMDEPS) $(call check_cmd,$(TERMPROG),Terminal program) $(TERMPROG) $(TERMFLAGS) $(TERMTEE) list-ttys: $(Q)$(RIOTTOOLS)/usb-serial/ttys.py doc: $(MAKE) -BC $(RIOTBASE) doc debug: $(DEBUGDEPS) $(call check_cmd,$(DEBUGGER),Debug program) $(DEBUGGER) $(DEBUGGER_FLAGS) debug-client: $(call check_cmd,$(DEBUGCLIENT),Debug client program) $(DEBUGCLIENT) $(DEBUGCLIENT_FLAGS) debug-server: $(call check_cmd,$(DEBUGSERVER),Debug server program) $(DEBUGSERVER) $(DEBUGSERVER_FLAGS) ifeq (1,$(EMULATE)) emulate: $(call check_cmd,$(EMULATOR),Emulation program) $(EMULATOR) $(EMULATOR_FLAGS) endif reset: $(call check_cmd,$(RESET),Reset program) $(PROGRAMMER_RESET) # tests related targets and variables include $(RIOTMAKE)/tests/tests.inc.mk .PHONY: fuzz fuzz: env FLASHFILE="$(FLASHFILE)" PORT="$(PORT)" TERMFLAGS="$(TERMFLAGS)" \ "$(RIOTBASE)"/dist/tools/fuzzing/afl.sh $(FLAGS_FOR_AFL) # Default OBJDUMPFLAGS for platforms which do not specify it: OBJDUMPFLAGS ?= -S -D -h objdump: $(call check_cmd,$(OBJDUMP),Objdump program) $(OBJDUMP) $(OBJDUMPFLAGS) $(ELFFILE) | less # inlcude clang-tidy include $(RIOTMAKE)/clang_tidy.inc.mk # Support Eclipse IDE. include $(RIOTMAKE)/eclipse.inc.mk # Export variables used throughout the whole make system: include $(RIOTMAKE)/vars.inc.mk # Include build targets for selected tools include $(RIOTMAKE)/tools/targets.inc.mk # Checks and defaults for USB Vendor and Product ID include $(RIOTMAKE)/usb-codes.inc.mk # Warn if the selected board and drivers don't provide all needed features: ifneq (, $(filter all flash, $(if $(MAKECMDGOALS), $(MAKECMDGOALS), all))) EXPECT_ERRORS := EXPECT_CONFLICT := # Test if there where dependencies against a module in DISABLE_MODULE. ifneq (, $(filter $(DISABLE_MODULE), $(USEMODULE))) $(shell $(COLOR_ECHO) "$(COLOR_RED)Required modules were disabled using DISABLE_MODULE:$(COLOR_RESET)"\ "$(sort $(filter $(DISABLE_MODULE), $(USEMODULE)))" 1>&2) USEMODULE := $(filter-out $(DISABLE_MODULE), $(USEMODULE)) EXPECT_ERRORS := 1 endif # Test if all feature requirements were met by the selected board. ifneq (,$(FEATURES_MISSING)) $(shell $(COLOR_ECHO) "$(COLOR_RED)There are unsatisfied feature requirements:$(COLOR_RESET)"\ "$(FEATURES_MISSING)" 1>&2) EXPECT_ERRORS := 1 endif # Test if no feature in the requirements used is blacklisted for the selected board. ifneq (,$(FEATURES_USED_BLACKLISTED)) $(shell $(COLOR_ECHO) "$(COLOR_RED)Some feature requirements are blacklisted:$(COLOR_RESET)"\ "$(FEATURES_USED_BLACKLISTED)" 1>&2) EXPECT_ERRORS := 1 endif # Test if any used feature conflict with another one. ifneq (,$(FEATURES_CONFLICTING)) $(shell $(COLOR_ECHO) "$(COLOR_YELLOW)The following features may conflict:$(COLOR_RESET)"\ "$(FEATURES_CONFLICTING)" 1>&2) ifneq (, $(FEATURES_CONFLICT_MSG)) $(shell $(COLOR_ECHO) "$(COLOR_YELLOW)Rationale: $(COLOR_RESET)$(FEATURES_CONFLICT_MSG)" 1>&2) endif EXPECT_CONFLICT := 1 endif # If there is a whitelist, then test if the board is whitelisted. ifneq (, $(BOARD_WHITELIST)) ifeq (, $(filter $(BOARD_WHITELIST), $(BOARD))) $(shell $(COLOR_ECHO) "$(COLOR_RED)The selected BOARD=$(BOARD) is not whitelisted:$(COLOR_RESET) $(BOARD_WHITELIST)" 1>&2) EXPECT_ERRORS := 1 endif endif # If there is a blacklist, then test if the board is blacklisted. ifneq (, $(BOARD_BLACKLIST)) ifneq (, $(filter $(BOARD_BLACKLIST), $(BOARD))) $(shell $(COLOR_ECHO) "$(COLOR_RED)The selected BOARD=$(BOARD) is blacklisted:$(COLOR_RESET) $(BOARD_BLACKLIST)" 1>&2) EXPECT_ERRORS := 1 endif endif # test if toolchain is supported. ifeq (,$(filter $(TOOLCHAIN),$(TOOLCHAINS_SUPPORTED))) $(shell $(COLOR_ECHO) "$(COLOR_RED)The selected TOOLCHAIN=$(TOOLCHAIN) is not supported.$(COLOR_RESET)\nSupported toolchains: $(TOOLCHAINS_SUPPORTED)" 1>&2) EXPECT_ERRORS := 1 endif # If there is a blacklist, then test if the board is blacklisted. ifneq (,$(TOOLCHAINS_BLACKLIST)) ifneq (,$(filter $(TOOLCHAIN),$(TOOLCHAINS_BLACKLIST))) $(shell $(COLOR_ECHO) "$(COLOR_RED)The selected TOOLCHAIN=$(TOOLCHAIN) is blacklisted:$(COLOR_RESET) $(TOOLCHAINS_BLACKLIST)" 1>&2) EXPECT_ERRORS := 1 endif endif ifneq (, $(EXPECT_CONFLICT)) $(shell $(COLOR_ECHO) "\n$(COLOR_YELLOW)EXPECT undesired behaviour!$(COLOR_RESET)" 1>&2) endif # Fail by default when errors are expected CONTINUE_ON_EXPECTED_ERRORS ?= 0 ifneq (, $(EXPECT_ERRORS)) ifneq (1,$(CONTINUE_ON_EXPECTED_ERRORS)) $(error You can let the build continue on expected errors by setting CONTINUE_ON_EXPECTED_ERRORS=1 to the command line) endif $(shell $(COLOR_ECHO) "\n\n$(COLOR_RED)EXPECT ERRORS!$(COLOR_RESET)\n\n" 1>&2) endif endif help: @$(MAKE) -qp | sed -ne 's/\(^[a-z][a-z_-]*\):.*/\1/p' | sort | uniq ifeq (iotlab-m3,$(BOARD)) ifneq (,$(filter iotlab-%,$(MAKECMDGOALS))) include $(RIOTBASE)/dist/testbed-support/Makefile.iotlab endif endif ifneq (,$(filter openv-%,$(MAKECMDGOALS))) include $(RIOTBASE)/dist/tools/openvisualizer/makefile.openvisualizer.inc.mk endif # Include desvirt Makefile include $(RIOTTOOLS)/desvirt/Makefile.desvirt # Build a header file with all common macro definitions and undefinitions # Everytime the header is updated, it will trigger a new compilation. # # The file is created first through a `.in` file that will be modified if # any CFLAGS changed. It depends on FORCE to re-run of the script every time # even if the file exists but the file will only be updated on modifications. # # The header is then created by keeping only the macros. Keeping the # comments added absolute path in the file that screwed caching. # # The rebuild behavior could even only be done with an empty file, but currently # some macros definitions are passed through this file. $(RIOTBUILD_CONFIG_HEADER_C): $(RIOTBUILD_CONFIG_HEADER_C).in $(Q)sed -n -e '1i\ /* Generated file do not edit */' -e '/^#.*/ p' $< > $@ .SECONDARY: $(RIOTBUILD_CONFIG_HEADER_C).in $(RIOTBUILD_CONFIG_HEADER_C).in: FORCE | $(CLEAN) @mkdir -p '$(dir $@)' $(Q)'$(RIOTTOOLS)/genconfigheader/genconfigheader.sh' $(CFLAGS_WITH_MACROS) \ | '$(LAZYSPONGE)' $(LAZYSPONGE_FLAGS) '$@' CFLAGS_WITH_MACROS += $(CFLAGS) CFLAGS_WITH_MACROS += -DRIOT_VERSION=\"$(RIOT_VERSION)\" CFLAGS_WITH_MACROS += -DRIOT_VERSION_CODE=$(RIOT_VERSION_CODE) # MODULE_NAME defines. Declared in 'makefiles/modules.inc.mk' CFLAGS_WITH_MACROS += $(EXTDEFINES) CFLAGS += -include '$(RIOTBUILD_CONFIG_HEADER_C)' # include mcuboot support include $(RIOTMAKE)/mcuboot.mk # include Murdock helpers include $(RIOTMAKE)/murdock.inc.mk # Sanity check, 'all' should be the default goal ifneq (all, $(.DEFAULT_GOAL)) $(error .DEFAULT_GOAL := $(.DEFAULT_GOAL)) endif # Detect if BASELIBS changed since its first use ifneq ($(_BASELIBS_VALUE_BEFORE_USAGE),$(BASELIBS)) $(warning $(sort $(filter-out $(_BASELIBS_VALUE_BEFORE_USAGE), $(BASELIBS)) \ $(filter-out $(BASELIBS), $(_BASELIBS_VALUE_BEFORE_USAGE)))) $(error BASELIBS value changed) endif endif include $(RIOTMAKE)/cargo-targets.inc.mk # include RIOT_MAKEFILES_GLOBAL_POST configuration files # allows setting user specific system wide configuration parsed after the body # of $(RIOTBASE)/Makefile.include include $(RIOT_MAKEFILES_GLOBAL_POST)