GNU Make 中的 -include 是什么以及它是如何工作的?

What is -include in GNU Make and how it works?

-include 用于忽略不存在的文件。但是谁能告诉我这个例子中这些文件在哪里使用?

CXX    := g++
TARGET := exec

SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp, %.o, $(SOURCES))
DEPENDS := $(patsubst %.cpp, %.d, $(SOURCES))

DEPFLAGS = -MMD -MF $(@:.o=.d)

all: $(TARGET)

-include $(DEPENDS)

$(TARGET): $(OBJECTS)
    $(CXX) -o $@ $^

clean:
    $(RM) $(OBJECTS) $(DEPENDS) $(TARGET)

%.o: %.cpp
    $(CXX) -c $< $(DEPFLAGS)

这个Makefile的结构有点问题。

这是在尝试执行 Make 手册 Automatic Prerequisites 部分中讨论的技术的变体,但它实际上并没有按预期工作。

当您有 include 语句时,make 将尝试构建任何包含的文件(如果它们不存在)。不幸的是,Makefile 没有生成依赖关系的规则,这就是为什么它有 -include 而不是 include 的原因——第一次 运行 make 它会找不到提到的文件。

因为 Makefile$(DEPFLAGS) 添加到用于生成 .o 文件的命令行,所以第一次编译 .o 文件时会像这样:

g++ -c somefile.c -MMD -MF somefile.d

$(DEPFLAGS) 中的参数要求 g++somefile.d 中生成依赖项,因此 下一次 时间你 运行 make 它将在计算中使用依赖文件。

-MMD输出的依赖信息将是一系列make规则,看起来像这样(假设file1.cpp包括file2.h):

file1.o: file1.cpp file2.h

固定的 Makefile 可能看起来像这样:

CXX := g++
TARGET := exec

SOURCES := $(wildcard *.cpp)
OBJECTS := $(SOURCES:.cpp=.o)
DEPENDS := $(SOURCES:.cpp=.d)

%.d: %.cpp
    $(CXX) -M -MMD $<

all: $(TARGET)

$(TARGET): $(OBJECTS)
    $(CXX) -o $@ $^

clean:
    $(RM) $(OBJECTS) $(DEPENDS) $(TARGET)

include $(DEPENDS)

这里我们依赖make.cpp个文件编译成.o个文件的隐式规则,我们引入了一个构建.d个文件的模式规则来自 .cpp 个文件。

这允许我们从 -include 中删除 -,因为当 make 首先 运行s 它将看到依赖文件丢失,并将 使用模式规则来构建它们。