# 目标文件名称
TARGET_FILE_NAME = STM32G030F6P6_Evaluation

# CPU架构
CPU = -mcpu=cortex-m0plus

# 浮点运算单元
FPU = 					# NONE for Cortex-M0/M0+/M3

# 浮点运算方式
FLOAT-ABI = 			# NONE for Cortex-M0/M0+/M3

# 编译目录
BUILD_DIR = Build

# Release 编译子目录
SUB_DIR_RELEASE = Release

# Debug 编译子目录
SUB_DIR_DEBUG = Debug

# Release 优化等级
RELEASE_OPT = -Os

# Debug 优化等级
DEBUG_OPT = -Og

# C编译标准
C_STD = c23

# C++编译标准
CXX_STD = c++23

# 源文件编码定义
INPUT_CHAR_ENCODING = UTF-8

# 编译产物单字节字符(char)编码定义
OUTPUT_CHAR_ENCODING = GBK

# 编译产物宽字符(wchar_t)编码定义
OUTPUT_WCHAR_ENCODING = UTF-16LE

# 编译工具前缀
TOOLCHAIN_PREFIX = arm-none-eabi-

# C编译工具
C_COMPLIER = $(strip $(TOOLCHAIN_PREFIX))gcc

# C++编译工具
C++_COMPLIER = $(strip $(TOOLCHAIN_PREFIX))g++

# 编译后处理工具
AS  = $(strip $(TOOLCHAIN_PREFIX))gcc -x assembler-with-cpp
CP  = $(strip $(TOOLCHAIN_PREFIX))objcopy
SZ  = $(strip $(TOOLCHAIN_PREFIX))size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S

##################################################################################

# 链接库
LIBS_LINK = 	\
c				\
m				\
nosys 			\

# 额外链接库目录
LIB_PATHS = 	\

# ASM 汇编文件
ASM_SOURCES =  			\
startup_stm32g030xx.s	\

# 链接脚本
LD_SCRIPT = STM32G030XX_FLASH.ld

# C定义
C_DEFS =		\
USE_HAL_DRIVER	\
STM32G030xx		\

# C头文件目录
C_INCLUDES_PATHS =	                                            \
Core/Inc 														\
Drivers/STM32G0xx_HAL_Driver/Inc 								\
Drivers/STM32G0xx_HAL_Driver/Inc/Legacy			 				\
Middlewares/Third_Party/FreeRTOS/Source/include 				\
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS 				\
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM0 	\
Drivers/CMSIS/Device/ST/STM32G0xx/Include 						\
Drivers/CMSIS/Include                                       	\

# C源文件目录
C_SOURCES_PATHS =	\

# C额外单个源文件
C_EXTERA_SOURCES =											        \
Core/Src/main.c 													\
Core/Src/gpio.c 													\
Core/Src/app_freertos.c 											\
Core/Src/dma.c 														\
Core/Src/tim.c 														\
Core/Src/usart.c 													\
Core/Src/stm32g0xx_it.c 											\
Core/Src/stm32g0xx_hal_msp.c 										\
Core/Src/stm32g0xx_hal_timebase_tim.c 								\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_tim.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_tim_ex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc_ex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_rcc.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_flash_ex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_gpio.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_dma_ex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_pwr_ex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_cortex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal.c 					\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_exti.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_uart_ex.c 			\
Core/Src/system_stm32g0xx.c 										\
Middlewares/Third_Party/FreeRTOS/Source/croutine.c 					\
Middlewares/Third_Party/FreeRTOS/Source/event_groups.c 				\
Middlewares/Third_Party/FreeRTOS/Source/list.c 						\
Middlewares/Third_Party/FreeRTOS/Source/queue.c 					\
Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c 			\
Middlewares/Third_Party/FreeRTOS/Source/tasks.c 					\
Middlewares/Third_Party/FreeRTOS/Source/timers.c 					\
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c 		\
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c 	\
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c \
Core/Src/sysmem.c 													\
Core/Src/syscalls.c 												\
Core/Src/i2c.c 														\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_i2c.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_i2c_ex.c 			\
Core/Src/adc.c 														\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_adc_ex.c 			\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_ll_adc.c 				\
Core/Src/spi.c 														\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_spi.c 				\
Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_spi_ex.c				\

# C++定义
CXX_DEFS =				\
$(C_DEFS)               \

# C++ 头文件目录
CXX_INCLUDES_PATHS =	\
$(C_INCLUDES_PATHS)		\
User/Main/Inc			\


# C++源文件目录
CXX_SOURCES_PATHS =		\
User/Main/Src			\

# C++额外单个源文件
CXX_EXTERA_SOURCES = 	\

##################################################################################

# MCU编译选项
MCU_FLAGS = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# C编译选项
C_FLAGS = $(MCU_FLAGS) 													\
		 $(foreach text,$(C_DEFS),$(addprefix -D,$(text)))				\
		 $(foreach path,$(C_INCLUDES_PATHS),$(addprefix -I,$(path))) 	\
		-std=$(strip $(C_STD))											\
		-finput-charset=$(strip $(INPUT_CHAR_ENCODING)) 				\
		-fexec-charset=$(strip $(OUTPUT_CHAR_ENCODING)) 				\
		-fwide-exec-charset=$(strip $(OUTPUT_WCHAR_ENCODING))			\
		-Wall 															\
		-fdata-sections													\
		-ffunction-sections												\
		-MMD -MP -MF"$(@:%.o=%.d)"										\

# C++编译选项
CXX_FLAGS = $(MCU_FLAGS) 													\
		   $(foreach text,$(CXX_DEFS),$(addprefix -D,$(text)))				\
		   $(foreach path,$(CXX_INCLUDES_PATHS),$(addprefix -I,$(path))) 	\
		  -std=$(strip $(CXX_STD))											\
		  -finput-charset=$(strip $(INPUT_CHAR_ENCODING)) 					\
		  -fexec-charset=$(strip $(OUTPUT_CHAR_ENCODING)) 					\
		  -fwide-exec-charset=$(strip $(OUTPUT_WCHAR_ENCODING))				\
		  -Wall 															\
          -fno-rtti                                                         \
          -fno-exceptions                                                   \
          -fverbose-asm                                                     \
		  -fdata-sections													\
		  -ffunction-sections												\
		  -MMD -MP -MF"$(@:%.o=%.d)"										\

# 链接选项
LD_FLAGS = $(MCU_FLAGS) 										\
		  -specs=nano.specs 									\
		  -T$(LD_SCRIPT) 										\
		  $(LIB_PATHS) 											\
		  $(foreach text,$(LIBS_LINK),$(addprefix -l,$(text)))	\
		  -Wl,-Map=$(basename $@).map,--cref 					\
		  -Wl,--gc-sections										\
          -Wl,--print-memory-usage                              \

##################################################################################

# C目标文件及索引目录关联
OBJECTS  = $(notdir $(C_EXTERA_SOURCES:.c=.o))
OBJECTS += $(subst .c,.o,$(notdir $(foreach path,$(C_SOURCES_PATHS),$(wildcard $(path)/*.c))))
vpath %.c $(sort $(dir $(C_EXTERA_SOURCES))) $(sort $(C_SOURCES_PATHS))

# C++目标文件及索引目录关联
OBJECTS += $(notdir $(CXX_EXTERA_SOURCES:.cpp=.o))
OBJECTS += $(subst .cpp,.o,$(notdir $(foreach path,$(CXX_SOURCES_PATHS),$(wildcard $(path)/*.cpp))))
vpath %.cpp $(sort $(dir $(CXX_EXTERA_SOURCES))) $(sort $(CXX_SOURCES_PATHS))

# ASM汇编目标文件及索引目录关联
OBJECTS += $(notdir $(ASM_SOURCES:.s=.o))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

# Release 目标文件
RELEASE_OBJECTS = $(addprefix $(BUILD_DIR)/$(SUB_DIR_RELEASE)/,$(OBJECTS))

# Debug 目标文件
DEBUG_OBJECTS = $(addprefix $(BUILD_DIR)/$(SUB_DIR_DEBUG)/,$(OBJECTS))

##################################################################################

# all任务 目标为 release 和 debug 产物
all: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).elf 	\
	 $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).hex 	\
	 $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).bin	\
     $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).elf 		\
     $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).hex 		\
     $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).bin 		\

	@echo ====== [All] Build Procedure Accomplished ======

# release任务 目标为 release 产物 
release: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).elf	\
	     $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).hex 	\
	     $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).bin	\
	
	@echo ====== [Release] Build Procedure Accomplished ======

# debug任务 目标为 debug 产物
debug: $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).elf	\
	   $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).hex 	\
	   $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).bin	\

	@echo ====== [Debug] Build Procedure Accomplished ====== 

# 清理任务
clean: $(BUILD_DIR)
	powershell rm -r $(BUILD_DIR)

# 构建目录生成
$(BUILD_DIR):
	powershell mkdir $@

# Release 工作目录生成
$(BUILD_DIR)/$(SUB_DIR_RELEASE): | $(BUILD_DIR)
	powershell mkdir $@

# Debug 工作目录生成
$(BUILD_DIR)/$(SUB_DIR_DEBUG): | $(BUILD_DIR)
	powershell mkdir $@

# Release 最终可执行文件编译任务
$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).elf: $(RELEASE_OBJECTS)
	@echo ====== [Release] All File Compiled. Now Linking... ====== 
	$(C++_COMPLIER) $(RELEASE_OBJECTS) -s -o $@ $(LIB_LINK) $(LD_FLAGS)
	$(SZ) $@
	@echo ====== [Release] Program Link Finished ======

# Release Hex文件生成任务
$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).hex: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).elf
	$(HEX) $< $@

# Release Bin文件生成任务
$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).bin: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).elf
	$(BIN) $< $@

# Debug 最终可执行文件编译任务
$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).elf: $(DEBUG_OBJECTS)
	@echo ====== [Debug] All File Compiled. Now Linking... ====== 
	$(C++_COMPLIER) $(DEBUG_OBJECTS) -o $@ $(LIB_LINK) $(LD_FLAGS)
	$(SZ) $@
	@echo ====== [Debug] Program Link Finished ====== 

# Debug Hex文件生成任务
$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).hex: $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).elf
	$(HEX) $< $@

# Debug Bin文件生成任务
$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).bin: $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).elf
	$(BIN) $< $@

# C Release 目标文件编译
$(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.c Tools/Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE)
	@echo ====== [Release] C Source File "$<" Compiling... ======
	$(C_COMPLIER) -c $(C_FLAGS) $(RELEASE_OPT) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(notdir $(<:.c=.lst)) $< -o $@

# C++ Release 目标文件编译
$(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.cpp Tools/Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE)
	@echo ====== [Release] C++ Source File "$<" Compiling... ====== 
	$(C++_COMPLIER) -c $(CXX_FLAGS) $(RELEASE_OPT) -Wa,-a,-ad,-ahlms=$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(notdir $(<:.cpp=.lst)) $< -o $@

# ASM Release 目标文件编译
$(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.s Tools/Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE)
	@echo ====== [Release] ASM File "$<" Compiling... ======
	$(AS) -c $(C_FLAGS) $(RELEASE_OPT) $< -o $@

# C Debug 目标文件编译
$(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.c Tools/Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG)
	@echo ====== [Debug] C Source File "$<" Compiling... ======
	$(C_COMPLIER) -c $(C_FLAGS) $(DEBUG_OPT) -g -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(notdir $(<:.c=.lst)) $< -o $@

# C++ Debug 目标文件编译
$(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.cpp Tools/Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG)
	@echo ====== [Debug] C++ Source File "$<" Compiling... ====== 
	$(C++_COMPLIER) -c $(CXX_FLAGS) $(DEBUG_OPT) -g -Wa,-a,-ad,-ahlms=$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(notdir $(<:.cpp=.lst)) $< -o $@

# ASM Release 目标文件编译
$(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.s Tools/Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG)
	@echo ====== [Release] ASM File "$<" Compiling... ======
	$(AS) -c $(C_FLAGS) $(DEBUG_OPT) $< -o $@

# 依赖关系
-include $(RELEASE_OBJECTS:.o=.d)
-include $(DEBUG_OBJECTS:.o=.d)