makefile:依赖项不构建

时间:2018-01-26 14:18:45

标签: makefile

这个问题是在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。

2 个答案:

答案 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标志允许为目标名称提供文字行。