尝试 link 个对象使它们重新编译,即使它们是最新的

Attempt to link objects makes them recompile even if up-to-date

我的 makefile 中有一个配方依赖于多个目标文件。我希望它只是 link 它们,但它们总是在重新编译。
我搜索了一下,发现了我不知道的信息(用#标记)并稍微更改了它,但问题仍然存在。

我被引导相信 make 期望配方的名称是文件的名称,但我未能做到这一点。问题是我没有别的办法来尝试解决这个问题。我将不胜感激

CC = g++
#.PHONY: sfml-app

LIBS = -lsfml-graphics -lsfml-window -lsfml-system

APPLICATION = sfml-app

INCLUDE_DIR = -I include/
SOURCE_DIR  = source
OUTPUT_DIR  = bin

SOURCES     = $(wildcard $(SOURCE_DIR)/*.cpp)
OBJECTS     = $(notdir $(patsubst %.cpp, %.o, $(SOURCES)))

#$(OUTPUT_DIR)/$(APPLICATION): $(OBJECTS)
#bin/sfml-app: $(OBJECTS)
#sfml-app: $(OBJECTS)
#$(APPLICATION): $(OBJECTS)
    $(CC) $(OUTPUT_DIR)/*.o $(LIBS) -o $(OUTPUT_DIR)/$(APPLICATION)

%.o: $(SOURCE_DIR)/%.cpp
    $(CC) -c $< $(INCLUDE_DIR) -o $(OUTPUT_DIR)/$@

clean:
    rm $(OUTPUT_DIR)/*

print-%  : ; @echo $* = $($*)

此规则不会创建它承诺的文件:

%.o: $(SOURCE_DIR)/%.cpp
    $(CC) -c $< $(INCLUDE_DIR) -o $(OUTPUT_DIR)/$@

看到-o $(OUTPUT_DIR)/$@了吗?这指示编译器在 $(OUTPUT_DIR) 而不是工作目录中创建文件。

如果您真的希望目标文件进入 $(OUTPUT_DIR),您需要确保您的规则表明:

$(OUTPUT_DIR)/%.o: $(SOURCE_DIR)/%.cpp
    $(CC) -c $< $(INCLUDE_DIR) -o $@

或者更好,像标准 %.o: %.c 规则(将包括 CFLAGS 等):

$(OUTPUT_DIR)/%.o: $(SOURCE_DIR)/%.cpp
    $(COMPILE.c) $(OUTPUT_OPTION) $<

我注意到您的输入文件被命名为 *.cpp - 通常,该约定适用于 C++ 文件(即使用 $(COMPILE.cc) 编译,这将调用 $(CXX) 而不是 $(CC)).检查您是否混淆了 C 和 C++ 源代码!