# Copyright (C) Arm Limited, 2014-2021. All rights reserved.
#
# This example is intended to be built with:
# * Arm Compiler for Embedded 6
# * Linaro bare-metal GCC

include host.mk

# Only build targets that have barman.c generated
TARGETS := $(patsubst %/src/barman.c,%,$(wildcard */src/barman.c))
APP_NAME := barman_example
QUIET :=
OPT_LEVEL := 1

CC = armclang
#CC = aarch64-elf-gcc

# Other switches the user should not normally need to change:
DEBUG_FLAGS = -g

OUT_DIR = ./build

include common/common.mk

.PHONY: first
first: all
all: check_targets

# Template for creating rules a target
#
# $(1) target name
define TARGET_TEMPLATE

include $(1)/target.mk

AGENT_SRCS_$(1) := $(1)/src/barman.c \
                   $(1)/src/barman.h
OUT_DIR_$(1) := $(OUT_DIR)/$(1)
OUT_DIRS += $$(OUT_DIR_$(1))

CPPFLAGS_$(1) += -Icommon/src -I$(1)/src -MD -MF $$@.d -DTARGET=$(1)
CFLAGS_$(1) += $(DEBUG_FLAGS) -O$(OPT_LEVEL) -Wall
ASFLAGS_$(1) += $(DEBUG_FLAGS)

ifeq ($(CC),armclang)
LAYOUT_$(1) = $(1)/layout.scat
LDFLAGS_$(1) += -Wl,--scatter=$$(LAYOUT_$(1)) -e start64
TARGET_ARCH_$(1) += --target=aarch64-arm-none-eabi
else
LAYOUT_$(1) = $(1)/layout.ld
LDFLAGS_$(1) += --specs=rdimon.specs -T$$(LAYOUT_$(1)) -Wl,--build-id=none
endif

# Compile C and assembly files
COMMON_C_OBJS_$(1) := $$(COMMON_C_SRC:%.c=$$(OUT_DIR_$(1))/%.o)

$$(COMMON_C_OBJS_$(1)) : $$(OUT_DIR_$(1))/%.o : common/src/%.c | $$(OUT_DIR_$(1))
	$(QUIET) $(CC) -c $$(TARGET_ARCH_$(1)) $$(CPPFLAGS_$(1)) $$(CFLAGS_$(1)) -o $$@ $$<


COMMON_S_OBJS_$(1) := $$(COMMON_S_SRC:%.S=$$(OUT_DIR_$(1))/%.o)

$$(COMMON_S_OBJS_$(1)) : $$(OUT_DIR_$(1))/%.o : common/src/%.S | $$(OUT_DIR_$(1))
	$(QUIET) $(CC) -c $$(TARGET_ARCH_$(1)) $$(CPPFLAGS_$(1)) $$(ASFLAGS_$(1)) -o $$@ $$<


TARGET_C_OBJS_$(1) := $$(TARGET_C_SRC_$(1):%.c=$$(OUT_DIR_$(1))/%.o)

$$(TARGET_C_OBJS_$(1)) : $$(OUT_DIR_$(1))/%.o : $(1)/src/%.c | $$(OUT_DIR_$(1))
	$(QUIET) $(CC) -c $$(TARGET_ARCH_$(1)) $$(CPPFLAGS_$(1)) $$(CFLAGS_$(1)) -o $$@ $$<


TARGET_S_OBJS_$(1) := $$(TARGET_S_SRC_$(1):%.S=$$(OUT_DIR_$(1))/%.o)

$$(TARGET_S_OBJS_$(1)) : $$(OUT_DIR_$(1))/%.o : $(1)/src/%.S | $$(OUT_DIR_$(1))
	$(QUIET) $(CC) -c $$(TARGET_ARCH_$(1)) $$(CPPFLAGS_$(1)) $$(ASFLAGS_$(1)) -o $$@ $$<


OBJS_$(1) := $$(COMMON_C_OBJS_$(1)) $$(COMMON_S_OBJS_$(1)) $$(TARGET_C_OBJS_$(1)) $$(TARGET_S_OBJS_$(1))

-include $$(OBJS_$(1):%=%.d)

APP_$(1) := $$(OUT_DIR_$(1))/$(APP_NAME).axf

# Link app
$$(APP_$(1)): $$(AGENT_SRCS_$(1)) $$(OBJS_$(1)) $$(LAYOUT_$(1)) | $$(OUT_DIR_$(1))
	$(QUIET) $(CC) $$(TARGET_ARCH_$(1)) $$(LDFLAGS_$(1)) --output $$@ $$(OBJS_$(1))

# Make sure everything is rebuilt if the makefiles are changed
$$(APP_$(1)) $$(OBJS_$(1)): makefile common/common.mk $(1)/target.mk

all: $$(APP_$(1))

endef

$(foreach target,$(TARGETS),$(eval $(call TARGET_TEMPLATE,$(target))))


$(OUT_DIRS):
	$(call MK_DIRS,$@)

.PHONY: all clean
clean:
	$(call RM_DIRS,$(OUT_DIR))

# Notify to the user what targets are being built
check_targets:
ifeq ($(TARGETS),)
	$(error No targets selected. Please make sure you follow the steps indicated in readme.md to generate the barman agent sources for at least one target)
else
	$(info Building the following targets: $(TARGETS))
endif

#If the files exist then this target will not be called
%/src/barman.%:
	$(error Missing agent sources. Please make sure you follow the steps indicated in readme.md to generate the barman agent sources in "$(@D)")
