首页 > 解决方案 > GNU Make 中的 -include 是什么以及它是如何工作的?

问题描述

-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)

标签: makefilegnu-make

解决方案


这个结构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

这允许我们删除-from -include,因为当make 第一次运行时,它会发现依赖文件丢失,并将使用模式规则来构建它们。


推荐阅读