【问题标题】:Why isn't make detecting changes in header dependencies为什么不检测标头依赖项的更改
【发布时间】:2013-04-25 18:14:22
【问题描述】:

我不确定我在这里做错了什么。我试图让 make 弄清楚我的项目有哪些依赖项,不仅是源文件,还有非系统包含的头文件。我有很多来自这个网站的与这个主题相关的资源。

如:Makefile header dependenciesMakefile, header dependencies

但是,当我这样做时

touch MyHeader.h

作为测试是否可行,我的制作过程无法重建包含此标头的源文件。所以,这就是我的 makefile 中的内容(相关性)

CPP=g++
CPPFLAGS=-Iadditional/includes -MMD
CXXFLAGS=-std=c++0x -c 
# not every source file in this directory needs to be included in this build
# this is because of shared code with Windows
SOURCESFILTER = File1.cpp File2.cpp

OBJ_DIR=obj
SOURCES = $(filter-out $(SOURCEFILTER),$(wildcard *.cpp))
OBJECTS = $(addprefix $(OBJ_DIR)/,$(SOURCES:.cpp=.o))

DEPENDENCIES = $(OBJECTS:.o=.d)

.PHONY: archive

archive : $(OBJECTS)
    ar mylib.a obj/*.o

-include $(DEPENDENCIES)

$(OBJ_DIR)/%.o: $(SOURCES) $(DEPENDENCIES)
    $(CPP) $(CPPFLAGS) $(CXXFLAGS) $< -o $@

我已验证上述过程确实生成了预期的 *.d 文件。我假设我正确地包括了它们。但是,如前所述,作为测试,我会: 触摸 MyHeader.h

与源代码位于同一目录中,然后重新运行 make,不会重新制作包含此标头的源文件。我错过了什么?

安迪

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    首先,您不能在后缀规则中包含先决条件。即使可以,您也肯定想要包含$(SOURCES)$(DEPENDENCIES),因为这会导致每个 对象在任何 时重建> 源文件或依赖文件已更改。

    其次,您不能在与 make 期望的目录不同的目录中创建目标文件。 Make会将它想要找到目标的位置放在变量$@中,并且您必须将输出准确地写入该位置。如果您曾经看到修改目标的规则,例如上面使用 obj/$@ 的规则,那将不起作用。

    很可能 GCC 将文件写为obj/foo.d,但您的include 试图包含foo.d,但那不存在...但是由于您使用了-include,所以不会抱怨。

    我建议您首先将目标文件写入本地目录并使用依赖项。一旦成功,然后阅读如何将目标写入不同的目录和/或再次询问。

    预计到达时间:

    试试这样的:

    CXX := g++
    CPPFLAGS := -Iadditional/includes -MMD
    CXXFLAGS := -std=c++0x
    # not every source file in this directory needs to be included in this build
    # this is because of shared code with Windows
    SOURCESFILTER := File1.cpp File2.cpp
    
    OBJ_DIR := obj
    SOURCES := $(filter-out $(SOURCEFILTER),$(wildcard *.cpp))
    OBJECTS := $(addprefix $(OBJ_DIR)/,$(SOURCES:.cpp=.o))
    
    DEPENDENCIES := $(OBJECTS:.o=.d)
    
    .PHONY: archive
    
    archive: mylib.a
    
    mylib.a: $(OBJECTS)
            $(AR) $@ $^
    
    -include $(DEPENDENCIES)
    
    $(OBJ_DIR)/%.o: %.cpp
            $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
    

    【讨论】:

    • 感谢您朝着正确的方向前进。我现在明白我的制作文件目标都是错误的。我已对此进行了更改,并将在提交此评论后更新我在此处发布的文本。我已经复制了 make 文件以尝试将它们构建到目录的本地。这行得通,但我在开始时遇到一个奇怪的错误,“致命错误:打开依赖文件 obj/*.d.d 没有这样的文件”。确实没有。这是来自本地构建的make文件???
    • 这个错误看起来不像是一个 make 错误。你剪切/粘贴了吗?还是转述?我建议您在变量分配中将= 更改为:=。同样正如我之前提到的,将$(SOURCES)$(DEPENDENCIES) 作为模式规则的先决条件确实是不正确的。一切都会一直重建。您不希望将依赖项作为任何东西的先决条件,您应该只使用一个 %.c 作为先决条件。我会更新我的答案。
    • 感谢您的帮助。这正是我所需要的。我非常接近答案,但并不完全在那里。我不确定如何使过滤器适用于模式规则 $(OBJ_DIR)/%.o: %.cpp。这似乎会编译每个源文件,显然我不希望这样。我还没有在 GNU 手册中找到 SOURCES 变量如何影响这一点,但显然这就是我想要的。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多