重建时不存在目标`mytarget`的先决条件`myphony` - 好像myphony是一个文件

时间:2015-10-08 22:08:01

标签: makefile

我的Makefile已重新编译我的所有源文件,即使它们没有更改。我用make -d看了一下,发现了这样的东西:

  ...
  Prerequisite `setup' of target `bin/exception/Exceptions.o' does not exist.
Must remake target `bin/exception/Exceptions.o'.
...

请注意,这是 bin/exception/Exceptions.o编译完成后的内容。

现在地球上没有先决条件意味着什么呢?我已经非常明确地宣布了这一点,并将其标记为PHONY。这个例子应该为你产生相同的结果(你应该只能运行它 - 我已经为它生成了所有必要的文件)

OBJ_DIR=bin
SRC_DIR=src
OBJS=$(OBJ_DIR)/exception/Exception.o

.PHONY: all

all: $(OBJ_DIR)/app

.PHONY: setup

setup:
    mkdir -p $(sort $(dir $(OBJS)))

# To make the source file for you
$(SRC_DIR)/%.cpp:
    @mkdir -p $(dir $@)
    touch $@

$(OBJ_DIR)/app: setup $(OBJS)
    @echo CXX -o $@
    @touch $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp setup
    @echo CXX -c -o $@
    @cp $< $@

如果我取消setup的要求,那么我的程序将不会按预期重新编译未更改的来源。

为什么make认为需要重建?

1 个答案:

答案 0 :(得分:2)

  

[Phony targets]不应该是真实目标文件的先决条件。

来自Phony targets的手册部分。

您所看到的是原因的一部分。 make 总是认为虚假的目标是过时的,需要重建。因此(并且因为文件不存在)也适用于任何依赖于它的东西。

这个问题有两个简单的解决方案。

首先是让setup成为Force Target而不是.PHONY目标,这将使其正常运作(它也可能也想成为Empty Target但是只要它被触及至少一次它应该工作)。

第二个是让setup成为order-only prerequisite

$(OBJ_DIR)/app: $(OBJS) | setup

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | setup

您还可以确保正常的输出目标配方在尝试使用之前创建输出目录。

$(OBJ_DIR)/app: $(OBJS)
    @mkdir -p $(@D)
    @echo CXX -o $@
    @touch $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    @mkdir -p $(@D)
    @echo CXX -c -o $@
    @cp $< $@