blob: e266f6b0fda892503dfc6a4f92b6ae8ca46487d9 [file] [log] [blame]
# Error on any uset variable
MAKEFLAGS=--warn-undefined-variables
# Default to a silent build. Run make with --trace for a verbose build.
.SILENT:
# Mac and Linux stat have different options required, set them up here
ifeq ($(shell uname), Darwin)
STAT = "stat -f '%z'"
else
STAT = "stat -c '%s'"
endif
BOARD ?= qemu_mps2_an385
$(info Building for $(BOARD))
# Set to 1 to build with templates/memfault_platform_port.c instead of
# FreeRTOS platform functions. Used to test compilation with template files
MEMFAULT_TEST_USE_PORT_TEMPLATE ?= 0
ifeq ($(MEMFAULT_TEST_USE_PORT_TEMPLATE),1)
ifneq (qemu_mps2_an385,$(BOARD))
$(error Testing with the template port only supported on the qemu_mps2_an385 board)
endif
endif
BOARD_DIR := boards/$(BOARD)
BUILD_DIR := build/$(BOARD)
ELF = $(BUILD_DIR)/main.elf
ARM_CC ?= arm-none-eabi-gcc
ARM_CXX ?= arm-none-eabi-g++
# if cc isn't set by the user, set it to ARM_CC
ifeq ($(origin CC),default)
CC := $(ARM_CC)
CXX := $(ARM_CXX)
endif
# use ccache if available
CCACHE := $(shell command -v ccache 2> /dev/null)
ifdef CCACHE
CC := ccache $(CC)
CXX := ccache $(CXX)
endif
OBJCOPY ?= $(shell $(CC) -print-prog-name=objcopy)
SIZE ?= $(shell $(CC) -print-prog-name=size)
READELF ?= $(shell $(CC) -print-prog-name=readelf)
# Check if FreeRTOS location set, add rule to download if not
FREERTOS_DIR ?=
ifeq ($(FREERTOS_DIR),)
FREERTOS_DIR = FreeRTOS-Kernel
FREERTOS_VER = V11.2.0
FREERTOS_SHA = 0adc196d4bd52a2d91102b525b0aafc1e14a2386
# Verify the FreeRTOS directory is present and matches expected SHA
FREERTOS_STALE = \
$(shell \
if ! (echo "$(FREERTOS_SHA)" | diff -q $(FREERTOS_DIR)/.git/HEAD - > /dev/null 2>&1); then \
echo FREERTOS_STALE; \
fi \
)
.PHONY: FREERTOS_STALE
$(FREERTOS_DIR)/.git/HEAD: $(FREERTOS_STALE)
$(info FREERTOS_DIR needs updating, deleting stale copy (if present) and fetching from git)
rm -rf $(FREERTOS_DIR)
git -c advice.detachedHead=false clone --branch $(FREERTOS_VER) --depth 1 https://github.com/FreeRTOS/FreeRTOS-Kernel.git $(FREERTOS_DIR)
.DEFAULT_GOAL :=
endif
include $(BOARD_DIR)/Makefile
# Gather list of FreeRTOS sources
FREERTOS_SRCS += \
$(FREERTOS_DIR)/tasks.c \
$(FREERTOS_DIR)/queue.c \
$(FREERTOS_DIR)/list.c \
$(FREERTOS_DIR)/timers.c \
$(FREERTOS_DIR)/portable/MemMang/heap_4.c \
# Add application sources
SRCS += \
src/main.c \
src/compact_log.cpp \
src/console.c \
src/heap_task.c \
src/metrics.c \
src/mpu.c \
src/memfault/memfault_platform_port.c \
$(BOARD_DIR)/startup.c \
$(BOARD_DIR)/memfault_platform_impl.c \
$(FREERTOS_SRCS) \
# Use Memfault SDK worker to gather initial Memfault SDK sources and include dirs
MEMFAULT_SDK_ROOT := ../..
MEMFAULT_COMPONENTS ?= core util panics metrics demo
include $(MEMFAULT_SDK_ROOT)/makefiles/MemfaultWorker.mk
# Add CFLAGS defines for each of the memfault components enabled above
CFLAGS += $(foreach each, $(MEMFAULT_COMPONENTS), -DMEMFAULT_COMPONENT_$(each)_)
# Add additional SDK sources to project for FreeRTOS and RAM-backed coredump.
# Intentionally using a wildcard to trap any new features added- it's nice to
# have them enabled in this example app.
SRCS += \
$(MEMFAULT_COMPONENTS_SRCS) \
$(MEMFAULT_SDK_ROOT)/ports/panics/src/memfault_platform_ram_backed_coredump.c \
ifneq ($(MEMFAULT_TEST_USE_PORT_TEMPLATE), 1)
SRCS += \
$(wildcard $(MEMFAULT_SDK_ROOT)/ports/freertos/src/*.c)
endif
# Fixup build path for objects of the Memfault SDK, all build output kept within build/
OBJS := $(subst $(MEMFAULT_SDK_ROOT),memfault-firmware-sdk,$(SRCS:%=$(BUILD_DIR)/%.o))
INCLUDE_PATHS += \
-I$(FREERTOS_DIR)/include \
-I. \
-Isrc \
-Isrc/memfault \
-I$(MEMFAULT_COMPONENTS_INC_FOLDERS) \
-I$(MEMFAULT_SDK_ROOT)/ports/include \
-I$(MEMFAULT_SDK_ROOT) \
-I$(FREERTOS_DIR)/portable/GCC/$(FREERTOS_PORT) \
# generic (non-arch-specific) CFLAGS
CFLAGS += \
-nostartfiles \
-Werror \
-Wall \
-Wextra \
-Werror=undef \
-ffunction-sections \
-fdata-sections \
-ggdb3 \
-Og \
-MD \
-fdebug-prefix-map="$(shell pwd)"=. \
-DBOARD=\"$(BOARD)\" \
$(ARCH_CFLAGS) \
# Enable the self test by default
MEMFAULT_DEMO_CLI_SELF_TEST ?= 1
CFLAGS += \
-DMEMFAULT_DEMO_CLI_SELF_TEST=$(MEMFAULT_DEMO_CLI_SELF_TEST) \
-DMEMFAULT_TEST_USE_PORT_TEMPLATE=$(MEMFAULT_TEST_USE_PORT_TEMPLATE)
LINKER_SCRIPT = $(BOARD_DIR)/linker.ld
LDFLAGS += \
-Wl,-T$(LINKER_SCRIPT) \
-Wl,--gc-sections \
--specs=nano.specs \
--specs=rdimon.specs \
-Wl,-lc \
-Wl,-lrdimon \
-Wl,-Map=$(BUILD_DIR)/main.map \
-Wl,--build-id \
-Wl,--print-memory-usage \
# Check if the compiler is = 4.9.3, if so, disable some incopatible flags. The
# warnings they emit are due to incomplete support for C99 braced initializers
# in this old version of GCC.
GCC_VERSION := $(shell $(CC) -dumpversion)
ifeq ($(GCC_VERSION),4.9.3)
$(info Detected GCC 4.9.3, disabling some flags)
CFLAGS += \
-Wno-error=missing-braces \
-Wno-error=missing-field-initializers \
# remove -Wl,--print-memory-usage from LDFLAGS
COMMA=,
LDFLAGS := $(filter-out -Wl$(COMMA)--print-memory-usage,$(LDFLAGS))
endif
.PHONY: all
all: $(ELF)
# Require clone to complete as prereq for sources
$(SRCS): $(FREERTOS_DIR)/.git/HEAD
# Store computed cflags in a file; it's a prerequisite for all objects. Use a
# shell hack to check if the current cflags are different from the stored file,
# and make it out of date if so
# If CFLAGS differ from last build, rebuild all files
RAW_CFLAGS := $(CFLAGS) $(LDFLAGS)
CFLAGS_STALE = \
$(shell \
if ! (echo "$(RAW_CFLAGS)" | diff -q $(BUILD_DIR)/cflags - > /dev/null 2>&1); then \
echo CFLAGS_STALE; \
fi \
)
.PHONY: CFLAGS_STALE
$(BUILD_DIR)/cflags: $(CFLAGS_STALE) Makefile
mkdir -p $(dir $@)
echo "$(RAW_CFLAGS)" > $@
# Add rules for patched build objects from SDK
$(BUILD_DIR)/memfault-firmware-sdk/%.c.o: $(MEMFAULT_SDK_ROOT)/%.c $(BUILD_DIR)/cflags
mkdir -p $(dir $@)
$(info Compiling $<)
$(CC) -std=gnu11 $(CFLAGS) $(INCLUDE_PATHS) -c $< -o $@
$(BUILD_DIR)/%.c.o: %.c $(BUILD_DIR)/cflags
mkdir -p $(dir $@)
$(info Compiling $<)
$(CC) -std=gnu11 $(CFLAGS) $(INCLUDE_PATHS) -c $< -o $@
$(BUILD_DIR)/%.cpp.o: %.cpp $(BUILD_DIR)/cflags
mkdir -p $(dir $@)
$(info Compiling $<)
$(CXX) -std=gnu++11 $(CFLAGS) $(INCLUDE_PATHS) -c $< -o $@
$(ELF).uncompressed: $(OBJS) $(LINKER_SCRIPT)
$(info Linking $@)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
$(ELF): $(ELF).uncompressed
echo -n 'Compressing debug info... '
$(OBJCOPY) --compress-debug-sections $^ $@
echo From $$("$(STAT)" $^) to $$("$(STAT)" $@) bytes
$(SIZE) $@
$(READELF) -n $@ | grep 'Build ID'
-include $(OBJS:.o=.d)
.PHONY: debug
debug: $(ELF)
$(info Starting debugger)
$(DEBUG_COMMAND)
.PHONY: gdb
gdb: $(ELF)
$(GDB_COMMAND)
.PHONY: run
run: $(ELF)
$(RUN_COMMAND)
# This target dumps the preprocessed output of the memfault_metrics.c file
.PHONY: memfault_metrics.c
memfault_metrics.c: # build/qemu_mps2_an385/memfault-firmware-sdk/components/metrics/src/memfault_metrics.c.o
$(CC) $(CFLAGS:-MD=) $(INCLUDE_PATHS) -c $(MEMFAULT_SDK_ROOT)/components/metrics/src/memfault_metrics.c -E -P -o -
.PHONY: clean
clean:
rm -rf build