一个通用Makefile模板

来源:互联网 发布:js预览pdf文件 编辑:程序博客网 时间:2024/04/27 16:22

最近学习Makefile,写了一个C++编译的通用Makefile模板

它能做什么:

1. 能编译出应用程序,静态库,动态库

2. 可以用在任意目录结构的工程

3. 可以指定多个源文件后缀

4. 可以指定源文件的排除目录和排除文件列表

5. 已经充分考虑了源文件与头文件的依赖关系

6. 使用简单,只需要修改USER-DEFINED SECTION中的几个参数


执行流程:

1. USER-DEFINED参数检查

2. 搜索当前目录下的所有目录及子目录,并去掉排除目录,得到源文件目录

3. 在源文件目录中搜索带有源后缀的源文件,并去掉排除文件,得到源文件列表

4. 根据源文件列表得到.o和.d文件列表

5. 对源文件列表里的每个文件,计算其依赖关系,并动态生成规则

6. 执行BEFOREBUILD规则,做些准备工作,用户可以在这里做些其它工作,如,编译依赖工程

7. 执行TARGET规则,根据TYPE编译目标

8. 执行AFTERBUILD规则,做些后期工作,用户可以在这里做些收尾工作,如,把目标拷到指定目录


下面是这个模板的内容

#################################################################### Makefile template# author hitzheng@gmail.com# date 2012-03-18# usage:# 1. customize the USER-DEFINED SECTION#2. make build the target#3. make cleanclean all#4. make objsbuild .o and .d only#5. make helpshow help#6. make showshow build variables#7. add something to BEFOREBUILD or AFTERBUILD if needed####################################################################### USER-DEFINED SECTION ########################################## compilerCC := g++# target nameTARGET :=# compile flagsCFLAGS := -g -Wall# ld flags for librariesLDFLAGS := # target type: exe static sharedTYPE := exe# source file extensionSRCEXT := .c .cpp# output directoryOBJ_DIR := bin# dirs exclude from searching sourcesEXCLUDE_DIRS := $(OBJ_DIR) .svn# files exclude from source listEXCLUDE_FILES := #### DO NOT CHANGE THIS SECTION ###################################EMPTY :=SPACE := $(EMPTY) $(EMPTY)TARGET := $(strip $(TARGET))TYPE := $(strip $(TYPE))ifeq ($(TARGET),)  TARGET := a.outendifTARGET := $(TARGET:%=$(OBJ_DIR)/%)ifeq ($(filter $(TYPE),exe static shared),)$(error type $TYPE is error)endif# regexp for exclude dirs used in grepEXCPAT := $(foreach d,$(EXCLUDE_DIRS),\\/$(d)\\\>)EXCPAT := $(subst $(SPACE),\\\|,$(EXCPAT))# get all dirs exclude the EXCLUDE_DIRSSRCDIRS := $(patsubst ./%,%,$(shell find . -type d | grep -v $(EXCPAT)))# get the source listSRCLIST:= $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*, $(SRCEXT))))SRCLIST:= $(filter-out $(EXCLUDE_FILES), $(SRCLIST))# objects listOBJS := $(basename $(notdir $(SRCLIST)))OBJS := $(OBJS:%=$(OBJ_DIR)/%.o)DEPS := $(OBJS:.o=.d)#generate rules for objects, $1:rule $2:sourcedefine rule_objs$(OBJ_DIR)/$1$(CC) -c $(CFLAGS) $2 -MMD -o $(patsubst %,$(OBJ_DIR)/%.o,$(basename $(notdir $2)))endef###################################################################################.PHONY: all objs clean show helpall : BEFOREBUILD $(TARGET) AFTERBUILDobjs : $(OBJS)# GENERATE RULES FOR OBJECTS$(eval $(foreach src,$(SRCLIST),$(call rule_objs,$(shell $(CC) -MM $(src)),$(src))))# TARGET RULE$(TARGET) : $(OBJS)ifeq ($(TYPE),exe)@echo "build exe...."$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $@else ifeq ($(TYPE),static)@echo "build static library..."ar rcs $@ $(OBJS)else ifeq ($(TYPE),shared)@echo "build shared objects..."$(CC) -fpic -shared $(CFLAGS) $(OBJS) $(LDFLAGS) -o $@else @echo "target type:$(TYPE) error!!!"endif# DO SOMETHING HERE BEFORE BUILDBEFOREBUILD:@echo "do preparations before build..."@if [ ! -e $(OBJ_DIR) ];then mkdir -p $(OBJ_DIR);echo "mkdir $(OBJ_DIR)";fi# DO SOMETHING HERE AFTER BUILDAFTERBUILD:@echo "build finish, do something here"clean:$(RM) $(OBJS) $(DEPS) $(TARGET)help:@echo "usage:"@echo "1. customize the USER-DEFINED SECTION"@echo "2. make build the target"@echo "3. make cleanclean all"@echo "4. make objsbuild .o and .d only"@echo "5. make helpshow help"@echo "6. make showshow build variables"@echo "7. add something BEFOREBUILD or AFTERBUILD if needed"# DEBUG USE ONLYshow:@echo "TARGET: "$(TARGET)@echo "TYPE: "$(TYPE)@echo "CFLAGS: "$(CFLAGS)@echo "LDFLAGS: "$(LDFLAGS)@echo "EXCLUDE_DIRS: "$(EXCLUDE_DIRS)@echo "EXCLUDE_FILES: "$(EXCLUDE_FILES)@echo "EXCPAT: "$(EXCPAT)@echo "SRCDIRS: "$(SRCDIRS)@echo "SRCLIST: "$(SRCLIST)@echo "OBJS: "$(OBJS)@echo "DEPS: "$(DEPS)


原创粉丝点击