##################################################
################ 可修改和配置参数 ################
##################################################
#目标文件名,例如:test, 为动态库时文件名=libtest.dll,为静态库时文件名=libtest.lib
TARGET := test
#目标类型,选项值:app - 应用程序, shared - 动态库, static - 静态库
TYPE := app
#标识定义,例如:ARM 或 x86
DEFINES :=
#源码宏定义,例如:-DDEBUG -DTEST=1
MACROS :=
#指定安装路径(默认安装到当前路径)
SET_PATH :=
#头文件路径(添加当前路径为搜索路径:-I.),例如:-I"D:/libcurl/include"
INC_PATH := -I.
#源文件路径(默认从当前路径搜索)
SRC_PATH := 3rd src
#指定运行时动态库搜索路径
ifeq (ARM,$(filter ARM,$(DEFINES)))
RPATH :=
else
RPATH :=
endif
#动态库路径(添加当前路径为搜索路径:-L.),例如:-L"D:/libcurl/lib"
LDFLAGS := -L.
ifeq (ARM,$(filter ARM,$(DEFINES)))
LDFLAGS +=
else
LDFLAGS +=
endif
#动态库文件,例如:-lpthread
LIBS :=
#静态库文件(默认从当前路径搜索),例如:libgendll.lib
LIB_STATICS :=
ifeq (ARM,$(filter ARM,$(DEFINES)))
LIB_STATICS +=
else
LIB_STATICS +=
endif
#编译器,这里针对不同目标平台做选择
CC := g++
AR := ar
ifeq (ARM,$(filter ARM,$(DEFINES)))
CC :=
AR :=
endif
#C编译器选项
CFLAGS := -g -Wall -O3 -Wl,-rpath=$(RPATH)
#C++编译器选项
CXXFLAGS := -DHAVE_CONFIG_H -std=c++11
#构建目录,存放临时文件
BUILD_DIR ?= _build
OBJ_C_DIR ?= $(BUILD_DIR)/object_c
OBJ_CXX_DIR ?= $(BUILD_DIR)/object_cxx
######################################################################
#Brief: 搜索当前目录下的子节点(包含目录和文件)
#Param: 空
#Return: 列表,空格分隔
######################################################################
define pwdFiles
$(1) = $(wildcard *)
endef
######################################################################
#Brief: 搜索指定目录下的子节点(包含目录和文件)
#Param: 参数1 - 目录列表,空格分隔,如.a b c
#Return: 列表,空格分隔
######################################################################
define searchFiles
$(1) = $(foreach dir,$(1),$(wildcard $(dir)/*))
endef
######################################################################
####################### 构建流程,基本不需再修改 ######################
######################################################################
SHELL = cmd
#当前路径
ifeq (,$(SET_PATH))
SET_PATH := ${CURDIR}
endif
#源文件
SOURCES := $(filter %.c %.cc %.cpp %.hpp,$(call pwdFiles) $(call searchFiles,$(SRC_PATH)))
#.d文件(依赖关系)
DEPENDS_C := $(patsubst %.c,$(OBJ_C_DIR)/%.d,$(filter %.c,$(SOURCES)))
DEPENDS_CC := $(patsubst %.cc,$(OBJ_CXX_DIR)/%.d,$(filter %.cc,$(SOURCES)))
DEPENDS_CPP := $(patsubst %.cpp,$(OBJ_CXX_DIR)/%.d,$(filter %.cpp,$(SOURCES)))
DEPENDS_HPP := $(patsubst %.hpp,$(OBJ_CXX_DIR)/%.d,$(filter %.hpp,$(SOURCES)))
DEPENDS := $(DEPENDS_C) $(DEPENDS_CC) $(DEPENDS_CPP) $(DEPENDS_HPP)
#.o文件
OBJECTS := $(DEPENDS:%.d=%.o)
#编译参数
FLAGS := $(MACROS) $(INC_PATH) $(CFLAGS) $(CXXFLAGS)
ifeq (shared,$(TYPE)) # 动态库
FLAGS += -fpic -shared
TARGET := lib$(TARGET).dll
endif
ifeq (static,$(TYPE)) # 静态库
TARGET := lib$(TARGET).lib
endif
#链接库参数
LIB_FLAGS := $(LDFLAGS) $(LIBS) $(LIB_STATICS)
#伪目标
.PHONY: help
#帮助说明
help:
$(info Build Help for Target '$(TARGET)':)
$(info * make all -- build project, aborted after an error)
$(info * make clean -- delete files [.d .o] in folder '$(BUILD_DIR)')
$(info * make veryclean -- delete folder '$(BUILD_DIR)')
$(info * make rebuild -- rebuild project)
$(info * make install -- install to the path '$(SET_PATH)')
#编译构建
all: $(TARGET)
#编译c源码的.d文件
$(OBJ_C_DIR)/%.d: %.c
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@set -e; del /F /Q $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_C_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
del /F /Q $@.$$$$
#编译c++源码的.d文件
$(OBJ_CXX_DIR)/%.d: %.cc
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@set -e; del /F /Q $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_CXX_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
del /F /Q $@.$$$$
$(OBJ_CXX_DIR)/%.d: %.cpp
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@set -e; del /F /Q $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_CXX_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
del /F /Q $@.$$$$
$(OBJ_CXX_DIR)/%.d: %.hpp
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@set -e; del /F /Q $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_CXX_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
del /F /Q $@.$$$$
#编译.o文件描述
o_describe:
$(info ========================== Generate .o File ==========================)
#编译c源码的.o文件
$(OBJ_C_DIR)/%.o: %.c
$(info $@)
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@$(CC) $(FLAGS) -c $< -o $@
#编译c++源码的.o文件
$(OBJ_CXX_DIR)/%.o: %.cc
$(info $@)
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@$(CC) $(FLAGS) -c $< -o $@
$(OBJ_CXX_DIR)/%.o: %.cpp
$(info $@)
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@$(CC) $(FLAGS) -c $< -o $@
$(OBJ_CXX_DIR)/%.o: %.hpp
$(info $@)
@if not exist $(subst /,\\,$(@D)) (mkdir $(subst /,\\,$(@D)))
@$(CC) $(FLAGS) -c $< -o $@
#链接目标文件
-include $(DEPENDS)
$(TARGET): o_describe $(OBJECTS)
$(info ======================== Generate Target File ========================)
ifeq (static,$(TYPE)) # 静态库
@$(AR) -r $(BUILD_DIR)/$@ $(OBJECTS)
else
@$(CC) $(FLAGS) -o $(BUILD_DIR)/$@ $(OBJECTS) $(LIB_FLAGS)
endif
$(info Build "$(BUILD_DIR)/$@" OK ...)
#只清除[.d .o]文件
clean:
@if exist $(subst /,\\,$(OBJ_C_DIR)) (rd /S /Q $(subst /,\\,$(OBJ_C_DIR)))
@if exist $(subst /,\\,$(OBJ_CXX_DIR)) (rd /S /Q $(subst /,\\,$(OBJ_CXX_DIR)))
$(info Clean OK ...)
#清除所有构建生成的文件
veryclean:
@if exist $(subst /,\\,$(BUILD_DIR)) (rd /S /Q $(subst /,\\,$(BUILD_DIR)))
$(info Very Clean OK ...)
#重新构建
rebuild: clean all
Windows通用Makefile
最新推荐文章于 2023-04-09 10:57:48 发布