mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-13 08:40:26 +01:00
f166e74696
When the build system is aware of an invalid configuration - such as multiple C libs being used or a single piece of hardware being used in two conflicting roles - this now is treated as an error rather than a warning.
1090 lines
37 KiB
Makefile
1090 lines
37 KiB
Makefile
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.
|
|
ifneq (,$(filter native native64,$(BOARD)))
|
|
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
|
|
|
|
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
|
|
|
|
# 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
|
|
|
|
# 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)))
|
|
$(warning '$(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
|
|
|
|
# Other than on native, RWX segments in ROM are not actually RWX, as regular
|
|
# store instructions won't write to flash.
|
|
ifeq (,$(filter native native64,$(BOARD)))
|
|
LINKER_SUPPORTS_NOWARNRWX ?= $(shell LC_ALL=C $(LINK) $(RIOTTOOLS)/testprogs/minimal_linkable.c -o /dev/null -lc -Wall -Wextra -pedantic -Wl,--no-warn-rwx-segments 2> /dev/null && echo 1 || echo 0)
|
|
ifeq (1,$(LINKER_SUPPORTS_NOWARNRWX))
|
|
LINKFLAGS += -Wl,--no-warn-rwx-segments
|
|
endif
|
|
endif
|
|
|
|
# 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
|
|
|
|
# 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))
|
|
CFLAGS += -DRIOT_APPLICATION=\"$(APPLICATION)\"
|
|
CFLAGS += -DBOARD_$(BOARDDEF)=\"$(BOARD)\" -DRIOT_BOARD=BOARD_$(BOARDDEF)
|
|
CFLAGS += -DCPU_$(CPUDEF)=\"$(CPU)\" -DRIOT_CPU=CPU_$(CPUDEF)
|
|
|
|
# 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)
|
|
|
|
# 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)
|
|
|
|
# include makefile snippets for packages in $(PKG_PATHS) that modify GENSRC:
|
|
-include $(PKG_PATHS:%=%Makefile.gensrc)
|
|
# remove duplicates & make accessible to subprocesses
|
|
GENSRC := $(sort $(GENSRC))
|
|
export GENSRC
|
|
|
|
# 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: $(COMPILE_COMMANDS_PATH)
|
|
%/compile_commands.json: $(BUILDDEPS)
|
|
$(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \
|
|
APPLICATION_SRC="$(SRC)" APPLICATION_SRCXX="$(SRCXX)" APPLICATION_ASMSRC="$(ASMSRC)" APPLICATION_ASSMSRC="$(ASSMSRC)" \
|
|
"$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk compile-commands
|
|
$(Q)$(RIOTTOOLS)/compile_commands/compile_commands.py $(COMPILE_COMMANDS_FLAGS) $(BINDIR) \
|
|
> $@
|
|
|
|
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)" \
|
|
APPLICATION_SRC="$(SRC)" APPLICATION_SRCXX="$(SRCXX)" APPLICATION_ASMSRC="$(ASMSRC)" APPLICATION_ASSMSRC="$(ASSMSRC)" \
|
|
"$(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 $(GENSRC)
|
|
|
|
# 'print-size' triggers a rebuild. Use 'info-buildsize' if you do not need to rebuild.
|
|
print-size: $(ELFFILE)
|
|
$(Q)$(SIZE) $(SIZEFLAGS) $<
|
|
|
|
%.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 CPU "$(CPU)".$(COLOR_RESET)'
|
|
@$(COLOR_ECHO)
|
|
|
|
# The `clean` needs to be serialized before everything else.
|
|
all $(BASELIBS) $(ARCHIVES) $(BUILDDEPS) $(GENSRC) ..in-docker-container: | $(CLEAN)
|
|
|
|
.PHONY: pkg-prepare pkg-build
|
|
pkg-prepare:
|
|
-@$(foreach dir,$(PKG_PATHS),"$(MAKE)" -C $(dir) prepare $(NEWLINE))
|
|
|
|
$(GENSRC): pkg-prepare
|
|
|
|
pkg-build: $(BUILDDEPS) | $(GENSRC)
|
|
$(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 :=
|
|
|
|
# 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_RED)The following features 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_ERRORS := 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
|
|
|
|
# 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:
|
|
# filter all targets starting with lowercase and containing lowercase letters, hyphens, or underscores; explicitly include generate-Makefile.ci
|
|
@$(MAKE) -qp | sed -ne 's/\(^[a-z][a-z_-]*\|generate-Makefile.ci\):.*/\1/p' | sort -u
|
|
|
|
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)
|
|
ifneq (,$(RIOT_VERSION_EXTRA))
|
|
CFLAGS_WITH_MACROS += -DCONFIG_RIOT_VERSION_EXTRA=\""$(RIOT_VERSION_EXTRA)"\"
|
|
endif
|
|
# 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)
|