我正在尝试编写一个 makefile,它能够确定何时更改了 header ,然后重新编译相应的 .cpp 文件。为了测试这一点,我创建了三个文件: main.cpp
、 a.h
和 b.h
。 main.cpp
包括 s a.h
和 a.h
包括 b.h
。
我的生成文件如下所示:
prog: main.cpp a.h
g++ main.cpp -o prog
a.h: b.h
当
a.h
、 b.h
和 main.cpp
的任意组合发生变化时,我希望 prog
被重新编译。尽管如此,prog
仅在 a.h
或 main.cpp
更改时才重新编译,最后一行似乎被忽略。我在做什么不正确以及如何在不向这样的每个单独的 .cpp 文件中添加完整和完整的 header 集的情况下完成我想要的(因为对于较大的项目,这可能变得非常麻烦):
prog: main.cpp a.h b.h
g++ ...
最佳答案
你的规则:
a.h: b.h
只是告诉
make
a.h
取决于 b.h
,即 a.h
需要被(重新)制作,以
make
可以从 makefile 中确定的任何方式,如果a.h
比 b.h
旧或不存在。它没有告诉
make
如何从 a.h
重新制作 b.h
。你的makefile不包含从
a.h
重新制作 b.h
的方法。它只包含一个配方用于从
prog
和 main.cpp
重新制作 a.h
,即:prog: main.cpp a.h
g++ main.cpp -o prog
此外
make
,当然,没有内置的规则来制作a.h
来自 b.h
。因此,在没有任何从 a.h
制作 b.h
的方法的情况下它假设这种依赖不需要做任何事情。没有
其他合理违约。因此,即使
a.h
比 b.h
旧,也没有a.h
已完成;尽管 prog
依赖于 a.h
,但无需执行任何操作prog
在该帐户上。这是幸运的,因为实际上您不希望
a.h
在无论何时
b.h
发生任何变化,并且您不希望 main.cpp
成为当
a.h
或 b.h
改变时,以任何方式重新制作。你想要前卫当它们中的任何一个发生变化时重新制作。你想要的由任何一个表达
以下生成文件:
1
prog: main.cpp a.h b.h
g++ main.cpp -o prog
2
prog: main.cpp a.h
g++ main.cpp -o prog
prog: b.h
3
prog: main.cpp b.h
g++ main.cpp -o prog
prog: a.h
4
prog: main.cpp
g++ main.cpp -o prog
prog: a.h b.h
5
prog: main.cpp
g++ main.cpp -o prog
prog: a.h
prog: b.h
(还有一些)。他们都是等价的。他们都说
prog
取决于在
main.cpp
、 a.h
和 b.h
上,它们都说明了要做什么prog
需要重新制作,即: g++ main.cpp -o prog
确实会,因此 GCC 编译器在很长一段时间内都有
用于生成表示依赖关系的 mini-makefile 的功能
将在每个头文件上生成的目标文件
被读取以制作目标文件。 GNU make 可以利用这个特性
生成这些依赖文件并将它们包含在用于构建 GCC 目标的 makefile 中。之间的这种合作
GCC 和
make
被称为自动依赖生成(或类似)。这如何在 makefile 中执行此操作的问题是 this one 的拷贝
如果你谷歌,例如“gcc 自动生成依赖项”你也可以找到大师的治疗方法。
在评论中,您建议您对 GNU 还不够熟练
对所示的自动依赖生成技术充满信心
在 those answers 中。嗯,你
可以通过简单的基本实现开始掌握它
这样(这也使 makefile 在其他方面更正常):
生成文件
.PHONY: all clean
all: prog
prog: prog.o
prog.o: main.cpp
g++ -MMD -c -o prog.o main.cpp
prog: prog.o
g++ -o prog prog.o
clean:
rm -f prog *.o *.d
-include prog.d
-MMD
是生成依赖文件的 GCC 预处理器选项prog.d
。这是 the documentation of -MMD
prog.d
是一个迷你生成文件:$ cat prog.d
prog.o: main.cpp a.h b.h
表达
prog.o
的所有依赖项。这是第一次运行,include
-ed makefile prog.d
将不存在,这将是一个致命的 make
错误,但事实上 -
前缀告诉 make
忽略该错误。因此
make
继续进行,包括 prog.d
在内的所有内容都已生成,此后prog.d
将在任何规则时重新生成 - 包括 prog.d
中的规则本身 - 需要重新编译
prog.o
。关于c++ - 同一 Makefile 中 make 目标之间的递归依赖关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41906725/