Makefile每次都构建所有内容

Makefile每次都构建所有内容,makefile,build,gnu-make,Makefile,Build,Gnu Make,我将以下Makefile简化为忽略不相关的内容: BUILD_DIR=./build OBJS = \ $(BUILD_DIR)/main.o \ $(BUILD_DIR)/common.o \ ... roo: $(OBJS) $(CXX) -o $@ $(OBJS) $(LFLAGS) .PHONY: $(BUILD_DIR) $(BUILD_DIR): mkdir -p $(BUILD_DIR)/passes $(BUILD_DIR)/%.o: src/%

我将以下Makefile简化为忽略不相关的内容:

BUILD_DIR=./build
OBJS = \
  $(BUILD_DIR)/main.o \
  $(BUILD_DIR)/common.o \
  ...

roo: $(OBJS)
    $(CXX) -o $@ $(OBJS) $(LFLAGS)

.PHONY: $(BUILD_DIR)
$(BUILD_DIR):
    mkdir -p $(BUILD_DIR)/passes

$(BUILD_DIR)/%.o: src/%.cpp $(BUILD_DIR)
    $(CXX) -o $@ -c $< $(CFLAGS)
但是,每次都会重新编译每个对象文件,即使我是按照规则在每个非虚假目标中直接使用$@也是如此

我不认为这是重复的,因为我在规则中应用子目录,而不是在配方中,但我可能错了?如何让Make正确跟踪生成目录中的依赖项?

您已经声明$build\u DIR/%.o依赖于$build\u DIR,但是每次将文件添加到该目录(例如,通过该规则本身)时,都会触及该目录。也就是说,$BUILD_DIR将始终比其目标更新

看起来您希望自动创建生成目录。我认为,最好的办法是

$(BUILD_DIR)/%.o: src/%.cpp
    mkdir -p $(BUILD_DIR)/passes
    $(CXX) -o $@ -c $< $(CFLAGS)

谢谢完美修复了它,或者你可以创建dir:PHONY目标。在这个目标中,您可以运行mkdir-p${BUILD\u DIR}/过程,并且${BUILD\u DIR}/%.o的依赖项将创建DIR-因此您可以在需要时重复使用它。进行测试没有意义。您不妨运行mdir-p。如果目录已经存在,那将是不可操作的。@MadScientist,你知道吗,在我多年的Make经验中,我从来没有想到过这一点!但你完全正确。我将编辑答案以反映这一点。