这个问题是在MadScientist的答案之后编辑的。查看原始makefile的历史记录,但问题保持不变。
我有一个小的makefile:
DEPFLAGS=-MD -Mo $(OUTDIR)/$*.Td
POSTCOMPILE=@mv -f $(OUTDIR)/$*.Td $(OUTDIR)/$*.d && touch $@
VPATH=../src
OUTDIR=../out
SOURCES:=$(notdir $(wildcard ../src/*.c))
OBJECTS:=$(SOURCES:%.c=$(OUTDIR)/%.o)
all: $(OBJECTS) $(OBJECTS:%.o=%.d)
$(OUTDIR)/%.o : %.c
$(OUTDIR)/%.o : %.c $(OUTDIR)/%.d
@$(CC) $(DEPFLAGS) -c $< -o $@
@$(POSTCOMPILE)
$(OUTDIR)/%.d : ;
.PRECIOUS: $(OUTDIR)/%.d
目录结构如下:
src
contains file.c
out
empty, after make: contains file.o and file.d
make
contains the makefile
当我调用makefile时,一切正常并生成两个文件: file.o 和 file.d
但是,当我删除 file.d 时,没有任何反应。我希望make找到 file.c 缺少的依赖项并开始重建。为什么不发生?
在Windows 7下为i386-pc-mingw32制作版本3.81。
答案 0 :(得分:1)
将文件标记为.PRECIOUS
并不会删除它的所有方面&#34;中间性&#34;。它只是阻止它被删除,但intermediate files的这个功能仍然有效:
如果普通文件b不存在,并且make考虑依赖于b的目标,则它总是创建b,然后从b更新目标。但是如果b是一个中间文件,那么make就可以单独留下。它不会打扰更新b或最终目标,除非b的某些先决条件比该目标更新或者有其他理由更新该目标。
这就是为什么不重新创建.d
文件的原因。为了重新创建它,您需要确保它不是中间文件。幸运的是,这是微不足道的:你只需要在某处明确地提到文件作为目标或先决条件。你可以这样做:
all: $(OBJECTS) $(SOURCES:%.c=$(OUTDIR)/%.d)
或者如果你喜欢这样:
depends: $(SOURCES:%.c=$(OUTDIR)/%.d)
如果你愿意的话,允许你运行make depends
来更新依赖文件。
我只是简单地指出这种管理依赖关系的方法被认为是过时的。有一种更好,更先进的方式可以在其他地方进行described here。
答案 1 :(得分:0)
(我将在这里成为一个可怕的死灵法师,但我遇到了同样的问题,发现实际的问题不在此处的答案或评论中提及)
由编译器默认生成的相关性规则是体育文件名,其中所有后缀都被单个后缀.o 并删除了路径。哪个与makefile中的规则模式不匹配。
对于gcc 4.x和更高版本,正确的选项应该是
$(OUTDIR)/%.o : %.c $(OUTDIR)/%.d
@$(CC) -MF $(OUTDIR)/$*.Td -MT $@ -c $< -o $@
Mo标志不再存在,您仅需使用MF标志来指定依赖文件名.MT标志允许为目标名称提供文字行。