一下是一个稍微完整的Makefile文件,文件编译的工程一共有四个模块:array,foo,hello,Main;
头文件在inc中,源码和子Makefile在src目录中。
- #主Makefile
-
#环境变量,目标路径,进入子目录make all clean,总的make all clean,打印完成信息
-
-
.PHONY:all clean
-
-
MAKE = make
-
MAKEFLAG = -r
-
-
RM = rm
-
RMFLAG = -rf
-
-
#ROOT是上一目录的绝对路径
-
ROOT = $(realpath ..)
-
DIR = $(ROOT)/code/foo/src $(ROOT)/code/hello/src $(ROOT)/code/array/src $(ROOT)/code/Main/src
-
-
RMS = $(ROOT)/build/exes $(ROOT)/build/libs
-
-
#1.生成的目标与依赖关系集合
-
#循环 cd make clean
-
all clean:
-
@echo "Make $@ begin!"
-
@set -e ;\
-
for dir in $(DIR) ;\
-
do \
-
cd $$dir && $(MAKE) -r ROOT=$(ROOT) $@ ;\
-
done
-
@set -e ;\
-
if [ "$(MAKECMDGOALS)" = "clean" ]; \
-
then $(RM) $(RMFLAG) $(RMS); \
-
fi
-
@echo ""
-
@echo "~) Completed"
-
@echo ""
-
-
#先必须执行完毕所有的子Makefile中的all clean规则,再执行总的all clean规则,这在26行
-
#在这一点上无论是all clean都一样,故有一致性,可以写在一起
主Makefile
- #公有Makefile
-
-
.PHONY:all clean
-
-
CC = gcc
-
RM = rm
-
RMFLAG = -rf
-
MKDIR = mkdir
-
AR = ar
-
ARFLAG = crs
-
-
#3.路径
-
#绝对路径
-
DIR_EXE = $(ROOT)/build/exes
-
DIR_LIBS = $(ROOT)/build/libs
-
#相对路径
-
DIR_DEPS = deps
-
DIR_OBJS = objs
-
DIRS = $(DIR_DEPS) $(DIR_EXE) $(DIR_LIBS) $(DIR_OBJS)
-
-
#3**.RMS clean:exe .a .o .dep文件
-
#每个子Makefile应该清理掉的战场: .o和.dep文件
-
RMS = $(DIR_DEPS) $(DIR_OBJS)
-
-
#2.目标
-
#EXE =
-
#LIBS =
-
ifneq ("$(LIBS)","")
-
LIBS := $(addprefix $(DIR_LIBS)/,$(LIBS))
-
RMS += $(LIBS)
-
endif
-
ifneq ("$(EXE)","")
-
EXE := $(addprefix $(DIR_EXE)/,$(EXE))
-
RMS += $(EXE)
-
endif
-
-
#4.源
-
SRCS = $(wildcard *.c)
-
OBJS = $(SRCS:.c=.o)
-
OBJS := $(addprefix $(DIR_OBJS)/,$(OBJS))
-
#依赖关系文件加上路径
-
DEPS = $(SRCS:.c=.dep)
-
DEPS := $(addprefix $(DIR_DEPS)/,$(DEPS))
-
-
#6.LINK_LIBS与INCLUDE_DIRS
-
#-I *.h在生成.o文件的方法里和依赖关系里面都用到了,一共两处,INCLUDE_DIRS变量在子Makefile中指定
-
#-l *.a $(LINK_LIBS)与$(DEP_LIBS)
-
#做出一个libX%的筛选器,找出$(DIR_LIBS)/里面的所有库文件
-
ifneq ("$(LINK_LIBS)","")
-
LINK_LIBS := $(strip $(LINK_LIBS))
-
LINK_LIBS := $(addprefix -l,$(LINK_LIBS))
-
LIB_ALL := $(notdir $(wildcard $(DIR_LIBS)/*))
-
LIB_FILTERED := $(addsuffix %, $(addprefix lib,$(LINK_LIBS)))
-
$(eval DEP_LIBS=$(filter $(LIB_FILTERED),$(LIB_ALL)))
-
DEP_LIBS := $(addprefix $(DIR_LIBS)/,$(DEP_LIBS))
-
endif
-
ifneq ("$(INCLUDE_DIRS)","")
-
INCLUDE_DIRS := $(strip $(INCLUDE_DIRS))
-
INCLUDE_DIRS := $(addprefix -I,$(INCLUDE_DIRS))
-
endif
-
-
#5.DEP_DIR_EXE
-
#目录不存在则新建目录
-
#使用ifeq [ "$(DEP_DIR_EXE)","" ],ifeq [ "$(DEP_DIR_EXE" = "" ]是不行的,每次运行Makefile $(DEP_DIR_EXE)都是空,变量是空与文件夹不存在是两回事
-
ifeq ("$(wildcard $(DIR_EXE))","")
-
DEP_DIR_EXE := $(DIR_EXE)
-
endif
-
ifeq ("$(wildcard $(DIR_OBJS))","")
-
DEP_DIR_OBJS := $(DIR_OBJS)
-
endif
-
ifeq ("$(wildcard $(DIR_LIBS))","")
-
DEP_DIR_LIBS := $(DIR_LIBS)
-
endif
-
ifeq ("$(wildcard $(DIR_DEPS))","")
-
DEP_DIR_DEPS := $(DIR_DEPS)
-
endif
-
-
#1.生成关系目标依赖
-
#include与mkdir
-
#all与DEP_LIBS
-
all:$(EXE) $(LIBS)
-
ifneq ($(MAKECMDGOALS),clean)
-
include $(DEPS)
-
endif
-
$(DIRS):
-
$(MKDIR) $@
-
$(EXE):$(DEP_DIR_EXE) $(OBJS) $(DEP_LIBS)
-
$(CC) -L $(DIR_LIBS) -o $@ $(filter %.o,$^) $(LINK_LIBS)
-
$(DIR_OBJS)/%.o:$(DEP_DIR_OBJS) %.c
-
$(CC) $(INCLUDE_DIRS) -o $@ -c $(filter %.c,$^)
-
$(LIBS):$(DEP_DIR_LIBS) $(OBJS)
-
$(AR) $(ARFLAG) $@ $(filter %.o,$^)
-
-
#7.dep依赖关系规则,以便include生成,dep文件
-
$(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
-
@echo "Creating $@ ..."
-
@set -e ; \
-
$(RM) $(RMFLAG) $@.tmp ; \
-
$(CC) $(INCLUDE_DIRS) -E -MM $(filter %.c,$^) > $@.tmp ; \
-
sed 's,\(.*\)\.o[ :]*,objs/\1.o $@: ,g' < $@.tmp > $@ ; \
-
$(RM) $(RMFLAG) $@.tmp
-
-
#8.clean
-
clean:
-
$(RM) $(RMFLAG) $(RMS)
公有Makefile
- #子Makefile模板
-
#子目标 .h 库 包含公有Makefile
-
-
EXE =
-
LIBS = libarray.a
-
-
INCLUDE_DIRS = $(ROOT)/code/array/inc
-
LINK_LIBS =
-
include $(ROOT)/build/MakefileRule
子Makefilearray模块
- #子Makefile模板
-
#子目标 .h 库 包含公有Makefile
-
-
EXE =
-
LIBS = libfoo.a
-
-
INCLUDE_DIRS = $(ROOT)/code/foo/inc
-
LINK_LIBS =
-
include $(ROOT)/build/MakefileRule
子Makefilefoo模块
- #子Makefile模板
-
#子目标 .h 库 包含公有Makefile
-
-
#ROOT = /home/qq/learning/MakefileModel/
-
-
EXE =
-
LIBS = libhello.a
-
-
INCLUDE_DIRS = $(ROOT)/code/hello/inc
-
LINK_LIBS =
-
include $(ROOT)/build/MakefileRule
子Makefilehello模块
- #子Makefile模板
-
#子目标 .h 库 包含公有Makefile
-
-
EXE = complicated
-
LIBS =
-
-
INCLUDE_DIRS = $(ROOT)/code/array/inc $(ROOT)/code/foo/inc $(ROOT)/code/hello/inc
-
LINK_LIBS = array foo hello
-
include $(ROOT)/build/MakefileRule
阅读(4708) | 评论(0) | 转发(0) |