一个通用Makefile模板
2012-03-19 16:27
387 查看
最近学习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规则,做些后期工作,用户可以在这里做些收尾工作,如,把目标拷到指定目录
下面是这个模板的内容
它能做什么:
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 clean clean all # 4. make objs build .o and .d only # 5. make help show help # 6. make show show build variables # 7. add something to BEFOREBUILD or AFTERBUILD if needed ################################################################### #### USER-DEFINED SECTION ######################################### # compiler CC := g++ # target name TARGET := # compile flags CFLAGS := -g -Wall # ld flags for libraries LDFLAGS := # target type: exe static shared TYPE := exe # source file extension SRCEXT := .c .cpp # output directory OBJ_DIR := bin # dirs exclude from searching sources EXCLUDE_DIRS := $(OBJ_DIR) .svn # files exclude from source list EXCLUDE_FILES := #### DO NOT CHANGE THIS SECTION ################################### EMPTY := SPACE := $(EMPTY) $(EMPTY) TARGET := $(strip $(TARGET)) TYPE := $(strip $(TYPE)) ifeq ($(TARGET),) TARGET := a.out endif TARGET := $(TARGET:%=$(OBJ_DIR)/%) ifeq ($(filter $(TYPE),exe static shared),) $(error type $TYPE is error) endif # regexp for exclude dirs used in grep EXCPAT := $(foreach d,$(EXCLUDE_DIRS),\\/$(d)\\\>) EXCPAT := $(subst $(SPACE),\\\|,$(EXCPAT)) # get all dirs exclude the EXCLUDE_DIRS SRCDIRS := $(patsubst ./%,%,$(shell find . -type d | grep -v $(EXCPAT))) # get the source list SRCLIST := $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*, $(SRCEXT)))) SRCLIST := $(filter-out $(EXCLUDE_FILES), $(SRCLIST)) # objects list OBJS := $(basename $(notdir $(SRCLIST))) OBJS := $(OBJS:%=$(OBJ_DIR)/%.o) DEPS := $(OBJS:.o=.d) #generate rules for objects, $1:rule $2:source define rule_objs $(OBJ_DIR)/$1 $(CC) -c $(CFLAGS) $2 -MMD -o $(patsubst %,$(OBJ_DIR)/%.o,$(basename $(notdir $2))) endef ################################################################################### .PHONY: all objs clean show help all : BEFOREBUILD $(TARGET) AFTERBUILD objs : $(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 BUILD BEFOREBUILD: @echo "do preparations before build..." @if [ ! -e $(OBJ_DIR) ];then mkdir -p $(OBJ_DIR);echo "mkdir $(OBJ_DIR)";fi # DO SOMETHING HERE AFTER BUILD AFTERBUILD: @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 clean clean all" @echo "4. make objs build .o and .d only" @echo "5. make help show help" @echo "6. make show show build variables" @echo "7. add something BEFOREBUILD or AFTERBUILD if needed" # DEBUG USE ONLY show: @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)
相关文章推荐
- 调试通过的一个通用makefile模板
- 一个通用的Makefile模板-转
- 一个适合小型项目的通用Makefile模板
- 一个C/C++通用的Makefile模板
- 自己调试通过的一个通用makefile模板
- 一个通用的Makefile模板
- 一个简单的通用Makefile模板
- 我所使用的一个通用的Makefile模板
- 一个简单的通用Makefile实现
- Linux 通用Makefile模板
- 一个通用的Makefile
- 一个通用Makefile的编写
- *Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile
- 一个通用的makefile写法,自动推导文件的依赖关系【转】
- Makefile 通用模板
- bootloader---10.一个通用的Makefile
- 一个通用的makefile写法,自动推导文件的依赖关系
- Linux的通用makefile模板
- 一个通用的C/C++ Makefile
- 一个好用的Makefile模板