# set undefined variables RIOTBASE ?= $(shell dirname "$(lastword $(MAKEFILE_LIST))") export RIOTBASE := $(abspath $(RIOTBASE)) RIOTCPU ?= $(RIOTBASE)/cpu export RIOTCPU := $(abspath $(RIOTCPU)) RIOTBOARD ?= $(RIOTBASE)/boards export RIOTBOARD := $(abspath $(RIOTBOARD)) ifeq ($(strip $(MCU)),) MCU = $(CPU) endif ifeq (,$(filter buildtest,$(MAKECMDGOALS))) ifneq (,$(BOARD_WHITELIST)) ifeq (,$(filter $(BOARD),$(BOARD_WHITELIST))) $(error This application only runs on following boards: $(BOARD_WHITELIST)) endif endif ifneq (,$(filter $(BOARD),$(BOARD_BLACKLIST))) $(error This application does not run on following boards: $(BOARD_BLACKLIST)) endif endif # if you want to publish the board into the sources as an uppercase #define BB = $(shell echo $(BOARD)|tr 'a-z' 'A-Z') CPUDEF = $(shell echo $(CPU)|tr 'a-z' 'A-Z') CFLAGS += -DBOARD=$(BB) -DCPU_$(CPUDEF) # Add `-fno-delete-null-pointer-checks` flag iff the compiler supports it. # GCC removes moves tests whether `x == NULL`, if previously `x` or even `x->y` was accessed. # 0x0 might be a sane memory location for embedded systems, so the test must not be removed. # Right now clang does not use the *delete-null-pointer* optimization, and does not understand the parameter. # Related issues: #628, #664. ifeq ($(shell $(CC) -fno-delete-null-pointer-checks -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0) ifeq ($(shell LANG=C $(CC) -fno-delete-null-pointer-checks -E - 2>&1 1>/dev/null </dev/null | grep warning: | grep -- -fno-delete-null-pointer-checks),) CFLAGS += -fno-delete-null-pointer-checks endif endif export CFLAGS export BINDIR =$(CURDIR)/bin/$(BOARD)/ ifeq ($(QUIET),1) AD=@ else AD= endif export AD BOARD := $(strip $(BOARD)) # mandatory includes! include $(RIOTBASE)/Makefile.modules include $(RIOTBOARD)/$(BOARD)/Makefile.include include $(RIOTCPU)/$(CPU)/Makefile.include include $(RIOTBASE)/Makefile.dep # Test if the input language was specified externally. # Otherwise test if the compiler unterstands the "-std=gnu99" flag, and use it if so. # Otherwise test if the compiler unterstands the "-std=c99" flag, and use it if so. ifeq ($(filter -std=%,$(CFLAGS)),) ifeq ($(shell $(CC) -std=gnu99 -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0) CFLAGS += -std=gnu99 else ifeq ($(shell $(CC) -std=c99 -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0) CFLAGS += -std=c99 endif endif endif # your binaries to link BASELIBS += $(BINDIR)$(BOARD)_base.a BASELIBS += $(BINDIR)${PROJECT}.a BASELIBS += $(USEPKG:%=${BINDIR}%.a) .PHONY: all clean flash doc term ## make script for your project. Build RIOT-base here! all: $(BINDIR)$(PROJECT).a @echo "Building project $(PROJECT) for $(BOARD) w/ MCU $(MCU)." "$(MAKE)" -C $(RIOTBOARD)/$(BOARD) "$(MAKE)" -C $(RIOTBASE) @for i in $(USEPKG) ; do "$(MAKE)" -C $(RIOTBASE)/pkg/$$i ; done ; ifeq ($(BUILDOSXNATIVE),1) $(AD)$(LINK) $(UNDEF) -o $(BINDIR)$(PROJECT).elf $(BASELIBS) $(LINKFLAGS) -Wl,-no_pie else $(AD)$(LINK) $(UNDEF) -o $(BINDIR)$(PROJECT).elf -Wl,--start-group $(BASELIBS) -lm -Wl,--end-group -Wl,-Map=$(BINDIR)$(PROJECT).map $(LINKFLAGS) endif $(AD)$(SIZE) $(BINDIR)$(PROJECT).elf $(AD)$(OBJCOPY) $(OFLAGS) $(BINDIR)$(PROJECT).elf $(BINDIR)$(PROJECT).hex ## your make rules ## Only basic example - modify it for larger projects!! #$(BINDIR)/$(PROJECT).a: $(BINDIR)/$(PROJECT).o # $(AR) -rc $(BINDIR)/project.a $(BINDIR)/$(PROJECT).o # string array of all names of c files in dir SRC = $(wildcard *.c) # string array of all names replaced .c with .o OBJ = $(SRC:%.c=${BINDIR}${PROJECT}/%.o) $(BINDIR)$(PROJECT).a: $(OBJ) $(AD)$(AR) -rc $(BINDIR)$(PROJECT).a $(OBJ) # include Makefile.includes for packages in $(USEPKG) $(RIOTBASE)/pkg/%/Makefile.include:: $(AD)"$(MAKE)" -C $(RIOTBASE)/pkg/$* Makefile.include .PHONY: $(USEPKG:%=$(RIOTBASE)/pkg/%/Makefile.include) -include $(USEPKG:%=$(RIOTBASE)/pkg/%/Makefile.include) # pull in dependency info for *existing* .o files -include $(OBJ:.o=.d) $(BINDIR)$(PROJECT)/%.o: %.c $(PROJDEPS) $(USEPKG:%=${BINDIR}%.a) @mkdir -p ${BINDIR} @echo; echo "Compiling.... $*.c"; echo @test -d $(BINDIR)$(PROJECT) || mkdir -p $(BINDIR)$(PROJECT) $(AD)$(CC) $(CFLAGS) $(INCLUDES) -c $*.c -o $(BINDIR)$(PROJECT)/$*.o $(USEPKG:%=${BINDIR}%.a):: @mkdir -p ${BINDIR} "$(MAKE)" -C $(RIOTBASE)/pkg/$(patsubst ${BINDIR}%.a,%,$@) clean: @for i in $(USEPKG) ; do "$(MAKE)" -C $(RIOTBASE)/pkg/$$i clean ; done ; "$(MAKE)" -C $(RIOTBOARD)/$(BOARD) clean "$(MAKE)" -C $(RIOTBASE) clean rm -rf $(BINDIR) flash: all $(FLASHER) $(FFLAGS) term: $(TERMPROG) $(PORT) doc: make -BC $(RIOTBASE) doc debug: $(DEBUGGER) $(DEBUGGER_FLAGS) buildtest: @if [ -z "$${JENKINS_URL}" ] && tput colors 2>&1 > /dev/null; then \ GREEN='\033[1;32m'; RED='\033[1;31m'; RESET='\033[0m'; \ ECHO='echo -e'; \ else \ GREEN=''; RED=''; RESET=''; \ ECHO='echo'; \ fi; \ \ if [ -z "$(BOARD_WHITELIST)" ]; then \ BOARDS=$$(find $(RIOTBOARD) -mindepth 1 -maxdepth 1 -type d \! -name \*-common -printf '%f\n' ); \ else \ BOARDS="$(BOARD_WHITELIST)"; \ fi; \ \ for BOARD in $(BOARD_BLACKLIST); do \ echo "Ignoring $${BOARD} (blacklisted)"; \ BOARDS=$$(echo \ $${BOARDS}\ | sed -e 's/ '$${BOARD}' / /'); \ done; \ \ for BOARD in $${BOARDS}; do \ $${ECHO} -n "Building for $${BOARD} .. "; \ env -i \ HOME=$${HOME} \ PATH=$${PATH} \ BOARD=$${BOARD} \ RIOTBASE=$${RIOTBASE} \ RIOTBOARD=$${RIOTBOARD} \ RIOTCPU=$${RIOTCPU} \ $(MAKE) -B clean all >/dev/null 2>&1 ; \ if [ "$${?}" = "0" ]; then \ $${ECHO} "$${GREEN}success$${RESET}"; \ else \ $${ECHO} "$${RED}failed$${RESET}"; \ BUILDTESTFAILED=1; \ fi; \ done; \ if [ "$${BUILDTESTFAILED}" = "1" ]; then \ exit 1; \ fi