文章目录
1. 组织 .dep 文件到指定目录
解决思路:
-当 include 发现 .dep 文件不存在时
1. 通过股则和命令创建 deos 文件
2. 将所有 .dep 文件创建到 deps文件夹
初步代码设计
.PHONY : all clean
MKDIR := mkdir
RM := rm -fr
CC := gcc
DIR_DEPS := deps
SRCS := $(wildcard *.c)
DEPS := $(SRCS:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
include $(DEPS)
all :
@echo "all"
$(DIR_DEPS) :
$(MKDIR) $@
$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
@echo "Creating $@ ..."
@set -e; \
$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g' > $@
clean :
$(RM) $(DIR_DEPS)
代码执行结果:
结果出现了一点小问题:func.dep 这个文件重复创建了,因为在deps目录下创建了 main.dep文件后,这个文件夹的时间戳最新,所以要重新创建func.dep
代码优化:
.PHONY : all clean
MKDIR := mkdir
RM := rm -fr
CC := gcc
DIR_DEPS := deps
SRCS := $(wildcard *.c)
DEPS := $(SRCS:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
all :
@echo "all"
ifeq ("$(MAKECMDGOALS)", "all")
-include $(DEPS)
endif
ifeq ("$(MAKECMDGOALS)", "")
-include $(DEPS)
endif
$(DIR_DEPS) :
$(MKDIR) $@
ifeq ("$(wildcard $(DIR_DEPS))", "") # 加上if 判断
$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
else
$(DIR_DEPS)/%.dep : %.c
endif
@echo "Creating $@ ..."
@set -e; \
$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g' > $@
clean :
$(RM) $(DIR_DEPS)
2. include 暗黑操作
2.1 include 暗黑操作1
在include前
使用减号不但关闭了 include
发出的警告,同时关闭了错误;当错误发生时 make 将忽略这些错误!
示例:
.PHONY : all
-include test.txt
all :
@echo "this is all"
2.2 include 暗黑操作二:
如果 include 触发规则创建了文件,之后还会发生什么?
示例:
.PHONY : all
-include test.txt
all :
@echo "this is all"
test.txt :
@echo "creating $@ ..."
@echo "other : ; @echo "this is other" " > test.txt
由于 test.txt 中的内容使得 all 不再是顶层目标
2.3 include 暗黑操作三
如果 include 包含文件存在,但是文件名对应的规则有依赖,并且依赖更新,之后会发生什么?
示例:
.PHONY : all
-include test.txt
all :
@echo "this is all"
test.txt : b.txt
@echo "creating $@ ..."
2.4 include 总结
- 当目标文件不存在,以文件名查找规则并执行,当目标文件不存在,且查找到的规则中创建了目标文件,将
-当目标文件存在,将目标文件包含进当前makefile,以目标文件名查找是否有相应规则,并且比较规则的依赖关系,决定是否执行规则的命令,也就是说即使文件存在,命令也有可能被执行