RM := rm -rf

COMPILER_PREFIX ?= arm-none-eabi

# Define option(s) defined in pre-processor compiler option(s)
DEFINE_OPTS = -DDEBUG=1
# Optimisation option(s)
OPTIM_OPTS = -Os
# Debug option(s)
DEBUG = -g

BUILD_DIR = ./build

PROJECT = $(BUILD_DIR)/llcc68_ping_pong

BSP_DIR   = ../../Drivers/BSP/CX32L003_EBYTE_E220_UART
BSP_SRCS  = $(wildcard $(BSP_DIR)/*.c)
OBJS     += $(patsubst $(BSP_DIR)/%.c,$(BUILD_DIR)/%.o,$(BSP_SRCS))

HAL_DRIVER_DIR  = ../../Drivers/CX32L003_HAL_Driver/Src
HAL_DRIVER_SRCS = $(wildcard $(HAL_DRIVER_DIR)/*.c)
OBJS       += $(patsubst $(HAL_DRIVER_DIR)/%.c,$(BUILD_DIR)/%.o,$(HAL_DRIVER_SRCS))

CMSIS_DEVICE_DIR   = ../../Drivers/CMSIS/Device/XMC/CX32L003/Source
CMSIS_DEVICE_SRCS  = $(wildcard $(CMSIS_DEVICE_DIR)/*.c)
OBJS     += $(patsubst $(CMSIS_DEVICE_DIR)/%.c,$(BUILD_DIR)/%.o,$(CMSIS_DEVICE_SRCS))

LLCC68_DRIVER_DIR  = ../../Drivers/llcc68_driver/src
LLCC68_DRIVER_SRCS = $(wildcard $(LLCC68_DRIVER_DIR)/*.c)
OBJS       += $(patsubst $(LLCC68_DRIVER_DIR)/%.c,$(BUILD_DIR)/%.o,$(LLCC68_DRIVER_SRCS))

LLCC68_DRIVER_COMMON_DIR   = ../../Drivers/llcc68_driver/common
LLCC68_DRIVER_COMMON_SRCS  = $(wildcard $(LLCC68_DRIVER_COMMON_DIR)/*.c)
OBJS     += $(patsubst $(LLCC68_DRIVER_COMMON_DIR)/%.c,$(BUILD_DIR)/%.o,$(LLCC68_DRIVER_COMMON_SRCS))

COMMON_DIR   = ../../Common
COMMON_SRCS  = $(wildcard $(COMMON_DIR)/*.c)
OBJS     += $(patsubst $(COMMON_DIR)/%.c,$(BUILD_DIR)/%.o,$(COMMON_SRCS))

USER_DIR  = ./Src
USER_SRCS = $(wildcard $(USER_DIR)/*.c)
OBJS     += $(patsubst $(USER_DIR)/%.c,$(BUILD_DIR)/%.o,$(USER_SRCS))

# All of the sources participating in the build are defined here
OBJS += $(BUILD_DIR)/startup_cx32l003.o
DEPS  = $(subst .o,.d,$(OBJS))
LIBS  =

BASE_OPTS = -mcpu=cortex-m0plus -mthumb $(OPTIM_OPTS) -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections
C_OPTS    = $(BASE_OPTS) $(DEBUG) $(DEFINE_OPTS)\
              $(INCLUDES) -std=gnu99 -MMD -MP -MT"$(@)"
LD_OPTS   = -T "./ECLIPSE/CX32L003_FLASH.ld" -Xlinker --gc-sections -Xlinker --print-memory-usage -Wl,-Map,"$(PROJECT).map" --specs=nano.specs --specs=nosys.specs

INCLUDES = \
  -I"$(BSP_DIR)" \
  -I"../../Drivers/CX32L003_HAL_Driver/Inc" \
  -I"../../Drivers/CMSIS/Include" \
  -I"../../Drivers/CMSIS/Device/XMC/CX32L003/Include" \
  -I"../../Drivers/llcc68_driver/src" \
  -I"../../Drivers/llcc68_driver/common" \
  -I"$(COMMON_DIR)" \
  -I"./Inc"

# Add inputs and outputs from these tool invocations to the build variables
SECONDARY_FLASH += $(PROJECT).hex $(PROJECT).bin
SECONDARY_LIST  += $(PROJECT).lst
SECONDARY_SIZE  += $(PROJECT).siz
SECONDARY_MAP   += $(PROJECT).map

SECONDARY_OUTPUTS = $(SECONDARY_FLASH) $(SECONDARY_LIST) $(SECONDARY_SIZE) $(SECONDARY_MAP)
secondary-outputs: $(SECONDARY_OUTPUTS)

# All Target
all: $(PROJECT).elf secondary-outputs

.PRECIOUS: $(BUILD_DIR)/. $(BUILD_DIR)%/.

$(BUILD_DIR)/.:
	mkdir -p $@

$(BUILD_DIR)%/.:
	mkdir -p $@

.SECONDEXPANSION:

$(BUILD_DIR)/%.o: ../../Drivers/BSP/CX32L003_EBYTE_E220_UART/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/startup_cx32l003.o: ../../Drivers/CMSIS/Device/XMC/CX32L003/Source/GCC/startup_cx32l003.S | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -x assembler -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ../../Drivers/CMSIS/Device/XMC/CX32L003/Source/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ../../Drivers/CX32L003_HAL_Driver/Src/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ../../Drivers/llcc68_driver/src/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ../../Drivers/llcc68_driver/common/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ../../Common/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ../../Common/%.c | $$(@D)/.
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

$(BUILD_DIR)/%.o: ./Src/%.c | $$(@D)/.
	@echo $(OBJS)
	@echo 'Building file: $<'
	$(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<"
	@echo ' '

# Tool invocations
$(PROJECT).elf: $(OBJS)
	@echo 'Invoking: GNU ARM Cross C Linker'
	$(COMPILER_PREFIX)-gcc $(BASE_OPTS) $(LD_OPTS) -o "$(PROJECT).elf" $(OBJS) $(LIBS)
	@echo ' '

$(PROJECT).hex: $(PROJECT).elf
	@echo 'Invoking: GNU ARM Cross Create Flash Image'
	$(COMPILER_PREFIX)-objcopy -O ihex "$(PROJECT).elf"  "$(PROJECT).hex"
	@echo ' '

$(PROJECT).bin: $(PROJECT).elf
	-@echo 'Create Flash Image BIN'
	-$(COMPILER_PREFIX)-objcopy -O binary "$(PROJECT).elf"  "$(PROJECT).bin"
	-@echo ' '

$(PROJECT).lst: $(PROJECT).elf
	@echo 'Invoking: GNU ARM Cross Create Listing'
	$(COMPILER_PREFIX)-objdump --source --all-headers --demangle --line-numbers --wide "$(PROJECT).elf" > "$(PROJECT).lst"
	@echo ' '

$(PROJECT).siz: $(PROJECT).elf
	@echo 'Invoking: GNU ARM Cross Print Size'
	$(COMPILER_PREFIX)-size --format=berkeley "$(PROJECT).elf"
	@echo ' '

# Other Targets
clean:
	-$(RM) $(OBJS) $(DEPS) $(SECONDARY_OUTPUTS) $(PROJECT).elf
	-@echo ' '

.PHONY: all clean dependents
