1

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

如:Makefile头依赖Makefile、头依赖

但是,当我这样做时

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 文件。我假设我正确地包括了它们。但是,如前所述,作为我做的测试:touch MyHeader.h

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

安迪

4

1 回答 1

4

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

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

很可能 GCC 正在将文件编写为obj/foo.d,但您include正在尝试包含foo.d但不存在...但是由于您使用-includemake 不会抱怨。

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

预计到达时间:

尝试这样的事情:

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 $@ $<
于 2013-04-25T18:23:44.187 回答