# 目标文件名称 TARGET_FILE_NAME = Target # 编译目录 BUILD_DIR = Build # Release 编译子目录 SUB_DIR_RELEASE = Release # Debug 编译子目录 SUB_DIR_DEBUG = Debug # Release 优化等级 # ⚠️ 用 `-Oz` 而不是 `-Os`:本项目热点全在 GDI/GDI+ 绘制上,`-Oz` 与 `-Os` 的实测帧耗时 # 没有可辨识差异,但产物小 ~6KB(用户 2026-10-19 要求 Release 二进制 < 800KB)。 RELEASE_OPT = -Oz # Debug 优化等级 DEBUG_OPT = -O0 # GUI或CUI编译选项 [0]CUI/Console [1]GUI GUI = 1 # C编译标准 C_STD = c17 # C++编译标准 CXX_STD = c++17 # 源文件编码定义 INPUT_CHAR_ENCODING = UTF-8 # 编译产物单字节字符(char)编码定义 OUTPUT_CHAR_ENCODING = GBK # 编译产物宽字符(wchar_t)编码定义 OUTPUT_WCHAR_ENCODING = UTF-16LE # 编译工具前缀 COMPLIER_PREFIX = \ # C编译工具 C_COMPLIER = $(strip $(COMPLIER_PREFIX))gcc # C++编译工具 CXX_COMPLIER = $(strip $(COMPLIER_PREFIX))g++ # Windows 资源文件编译工具 WIN_RES_COMPLIER = windres ################################################################################## # 链接库 LIB_LINK = \ -lgdi32 \ -lgdiplus \ -lmsimg32 \ -lcomdlg32 \ -ld3d11 \ -ldwmapi \ -ld3dcompiler \ # C定义 C_DEFS = \ _UNICODE \ UNICODE \ # C头文件目录 C_INCLUDES_PATHS = \ # C源文件目录 C_SOURCES_PATHS = \ # C额外单个源文件 C_EXTERA_SOURCES = \ # C++定义 CXX_DEFS = \ _UNICODE \ UNICODE \ # C++ 头文件目录 # ⚠️ 目录约定:**所有头文件(.hpp)只放在 `Inc`**,`Src` 只放实现(.cpp)。 # `*Internal.hpp`(组件内部共享的常量/工具,如 `PlotViewInternal.hpp`)同样属于头文件, # 历史上曾被放在 `Src` 下(那里也能编译,因为编译器会先找 `#include` 所在目录), # 但那是靠“同目录优先”隐式生效的 —— 一旦文件被搬走就会无声失效。现已全部移入 `Inc`。 CXX_INCLUDES_PATHS = \ Utilities/Inc \ Resources/Inc \ Components/Main/Inc \ Components/Shared/Inc \ Components/Application/Inc \ Components/TabBar/Inc \ Components/Toolbar/Inc \ Components/SignalPanel/Inc \ Components/PlotView/Inc \ # C++源文件目录 CXX_SOURCES_PATHS = \ Utilities/Src \ Components/Main/Src \ Components/Shared/Src \ Components/Application/Src \ Components/TabBar/Src \ Components/Toolbar/Src \ Components/SignalPanel/Src \ Components/PlotView/Src \ # C++额外单个源文件 CXX_EXTERA_SOURCES = \ # Windows 资源文件脚本头文件路径 WIN_RESOURCE_INCLUDES_PATHS = \ Resources \ Resources/Inc \ # Windows 资源文件脚本输入代码页(对应 INPUT_CHAR_ENCODING = UTF-8) WIN_RESOURCE_CODEPAGE = 65001 # Windows 资源文件脚本列表 WIN_RESOURCE_SCRIPTS = \ Resources/JustDataInspector.rc \ ################################################################################## # C编译选项 CFLAGS = $(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)) \ -static \ -Wall \ -MMD -MP -MF"$(@:%.o=%.d)" \ # C++编译选项 CXXFLAGS = $(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)) \ -static \ -Wall \ -MMD -MP -MF"$(@:%.o=%.d)" \ -lstdc++ \ # 链接选项 LDFLAGS = -Wl,-Map,$(basename $@).map \ ################################################################################## # GUI与CUI选项附加 ifeq ($(GUI), 1) LDFLAGS += -mwindows else LDFLAGS += -mconsole endif # 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)) # Windows资源文件及索引目录关联 OBJECTS += $(notdir $(WIN_RESOURCE_SCRIPTS:.rc=.o)) vpath %.rc $(sort $(dir $(WIN_RESOURCE_SCRIPTS))) # 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).exe $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).exe @echo ====== [All] Build Procedure Accomplished ====== # release任务 目标为 release 产物 release: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).exe @echo ====== [Release] Build Procedure Accomplished ====== # debug任务 目标为 debug 产物 debug: $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).exe @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).exe: $(RELEASE_OBJECTS) @echo ====== [Release] All File Compiled. Now Linking... ====== $(CXX_COMPLIER) $(RELEASE_OBJECTS) -static -s -o $@ $(LIB_LINK) $(LDFLAGS) @echo ====== [Release] Program Link Finished ====== # Debug 最终可执行文件编译任务 $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).exe: $(DEBUG_OBJECTS) @echo ====== [Debug] All File Compiled. Now Linking... ====== $(CXX_COMPLIER) $(DEBUG_OBJECTS) -static -o $@ $(LIB_LINK) $(LDFLAGS) @echo ====== [Debug] Program Link Finished ====== # C Release 目标文件编译 $(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.c Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE) @echo ====== [Release] C Source File "$<" Compiling... ====== $(C_COMPLIER) -c $(CFLAGS) $(RELEASE_OPT) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(notdir $(<:.c=.lst)) $< -o $@ # C++ Release 目标文件编译 $(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.cpp Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE) @echo ====== [Release] C++ Source File "$<" Compiling... ====== $(CXX_COMPLIER) -c $(CXXFLAGS) $(RELEASE_OPT) -Wa,-a,-ad,-ahlms=$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(notdir $(<:.cpp=.lst)) $< -o $@ # Release 资源脚本文件编译 $(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.rc Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE) @echo ====== [Release] Windows Resource Script File "$<" Compiling... ====== $(WIN_RES_COMPLIER) -c $(WIN_RESOURCE_CODEPAGE) $(foreach path,$(WIN_RESOURCE_INCLUDES_PATHS),$(addprefix -I,$(path))) $< -o $@ # C Debug 目标文件编译 $(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.c Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG) @echo ====== [Debug] C Source File "$<" Compiling... ====== $(C_COMPLIER) -c $(CFLAGS) $(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 Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG) @echo ====== [Debug] C++ Source File "$<" Compiling... ====== $(CXX_COMPLIER) -c $(CXXFLAGS) $(DEBUG_OPT) -g -Wa,-a,-ad,-ahlms=$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(notdir $(<:.cpp=.lst)) $< -o $@ # Debug 资源脚本文件编译 $(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.rc Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG) @echo ====== [Debug] Windows Resource Script File "$<" Compiling... ====== $(WIN_RES_COMPLIER) -c $(WIN_RESOURCE_CODEPAGE) $(foreach path,$(WIN_RESOURCE_INCLUDES_PATHS),$(addprefix -I,$(path))) $< -o $@ # 依赖关系 -include $(RELEASE_OBJECTS:.o=.d) -include $(DEBUG_OBJECTS:.o=.d)