常用的C/C++工程Makefile模板

来源:互联网 发布:知乎公司 编辑:程序博客网 时间:2024/04/30 09:59

在Linux下做开发难免要接触makefile,整个项目的构建都依赖于它。100个developer有100种makefile的写法,在一个较大的项目中,各种各样的makefile无论在开发、后期维护还是整个系统的持续集成都是一个负担。 



有幸参与重构一个遗留系统的makefile,以下是一些心得和一个makefile模板。 
重构目的: 
1.清晰易懂、容易维护 
2.方便系统的持续集成 
重构原则: 
1.子模块makefile模板化 
2.外部依赖、通用宏定义集中化 
3.中间和最终输出集中,便于系统构建 



下面是总结出的一个makefile模板,我在日常的开发中都用它,其中加入了详细的注释。 



view plaincopy to clipboardprint? 
#Get the ROOT_PATH which common files located, assuming this makefile located in $(ROOT_PATH)/src/sub_module 
ROOT_PATH = $(shell cd ../..; pwd) 

#Where define the path of third party modules 
include $(ROOT_PATH)/path 

#Where define common macros such as CC=gcc, CXX=g++ and so on 
include $(ROOT_PATH)/common 

#Set target output path and the path of intermidiate object 
#The path macros should include in $(ROOT_PATH)/path 
OUT_PATH = $(OUTPUT_PATH)/submodule 
OBJ_PATH = $(TMPOBJ_PATH)/submodule 
TARGET = $(OUT_PATH)/targe 

#If the targe is share object then set corresponding flags 
#which should define in $(ROOT_PATH)/common 
CFLAGS += $(CFLAGS_SO) 
LDFLAGS += $(LDFLAGS_SO) 
#Custom Predefines 
CFLAGS += -DXXXXXXXX 
CFLAGS += -DYYYYYYYY 
#Dependent header files 
#The path macros should include in $(ROOT_PATH)/path 
CFLAGS += -I. / 
-I$(XXXX_INC) / 
-I$(YYYY_INC) / 
-I$(ZZZZ_INC) 
#Dependent libraries 
#The path macros should include in $(ROOT_PATH)/path 
LDFLAGS += -L$(XXXX_LIB) -lxxxx / 
-L$(YYYY_LIB) -lyyyy 

#Set CPP source directory 
CPP_SRCDIR = . 
#Or set specific CPP Source files 
ADDITIONAL_CPP_SOURCES = / 
$(PATH_A)/a.cpp / 
$(PATH_B)/b.cpp 

#Traverse every directory in $(CPP_SRCDIR), and find every cpp file 
CPP_SOURCES = $(foreach d,$(CPP_SRCDIR),$(wildcard $(d)/*.cpp) ) $(ADDITIONAL_CPP_SOURCES) 
#Traverse every cpp file in $(CPP_SOURCES) and get corresponding object file(.o) 
CPP_OBJFILES = $(patsubst %.cpp,$(OBJ_PATH)/%.o,$(notdir $(CPP_SOURCES))) 

#Set C source directory 
C_SRCDIR = 
#Or set specific C Source files 
ADDITIONAL_C_SOURCES = / 
$(PATH_A)/a.c / 
$(PATH_B)/b.c 

#C Source files 
C_SOURCES = $(foreach d,$(C_SRCDIR),$(wildcard $(d)/*.c) ) $(ADDITIONAL_C_SOURCES) 
C_OBJFILES = $(patsubst %.c,$(OBJ_PATH)/%.o,$(notdir $(C_SOURCES))) 

#Set vpath where to find these types of files 
vpath %.cpp $(dir $(CPP_SOURCES)) 
vpath %.c $(dir $(C_SOURCES)) 
vpath %.o $(OBJ_PATH) 

#The first target to be executed 
all: target 

target: $(TARGET) 

#Static dependecy pattern 
#$(OBJ_PATH)/%.o define the pattern of target and %.c or %.cpp is the final dependency 
$(C_OBJFILES): $(OBJ_PATH)/%.o: %.c 
-mkdir -p $(OBJ_PATH) 
$(CXX) -c $(CFLAGS) -o $@ $< 

$(CPP_OBJFILES): $(OBJ_PATH)/%.o: %.cpp 
-mkdir -p $(OBJ_PATH) 
$(CXX) -c $(CFLAGS) -o $@ $< 

$(TARGET): $(CPP_OBJFILES) $(C_OBJFILES) 
-mkdir -p $(OUT_PATH) 
$(CXX) -o $@ $^ $(LDFLAGS) 

clean: 
-rm -rf $(OBJ_PATH) 
-rm -f $(TARGET) 
#Get the ROOT_PATH which common files located, assuming this makefile located in $(ROOT_PATH)/src/sub_module 
ROOT_PATH = $(shell cd ../..; pwd) 

#Where define the path of third party modules 
include $(ROOT_PATH)/path 

#Where define common macros such as CC=gcc, CXX=g++ and so on 
include $(ROOT_PATH)/common 

#Set target output path and the path of intermidiate object 
#The path macros should include in $(ROOT_PATH)/path 
OUT_PATH = $(OUTPUT_PATH)/submodule 
OBJ_PATH = $(TMPOBJ_PATH)/submodule 
TARGET = $(OUT_PATH)/targe 

#If the targe is share object then set corresponding flags 
#which should define in $(ROOT_PATH)/common 
CFLAGS += $(CFLAGS_SO) 
LDFLAGS += $(LDFLAGS_SO) 
#Custom Predefines 
CFLAGS += -DXXXXXXXX 
CFLAGS += -DYYYYYYYY 
#Dependent header files 
#The path macros should include in $(ROOT_PATH)/path 
CFLAGS += -I. / 
-I$(XXXX_INC) / 
-I$(YYYY_INC) / 
-I$(ZZZZ_INC) 
#Dependent libraries 
#The path macros should include in $(ROOT_PATH)/path 
LDFLAGS += -L$(XXXX_LIB) -lxxxx / 
-L$(YYYY_LIB) -lyyyy 

#Set CPP source directory 
CPP_SRCDIR = . 
#Or set specific CPP Source files 
ADDITIONAL_CPP_SOURCES = / 
$(PATH_A)/a.cpp / 
$(PATH_B)/b.cpp 

#Traverse every directory in $(CPP_SRCDIR), and find every cpp file 
CPP_SOURCES = $(foreach d,$(CPP_SRCDIR),$(wildcard $(d)/*.cpp) ) $(ADDITIONAL_CPP_SOURCES) 
#Traverse every cpp file in $(CPP_SOURCES) and get corresponding object file(.o)

 

CPP_OBJFILES = $(patsubst %.cpp,$(OBJ_PATH)/%.o,$(notdir $(CPP_SOURCES))) 

#Set C source directory 
C_SRCDIR = 
#Or set specific C Source files 
ADDITIONAL_C_SOURCES = / 
$(PATH_A)/a.c / 
$(PATH_B)/b.c 

#C Source files 
C_SOURCES = $(foreach d,$(C_SRCDIR),$(wildcard $(d)/*.c) ) $(ADDITIONAL_C_SOURCES) 
C_OBJFILES = $(patsubst %.c,$(OBJ_PATH)/%.o,$(notdir $(C_SOURCES))) 

#Set vpath where to find these types of files 
vpath %.cpp $(dir $(CPP_SOURCES)) 
vpath %.c $(dir $(C_SOURCES)) 
vpath %.o $(OBJ_PATH) 

#The first target to be executed 
all: target 

target: $(TARGET) 

#Static dependecy pattern 
#$(OBJ_PATH)/%.o define the pattern of target and %.c or %.cpp is the final dependency 
$(C_OBJFILES): $(OBJ_PATH)/%.o: %.c 
-mkdir -p $(OBJ_PATH) 
$(CXX) -c $(CFLAGS) -o $@ $< 

$(CPP_OBJFILES): $(OBJ_PATH)/%.o: %.cpp 
-mkdir -p $(OBJ_PATH) 
$(CXX) -c $(CFLAGS) -o $@ $< 

$(TARGET): $(CPP_OBJFILES) $(C_OBJFILES) 
-mkdir -p $(OUT_PATH) 
$(CXX) -o $@ $^ $(LDFLAGS) 

clean: 
-rm -rf $(OBJ_PATH) 
-rm -f $(TARGET)

原创粉丝点击