Skip to content
Snippets Groups Projects
Makefile.include 17.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • # include Makefile.local if it exists
    -include Makefile.local
    
    
    RIOTBASE       ?= $(dir $(lastword $(MAKEFILE_LIST)))
    
    CCACHE_BASEDIR ?= $(RIOTBASE)
    
    RIOTCPU        ?= $(RIOTBASE)/cpu
    RIOTBOARD      ?= $(RIOTBASE)/boards
    RIOTPKG        ?= $(RIOTBASE)/pkg
    RIOTPROJECT    ?= $(shell git rev-parse --show-toplevel 2>/dev/null || pwd)
    GITCACHE       ?= $(RIOTBASE)/dist/tools/git/git-cache
    APPDIR         ?= $(CURDIR)
    BINDIRBASE     ?= $(APPDIR)/bin
    BINDIR         ?= $(BINDIRBASE)/$(BOARD)
    
    __DIRECTORY_VARIABLES := RIOTBASE CCACHE_BASEDIR RIOTCPU RIOTBOARD RIOTPKG GITCACHE RIOTPROJECT APPDIR BINDIRBASE BINDIR
    
    # Make all paths absolute.
    override RIOTBASE       := $(abspath $(RIOTBASE))
    override CCACHE_BASEDIR := $(abspath $(CCACHE_BASEDIR))
    override RIOTCPU        := $(abspath $(RIOTCPU))
    override RIOTBOARD      := $(abspath $(RIOTBOARD))
    override RIOTPKG        := $(abspath $(RIOTPKG))
    override RIOTPROJECT    := $(abspath $(RIOTPROJECT))
    override GITCACHE       := $(abspath $(GITCACHE))
    
    override APPDIR         := $(abspath $(APPDIR))
    
    override BINDIRBASE     := $(abspath $(BINDIRBASE))
    
    override BINDIR         := $(abspath $(BINDIR))
    
    
    # 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
    
    # Use absolute paths in recusive "make" even if overriden on command line.
    MAKEOVERRIDES += $(foreach v,${__DIRECTORY_VARIABLES},${v}=${${v}})
    
    # Path to the current directory relative to RIOTPROJECT
    BUILDRELPATH ?= ${PWD:${RIOTPROJECT}/%=%}/
    
    # 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 $(RIOTBASE)/Makefile.docker
    
    
    # Static code analysis tools provided by LLVM
    include $(RIOTBASE)/Makefile.scan-build
    
    
    export RIOTBUILD_CONFIG_HEADER_C = $(BINDIR)/riotbuild/riotbuild.h
    
    COLOR_GREEN  :=
    COLOR_RED    :=
    COLOR_PURPLE :=
    COLOR_RESET  :=
    COLOR_ECHO   := /bin/echo
    
    ifeq (0,  $(shell tput colors 2>&1 > /dev/null; echo $$?))
      COLOR_GREEN  := \033[1;32m
      COLOR_RED    := \033[1;31m
      COLOR_YELLOW := \033[1;33m
      COLOR_PURPLE := \033[1;35m
      COLOR_RESET  := \033[0m
      ifeq ($(OS),Darwin)
        COLOR_ECHO   := echo -e
        SHELL=bash
      else
        COLOR_ECHO   := /bin/echo -e
    
      endif
    endif
    
    ifeq ($(OS),Darwin)
      OPEN   := open
    else
      OPEN   := xdg-open
    endif
    
    
    ifeq ($(QUIET),1)
    
      MAKEFLAGS += --no-print-directory
    
    endif
    
    # Fail on warnings. Can be overridden by `make WERROR=0`.
    WERROR ?= 1
    export WERROR
    ifeq ($(WERROR),1)
      CFLAGS += -Werror
    
    ifneq (10,$(if ${RIOT_VERSION},1,0)$(if ${__RIOTBUILD_FLAG},1,0))
    
    # Provide a shallow sanity check. You cannot call `make` in a module directory.
    export __RIOTBUILD_FLAG := RIOT
    
    
    Oleg Hahm's avatar
    Oleg Hahm committed
    BOARD := $(strip $(BOARD))
    
    APPLICATION := $(strip $(APPLICATION))
    
    Oleg Hahm's avatar
    Oleg Hahm committed
    
    
    # provide common external programs for `Makefile.include`s
    
    
    ifeq (,$(and $(DOWNLOAD_TO_STDOUT),$(DOWNLOAD_TO_FILE)))
      ifeq (,$(WGET))
        ifeq (0,$(shell which wget 2>&1 > /dev/null ; echo $$?))
          WGET := $(shell which wget)
        endif
    
      ifeq (,$(CURL))
        ifeq (0,$(shell which curl 2>&1 > /dev/null ; echo $$?))
          CURL := $(shell which curl)
        endif
    
      ifeq (,$(WGET)$(CURL))
        $(error Neither wget nor curl is installed!)
    
      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 2>&1 > /dev/null ; echo $$?))
        UNZIP_HERE := $(shell which unzip) -q
      else
        ifeq (0,$(shell which 7z 2>&1 > /dev/null ; echo $$?))
          UNZIP_HERE := $(shell which 7z) x -bd
        else
          $(error Neither unzip nor 7z is installed.)
        endif
      endif
    endif
    
    
    ifeq (, ${APPLICATION})
        $(error An application name must be specified as APPLICATION.)
    endif
    
    ifneq (0,$(shell test -d $(RIOTBOARD)/$(BOARD); echo $$?))
        $(error The specified board $(BOARD) does not exist.)
    endif
    
    
    # Use TOOLCHAIN environment variable to select the toolchain to use.
    # Default: gnu
    TOOLCHAIN ?= gnu
    
    # TOOLCHAIN = clang is an alias for TOOLCHAIN = llvm
    ifeq (clang,$(TOOLCHAIN))
    # use override so that we can redefine a variable set on the command line (as
    # opposed to one set in the environment)
    override TOOLCHAIN := llvm
    endif
    # TOOLCHAIN = gcc is an alias for TOOLCHAIN = gnu
    ifeq (gcc,$(TOOLCHAIN))
    # use override so that we can redefine a variable set on the command line (as
    # opposed to one set in the environment)
    override TOOLCHAIN := gnu
    endif
    
    ifeq (,$(TOOLCHAIN))
    override TOOLCHAIN := gnu
    endif
    
    export TOOLCHAIN
    
    
    # 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)-)
    
    
    # Import all toolchain settings
    include $(RIOTCPU)/Makefile.include.$(TOOLCHAIN)
    
    
    # Add standard include directories
    INCLUDES += -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/include
    INCLUDES += -I$(RIOTCPU)/$(CPU)/include
    INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include
    
    
    include $(RIOTBASE)/Makefile.pseudomodules
    include $(RIOTBASE)/Makefile.defaultmodules
    
    include $(RIOTBOARD)/$(BOARD)/Makefile.include
    
    include $(RIOTCPU)/$(CPU)/Makefile.include
    
    
    # get number of interfaces straight before resolving dependencies
    
    GNRC_NETIF_NUMOF ?= 1
    
    ifneq ($(GNRC_NETIF_NUMOF),1)
      CFLAGS += -DGNRC_NETIF_NUMOF=$(GNRC_NETIF_NUMOF)
    
    include $(RIOTBASE)/Makefile.dep
    
    USEMODULE += $(filter-out $(DISABLE_MODULE), $(DEFAULT_MODULE))
    
    
    ifeq ($(strip $(MCU)),)
    	MCU = $(CPU)
    endif
    
    
    # set some settings useful for continuous integration builds
    ifeq ($(RIOT_CI_BUILD),1)
        RIOT_VERSION_OVERRIDE:=buildtest
        ifneq ($(filter $(BOARD_INSUFFICIENT_MEMORY), $(BOARD)),)
            $(info CI-build: skipping link step)
            RIOTNOLINK:=1
        endif
    endif
    
    
    # if you want to publish the board into the sources as an uppercase #define
    BOARDDEF := $(shell echo $(BOARD) | tr 'a-z' 'A-Z' | tr '-' '_')
    CPUDEF := $(shell echo $(CPU) | tr 'a-z' 'A-Z' | tr '-' '_')
    MCUDEF := $(shell echo $(MCU) | tr 'a-z' 'A-Z' | tr '-' '_')
    
    CFLAGS += -DBOARD_$(BOARDDEF)=\"$(BOARD)\" -DRIOT_BOARD=BOARD_$(BOARDDEF)
    CFLAGS += -DCPU_$(CPUDEF)=\"$(CPU)\" -DRIOT_CPU=CPU_$(CPUDEF)
    CFLAGS += -DMCU_$(MCUDEF)=\"$(MCU)\" -DRIOT_MCU=MCU_$(MCUDEF)
    
    # OSX fails to create empty archives. Provide a wrapper to catch that error.
    
    ifneq (0, $(shell mkdir -p $(BINDIR); $(AR) rc $(BINDIR)/empty-archive.a 2> /dev/null; \
                echo $$?; rm -f $(BINDIR)/empty-archive.a 2>&1 > /dev/null))
    
    	AR := $(RIOTBASE)/dist/ar-wrapper $(AR)
    endif
    
    
    # Feature test default CFLAGS and LINKFLAGS for the set compiled.
    include $(RIOTBASE)/Makefile.cflags
    
    # make the RIOT version available to the program
    
    ifeq ($(origin RIOT_VERSION), undefined)
    
      GIT_STRING := $(shell git --git-dir="$(RIOTBASE)/.git" describe --always --abbrev=4 --dirty=-`hostname` 2> /dev/null)
    
      ifneq (,$(GIT_STRING))
    
        GIT_BRANCH := $(shell git --git-dir="$(RIOTBASE)/.git" rev-parse --abbrev-ref HEAD)
    
        ifeq ($(strip $(GIT_BRANCH)),master)
          RIOT_VERSION := $(GIT_STRING)
        else
          RIOT_VERSION := $(GIT_STRING)-$(GIT_BRANCH)
        endif
    
    Oleg Hahm's avatar
    Oleg Hahm committed
        RIOT_VERSION := 'UNKNOWN (builddir: $(RIOTBASE))'
    
    René Kijewski's avatar
    René Kijewski committed
    # the binaries to link
    
    BASELIBS += $(BINDIR)/${APPLICATION}.a
    
    BASELIBS += $(APPDEPS)
    
    .PHONY: all clean flash term doc debug debug-server reset objdump help info-modules
    
    .PHONY: ..in-docker-container
    
    ELFFILE ?= $(BINDIR)/$(APPLICATION).elf
    
    HEXFILE ?= $(ELFFILE:.elf=.hex)
    
    René Kijewski's avatar
    René Kijewski committed
    
    
    # variables used to compile and link c++
    
    CPPMIX ?= $(if $(wildcard *.cpp),1,)
    
    # We assume $(LINK) to be gcc-like. Use `LINKFLAGPREFIX :=` for ld-like linker options.
    LINKFLAGPREFIX ?= -Wl,
    
    
    ifeq ($(BUILD_IN_DOCKER),1)
    all: ..in-docker-container
    else
    
    ## make script for your application. Build RIOT-base here!
    
    all: ..compiler-check ..build-message $(RIOTBUILD_CONFIG_HEADER_C) $(USEPKG:%=${BINDIR}/%.a) $(APPDEPS)
    
    	$(Q)DIRS="$(DIRS)" "$(MAKE)" -C $(APPDIR) -f $(RIOTBASE)/Makefile.application
    
    ifeq (,$(RIOTNOLINK))
    
    René Kijewski's avatar
    René Kijewski committed
    ifeq ($(BUILDOSXNATIVE),1)
    
    	$(Q)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) $$(find $(BASELIBS) -size +8c) $(LINKFLAGS) $(LINKFLAGPREFIX)-no_pie
    
    René Kijewski's avatar
    René Kijewski committed
    else
    
    	$(Q)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) $(LINKFLAGPREFIX)--start-group $(BASELIBS) -lm $(LINKFLAGPREFIX)--end-group  $(LINKFLAGPREFIX)-Map=$(BINDIR)/$(APPLICATION).map $(LINKFLAGPREFIX)--cref $(LINKFLAGS)
    
    René Kijewski's avatar
    René Kijewski committed
    endif
    
    	$(Q)$(SIZE) $(ELFFILE)
    	$(Q)$(OBJCOPY) $(OFLAGS) $(ELFFILE) $(HEXFILE)
    
    endif # BUILD_IN_DOCKER
    
    ..compiler-check:
    
    	@command -v $(CC) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Compiler $(CC) is required but not found in PATH.  Aborting.${COLOR_RESET}'; \
    
    	@$(COLOR_ECHO) '${COLOR_GREEN}Building application "$(APPLICATION)" for "$(BOARD)" with MCU "$(MCU)".${COLOR_RESET}'
    	@$(COLOR_ECHO)
    
    # add extra include paths for packages in $(USEMODULE)
    export USEMODULE_INCLUDES =
    
    include $(RIOTBASE)/sys/Makefile.include
    include $(RIOTBASE)/drivers/Makefile.include
    
    
    # The `clean` needs to be serialized before everything else.
    ifneq (, $(filter clean, $(MAKECMDGOALS)))
    
        all $(BASELIBS) $(USEPKG:%=$(RIOTPKG)/%/Makefile.include) $(RIOTBUILD_CONFIG_HEADER_C): clean
    
    # include Makefile.includes for packages in $(USEPKG)
    
    $(RIOTPKG)/%/Makefile.include::
    
    	$(Q)"$(MAKE)" -C $(RIOTPKG)/$* Makefile.include
    
    .PHONY: $(USEPKG:%=$(RIOTPKG)/%/Makefile.include)
    -include $(USEPKG:%=$(RIOTPKG)/%/Makefile.include)
    
    USEMODULE_INCLUDES_ = $(shell echo $(USEMODULE_INCLUDES) | tr ' ' '\n' | awk '!a[$$0]++' | tr '\n' ' ')
    
    INCLUDES += $(USEMODULE_INCLUDES_:%=-I%)
    
    
    .PHONY: $(USEPKG:%=${BINDIR}/%.a)
    $(USEPKG:%=${BINDIR}/%.a): $(RIOTBUILD_CONFIG_HEADER_C)
    
    	@mkdir -p ${BINDIR}
    
    	"$(MAKE)" -C $(RIOTPKG)/$(patsubst ${BINDIR}/%.a,%,$@)
    
    	-@for i in $(USEPKG) ; do "$(MAKE)" -C $(RIOTPKG)/$$i clean ; done
    
    	-@rm -rf $(BINDIR)
    
    	-@rm -rf $(SCANBUILD_OUTPUTDIR)
    
    # Remove intermediates, but keep the .elf, .hex and .map etc.
    clean-intermediates:
    
    	-@for i in $(USEPKG) ; do "$(MAKE)" -C $(RIOTPKG)/$$i distclean ; done
    
    	-@rm -rf $(BINDIR)/*.a $(BINDIR)/*/
    
    
    clean-pkg:
    	-@for i in $(USEPKG) ; do "$(MAKE)" -C $(RIOTPKG)/$$i distclean ; done
    
    
    	-@for i in $(USEPKG) ; do "$(MAKE)" -C $(RIOTPKG)/$$i distclean ; done
    
    	-@rm -rf $(BINDIRBASE)
    
    	@command -v $(FLASHER) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Flash program $(FLASHER) not found. Aborting.${COLOR_RESET}'; \
    
    		exit 1; }
    
    	$(FLASHER) $(FFLAGS)
    
    term: $(filter flash, $(MAKECMDGOALS))
    
    	@command -v $(TERMPROG) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Terminal program $(TERMPROG) not found. Aborting.${COLOR_RESET}'; \
    
    		exit 1; }
    
    Martine Lenders's avatar
    Martine Lenders committed
    	$(TERMPROG) $(TERMFLAGS)
    
    	$(Q)$(RIOTBASE)/dist/tools/usb-serial/list-ttys.sh
    
    doc:
    	make -BC $(RIOTBASE) doc
    
    	@command -v $(DEBUGGER) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Debug program $(DEBUGGER) not found. Aborting.${COLOR_RESET}'; \
    
    		exit 1; }
    
    	$(DEBUGGER) $(DEBUGGER_FLAGS)
    
    	@command -v $(DEBUGSERVER) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Debug server program $(DEBUGSERVER) not found. Aborting.${COLOR_RESET}'; \
    
    		exit 1; }
    
    	$(DEBUGSERVER) $(DEBUGSERVER_FLAGS)
    
    reset:
    
    	@command -v $(RESET) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Reset program $(RESET) not found. Aborting.${COLOR_RESET}'; \
    
    		exit 1; }
    
    	$(RESET) $(RESET_FLAGS)
    
    
    # Default OBJDUMPFLAGS for platforms which do not specify it:
    OBJDUMPFLAGS ?= -S -D -h
    
    
    objdump:
    
    	@command -v $(OBJDUMP) >/dev/null 2>&1 || \
    
    		{ $(COLOR_ECHO) \
    
    Toon Stegen's avatar
    Toon Stegen committed
    		'${COLOR_RED}Objdump program $(OBJDUMP) not found. Aborting.${COLOR_RESET}'; \
    
    		exit 1; }
    
    	$(OBJDUMP) $(OBJDUMPFLAGS) $(ELFFILE) | less
    
    # Generate an XML file containing all macro definitions and include paths for
    # use in Eclipse CDT
    .PHONY: eclipsesym eclipsesym.xml $(CURDIR)/eclipsesym.xml
    eclipsesym: $(CURDIR)/eclipsesym.xml
    eclipsesym.xml: $(CURDIR)/eclipsesym.xml
    
    $(CURDIR)/eclipsesym.xml:
    
    	$(Q)printf "%s\n" $(CC) $(CFLAGS_WITH_MACROS) $(INCLUDES) | \
    
    		$(RIOTBASE)/dist/tools/eclipsesym/cmdline2xml.sh > $@
    
    
    # Extra make goals for testing and comparing changes.
    include $(RIOTBASE)/Makefile.buildtests
    
    # import list of provided features
    -include $(RIOTBOARD)/$(BOARD)/Makefile.features
    
    
    # Export variables used throughout the whole make system:
    include $(RIOTBASE)/Makefile.vars
    
    Cenk Gündoğan's avatar
    Cenk Gündoğan committed
    # Warn if the selected board and drivers don't provide all needed features:
    
    ifneq (, $(filter all, $(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 (, $(filter-out $(FEATURES_PROVIDED) $(FEATURES_OPTIONAL), $(FEATURES_REQUIRED)))
    
        $(shell $(COLOR_ECHO) "$(COLOR_RED)There are unsatisfied feature requirements:$(COLOR_RESET)"\
    
                              "$(sort $(filter-out $(FEATURES_PROVIDED) $(FEATURES_OPTIONAL), $(FEATURES_REQUIRED)))" 1>&2)
    
      # Test if any required feature conflict with another one.
      CONFLICT := $(foreach var,$(FEATURES_CONFLICT),$(if $(filter $(words $(subst :, ,$(var))),$(words $(filter $(FEATURES_REQUIRED),$(subst :, ,$(var))))),$(subst :, ,$(var))))
      ifneq (, $(strip $(CONFLICT)))
        $(shell $(COLOR_ECHO) "$(COLOR_YELLOW)The following features may conflict:$(COLOR_RESET)"\
                              "$(COLOR_GREEN)$(sort $(filter $(FEATURES_REQUIRED), $(CONFLICT)))$(COLOR_RESET)" 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
    
    
      ifneq (, $(EXPECT_CONFLICT))
        $(shell $(COLOR_ECHO) "\n$(COLOR_YELLOW)EXPECT undesired behaviour!$(COLOR_RESET)" 1>&2)
      endif
    
    
      ifneq (, $(EXPECT_ERRORS))
        $(shell $(COLOR_ECHO) "\n\n$(COLOR_RED)EXPECT ERRORS!$(COLOR_RESET)\n\n" 1>&2)
      endif
    
    
    else # RIOT_VERSION
    
      export __RIOTBUILD_FLAG := RIOT
    
      NUM_RIOT_VERSION := $(shell cd $(RIOTBASE) && git rev-parse --verify --short "$(RIOT_VERSION)" 2>/dev/null)
      ifeq (, ${NUM_RIOT_VERSION})
        $(error The supplied RIOT_VERSION=$(RIOT_VERSION) is invalid!)
      endif
    
      all $(filter-out clean, ${MAKECMDGOALS}): ..delegate
      ifneq (, $(filter clean, $(MAKECMDGOALS)))
        all $(filter-out clean, ${MAKECMDGOALS}): clean
      endif
    
      clean:
    
    	-$(Q)rm -rf $(BINDIR)
    
      $(BINDIR)/riot-version/$(NUM_RIOT_VERSION)/Makefile.include:
    
    	$(Q)rm -rf $(@D)
    	$(Q)mkdir -p $(@D)
    	$(Q)cd $(RIOTBASE) && git archive --format=tar $(NUM_RIOT_VERSION) | ( cd $(@D) && tar x 1>&2 )
    
      ..delegate: $(BINDIR)/riot-version/$(NUM_RIOT_VERSION)/Makefile.include
    
    	@$(COLOR_ECHO) '$(COLOR_GREEN)Using RIOT_VERSION=${NUM_RIOT_VERSION}$(COLOR_RESET)' 1>&2
    	@$(COLOR_ECHO)
    	$(MAKE) RIOTBASE=$(<D) $(filter-out clean, ${MAKECMDGOALS})
    
    endif
    
    
    help:
    	@$(MAKE) -qp | sed -ne 's/\(^[a-z][a-z_-]*\):.*/\1/p' | sort | uniq
    
    info-modules:
    	@for i in $(sort $(USEMODULE)); do echo $$i; done
    
    
    ifneq (,$(filter iotlab-m3 wsn430-v1_3b wsn430-v1_4,$(BOARD)))
    
      ifneq (,$(filter iotlab-%,$(MAKECMDGOALS)))
        include $(RIOTBASE)/dist/testbed-support/Makefile.iotlab
      endif
    
    
    # Include desvirt Makefile
    include $(RIOTBASE)/dist/tools/desvirt/Makefile.desvirt
    
    
    # include bindist target
    include $(RIOTBASE)/Makefile.bindist
    
    # Add all USEMODULE modules to CFLAGS
    include $(RIOTBASE)/Makefile.modules
    
    
    # Build a header file with all common macro definitions and undefinitions
    # make it phony to force re-run of the script every time even if the file exists
    # The script will only touch the file if anything has changed since last time.
    .PHONY: $(RIOTBUILD_CONFIG_HEADER_C)
    $(RIOTBUILD_CONFIG_HEADER_C):
    	@mkdir -p '$(dir $@)'
    
    	$(Q)'$(RIOTBASE)/dist/tools/genconfigheader/genconfigheader.sh' '$@' $(CFLAGS_WITH_MACROS)
    
    CFLAGS_WITH_MACROS := $(CFLAGS)
    
    
    export CFLAGS_WITH_MACROS += -DRIOT_VERSION=\"$(RIOT_VERSION_OVERRIDE)\"
    
    export CFLAGS_WITH_MACROS += -DRIOT_VERSION=\"$(RIOT_VERSION)\"
    
    
    CFLAGS := $(patsubst -D%,,$(CFLAGS))
    CFLAGS := $(patsubst -U%,,$(CFLAGS))
    CFLAGS += -include '$(RIOTBUILD_CONFIG_HEADER_C)'