GNU make auto依赖项取决于目录

时间:2016-11-12 14:44:45

标签: makefile dependencies gnu-make

(抱歉英语不好,我是德国人)

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

如果有人能向我解释这个奇怪的问题,我将感激不尽。

2 个答案:

答案 0 :(得分:1)

回答您关于您所看到的错误的问题:在解析makefile之前,会立即展开目标或先决条件列表中出现的宏和函数,早在make开始运行与模式匹配的规则并替换之前%。所以,在这一行:

$(depDir)/%.d : $(srcPath)/%.cpp $(shell cat $(depDir)/%.d)

当make在makefile中读取时调用shell函数,此时它将只使用逐字字符串%.d,因为尚未发生模式匹配。

正如其他答案中所提到的,这不是生成自动依赖生成的正确方法(您实际上并未显示这些.d文件是如何生成的,因此很难给出具体建议)。

如果您想了解如何以更现代,更有效的方式执行此操作,可以查看this blog post

答案 1 :(得分:0)

现在不是如何完成依赖项生成,您可以生成依赖项作为编译的side effect。还可以使用内置变量名称CXXCPPFLAGSCXXFLAGSLDFLAGSLDLIBS,并回收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)