(抱歉英语不好,我是德国人)
Hello Programmers,
我正在为我的C ++项目使用GNU make,但是我对自动依赖项有些麻烦: 如果我执行“make objects / file.o”,它会告诉我,即使source / file.cpp包含的文件发生了变化,objects / file.o也已经是最新的。 奇怪的是,如果我将DEP_DIR和OBJ_DIR更改为“。”一切正常。 这是我的makefile(不完整):
SRC_DIR := source
DEP_DIR := dependencies
OBJ_DIR := objects
$(shell mkdir -p $(dir EXE_PATH))
-include $(addprefix $(DEP_DIR)/, $(NAMES:=.d))
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
$(CXX) -c $(CFLAGS) $(SRC_DIR)/$*.cpp -o $@
$(CXX) -MM $(CFLAGS) $^ > $(DEP_DIR)/$*.d
$(EXE_PATH) : $(addprefix $(OBJ_DIR)/, $(NAMES:=.o))
$(CXX) $(LINK_FLAGS) $^ -o $(EXE_PATH)
all : $(EXE_PATH)
run :
$(EXE_PATH)
carun : $(EXE_PATH)
$(EXE_PATH)
clean:
rm -f EXE_PATH
如果有人能向我解释这个奇怪的问题,我将感激不尽。
答案 0 :(得分:1)
回答您关于您所看到的错误的问题:在解析makefile之前,会立即展开目标或先决条件列表中出现的宏和函数,早在make开始运行与模式匹配的规则并替换之前%
。所以,在这一行:
$(depDir)/%.d : $(srcPath)/%.cpp $(shell cat $(depDir)/%.d)
当make在makefile中读取时调用shell
函数,此时它将只使用逐字字符串%.d
,因为尚未发生模式匹配。
正如其他答案中所提到的,这不是生成自动依赖生成的正确方法(您实际上并未显示这些.d
文件是如何生成的,因此很难给出具体建议)。
如果您想了解如何以更现代,更有效的方式执行此操作,可以查看this blog post。
答案 1 :(得分:0)
现在不是如何完成依赖项生成,您可以生成依赖项作为编译的side effect。还可以使用内置变量名称CXX
,CPPFLAGS
,CXXFLAGS
,LDFLAGS
和LDLIBS
,并回收make内置的食谱。
.PHONY: all
all: Release/$(EXE_NAME)
echo "finished building... in theory"
Release/$(EXE_NAME): CC := $(CXX)
Release/$(EXE_NAME): $(OBJS) | Release
$(LINK.o) $^ $(LDLIBS) -o $@
$(objDir)/%.o: CPPFLAGS += -MMD -MP
$(objDir)/%.o: $(srcPath)/%.cpp | $(objDir)
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
$(objDir) Release: ; mkdir -p $@
-include $(OBJS:.o=.d)