Makefile4处理了include文件包含时出现的两个问题:
1)依赖关系生成的正确性:
主要考虑两点:A>依赖关系是一对一还是一对多?
B>使用gcc自动生成的结果是包含的路径不是自己想要的,如何修改?
#dep2)如下方案可以得到一对一关系的目标集合与依赖关系,但是写入$(DIR_DEPS)/%.dep文件的内容中的.o文件是不包含路径objs/的
# 因为gcc -E -MM Hello.c 就得不到关于objs/Hello.o的合理依赖只能是Hello.o的
#$(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
# $(CC) -E -MM $^ > $@
2)目录出现在规则的先决条件中,当加入文件到该目录,该目录的时间戳被修改,这也就意味着依赖关系文 件发生了更新,出现死循环:
方法是使用条件,决定目标是否需要生成
- .PHONY:all clean
-
-
CC = gcc
-
RM = rm
-
RMCMD = -rf
-
MKDIR = mkdir
-
-
DIR_OBJS = objs
-
DIR_EXES = exes
-
DIR_DEPS = deps
-
DIR = $(DIR_OBJS) $(DIR_EXES) $(DIR_DEPS)
-
SRCS = $(wildcard *.c)
-
OBJS = $(SRCS:.c=.o)
-
OBJS := $(addprefix $(DIR_OBJS)/,$(OBJS))
-
EXE = complicated
-
EXE := $(addprefix $(DIR_EXES)/,$(EXE))
-
DEPS = $(SRCS:.c=.dep)
-
DEPS := $(addprefix $(DIR_DEPS)/,$(DEPS))
-
-
ifeq ("$(wildcard $(DIR_OBJS))", "")
-
DEP_DIR_OBJS := $(DIR_OBJS)
-
endif
-
-
ifeq ("$(wildcard $(DIR_EXES))", "")
-
DEP_DIR_EXES := $(DIR_EXES)
-
endif
-
-
ifeq ("$(wildcard $(DIR_DEPS))", "")
-
DEP_DIR_DEPS := $(DIR_DEPS)
-
endif
-
-
all:$(EXE)
-
-
$(DIR):
-
$(MKDIR) $@
-
-
#dep2)如下方案可以得到一对一关系的目标集合与依赖关系,但是写入$(DIR_DEPS)/%.dep文件的内容中的.o文件是不包含路径objs/的
-
# 因为gcc -E -MM Hello.c 就得不到关于objs/Hello.o的合理依赖只能是Hello.o的
-
#$(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
-
# $(CC) -E -MM $^ > $@
-
-
#目录出现在规则的先决条件中,这给死循环埋下了伏笔:若DIR_DEPS目录时间戳被修改则规则会被再次使用:故要创建依赖则要看条件if
-
#先生成依赖关系再修改依赖关系,加上objs/
-
$(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
-
@echo "Creating $@ ..."
-
@set -e; \
-
$(RM) $(RMCMD) $@.tmp; \
-
$(CC) -E -MM $^ > $@.tmp; \
-
sed 's,\(.*\)\.o[ :]*,objs/\1.o: ,g' < $@.tmp > $@ ; \
-
$(RM) $(RMCMD) $@.tmp
-
-
#执行make的时候include会首先被执行,include能够创建所需包含进来的依赖文件,故目标甚至可以不被包含在all之后
-
include $(DEPS)
-
-
$(EXE):$(DEP_DIR_EXES) $(OBJS)
-
$(CC) -o $@ $(filter %.o,$^)
-
$(DIR_OBJS)/%.o:$(DEP_DIR_OBJS) %.c
-
$(CC) -o $@ -c $(filter %.c,$^)
-
-
clean:$(DIR)
-
$(RM) $(RMCMD) $^
Makefile4
阅读(1340) | 评论(0) | 转发(0) |