makefile 实现 release/debug 预编译头 依赖关系分析 支持引入公用cpp 指定编译中间路径
.PHONY :all clean clean_target build rebuld relink
## 需要配置 项 ##
ProjectName:=db_pool_svr
HOME_BIN=$(shell echo ~/bin)
PRODUCT_PATH=$(shell echo ~/devp.linux)
## 预处理定义 ###
PRE_DEF_HEAD= -D_XDB_USE_DPI
INCS= -I./ -I$(PRODUCT_PATH)/src/include -I$(PRODUCT_PATH)/src/include/y
## 共用cpp,可能会同时编译到so和执行程序,编译开关不同,需要有不同的 .o 文件名,
COM_SOURCE=
## MYLIBS:= $(shell find $(OUT_PATH) -name *.so)
MYLIBS:= -lxxx -lxxxxx
SYSLIBS= -lpthread -ldl -lrt
SYSLIBPATH += -L$(PRODUCT_PATH)/src/lib_imp/xxxx -LXXXXXX
##------------以下无需修改-----------###
#SOURCE := $(wildcard *.cpp) $(wildcard _db_impl/*.cpp) $(wildcard _db_impl_mysql/*.cpp) $(wildcard _db_impl_gci/*.cpp
#HFILE:= $(wildcard *.h) $(wildcard _db_impl/*.h) $(wildcard _db_impl_mysql/*.h) $(wildcard mfc/*.h) $(wildcard file/*.h)
DIRS=$(shell find ./ -type d)
SOURCE=$(foreach dir_var,$(DIRS),$(wildcard $(dir_var)/*.cpp))
HFILE=$(foreach dir_var,$(DIRS),$(wildcard $(dir_var)/*.h))
DEPS=$(SOURCE:.cpp=.d) gch.d
target_type=$(findstring .so,$(ProjectName))
CFLAGS= -c -fno-strict-aliasing -Wall -pipe
##编译输出后缀,release debug 可以相同,因为我这个makefile 的编译输出指定了路径 ##
C_OUT=o
CPP_OUT=o
ver=release
ifeq ($(ver),release)
DD= -DNDEBUG
CFLAGS += -O2
PRODUCT_BIN=$(PRODUCT_PATH)/bin
PRODUCT_LIB=$(PRODUCT_PATH)/src/lib
else
DD= -g -D_DEBUG
CFLAGS += -O0
PRODUCT_BIN=$(PRODUCT_PATH)/bin_debug
PRODUCT_LIB=$(PRODUCT_PATH)/src/lib_debug
ifeq ($(target_type),.so)
ProjectName:=$(patsubst %.so,%.d.so,$(ProjectName))
else
ProjectName:=$(ProjectName).d
endif
MYLIBS:= $(addsuffix .d,$(MYLIBS))
endif
DD+= $(PRE_DEF_HEAD)
ifeq ($(target_type),.so)
CFLAGS+= -fPIC
DD+= -shared
endif
## 也可以所有工程是基于一个固定路径: BUILD_PATH:=/home/hanxb/build_out/$(ProjectName)/$(ver).gch/
BUILD_PATH:= $(ver).gch/
OBJS := $(patsubst %.c,$(BUILD_PATH)%.$(C_OUT),$(patsubst %.cpp,$(BUILD_PATH)%.$(CPP_OUT),$(SOURCE)))
CXXFLAGS= $(CFLAGS)
gch_cc=$(BUILD_PATH)c++
###### 编译b ####
all: $(ProjectName)
-include $(DEPS)
$(gch_cc): stdafx.h
@test -d $(BUILD_PATH) || mkdir -p $(BUILD_PATH)
g++ -std=c++11 -fpermissive -x c++-header -MMD -MF gch.d $(CXXFLAGS) $(INCS) -w $(DD) $< -o $@
#$(gch_c): stdafx.h if .c , pre_head like next
# gcc -fpermissive -x c-header -MMD -MF gch.d $(CXXFLAGS) $(INCS) -w $(DD) $< -o $@
GCH_INCLUDE:= $(subst .gch/,, $(BUILD_PATH))
$(BUILD_PATH)%.$(C_OUT): %.c $(HFILE)
@test -d $(dir $@) || mkdir -p $(dir $@)
gcc -std=c11 $(CFLAGS) $(INCS) -w $(DD) $< >$@
### 因为 直接指定依赖 gch_cc, 所以生成的 .d 文件内容很少( gcc 会排除 gch 中的.h), 不影响 dependence 分析
$(BUILD_PATH)%.$(CPP_OUT): %.cpp $(gch_cc)
@test -d $(dir $@) || mkdir -p $(dir $@)
g++ -std=c++11 -include $(GCH_INCLUDE) -fpermissive -MMD -MF $*.d $(CXXFLAGS) $(INCS) -w $(DD) $< -o $@
### 引入公共cpp ###
COM_OBJS:=$(COM_SOURCE:.cpp=.$(ProjectName).$(ver).$(CPP_OUT))
%.$(ProjectName).$(ver).$(CPP_OUT):%.cpp
g++ -std=c++11 -fpermissive -MMD -MF $*.d $(CXXFLAGS) $(INCS) -w $(DD) $< -o $@
LIBPATH=-L$(HOME_BIN) -L$(PRODUCT_BIN) -L$(PRODUCT_LIB) -L$(PRODUCT_PATH)/src/lib_imp
$(ProjectName):$(OBJS) $(COM_OBJS) makefile
g++ $(DD) -o $(ProjectName) $(OBJS) $(COM_OBJS) $(LIBPATH) $(SYSLIBPATH) $(MYLIBS) $(SYSLIBS) -lc
@echo -e "\033[1;31m $(ProjectName) build complete. \033[0m"
cp $(ProjectName) $(PRODUCT_BIN)/$(ProjectName)
build: $(ProjectName)
@echo -e "\033[1;31m auto build end !! \033[0m"
rebuild: clean $(ProjectName)
@echo -e "\033[1;31m autore-build end !! \033[0m"
relink: clean_target $(ProjectName)
@echo -e "\033[1;31m re-link end !! \033[0m"
clean:
rm -f $(COM_OBJS)
rm -f $(ProjectName)
rm -rf $(BUILD_PATH)
@echo "clear all objs and target !!"
clean_target:
rm -f $(ProjectName)
@echo "clear target ok !!"