makefile - 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)
解决方案
这个结构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
第一次运行时,它会发现依赖文件丢失,并将使用模式规则来构建它们。
推荐阅读
- scala - scala 和 dotty 的下限和上限类型
- javascript - JavaScript:打印动态值/数据
- google-cloud-platform - GCP:创建包括运行时进程的 VM 快照
- java - 在用户的 gmail 中更新时,无法更新 firebase 数据库中的数据
- python-3.x - psycopg2 不会将数据保存到 postgres 数据库中
- javascript - 无法使用 JQuery 获取输入字段的值
- amazon-web-services - AWS 为 S3 文件夹级别访问生成动态凭证?
- javascript - d3js连续节点颜色网络 - 无法找出问题
- java - 如何仅使用循环(无数组)找到第二高分
- python - 来自groupby的python图不显示x轴值