我正在尝试编写一个makefile,它能够确定何时更改了标头,然后重新编译相应的.cpp文件。为了测试这一点,我创建了三个文件:main.cpp
,a.h
和b.h
。 main.cpp
包括a.h
和a.h
包括b.h
。
我的makefile如下所示:
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文件添加完整和完整的标题集的情况下完成我想要的内容(因为对于较大的项目,这可能会变得非常麻烦):
prog: main.cpp a.h b.h
g++ ...
答案 0 :(得分:6)
我做错了什么
你的规则:
a.h: b.h
仅告诉make
a.h
取决于b.h
,即a.h
需要make
以({1}}可以从makefile中确定的任何方式(重新)创建if
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
的{{1}}。因此,如果没有任何方法,可以从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
更改时以任何方式重新制作。你想要 prog
当任何一个改变时重制。你想要的是任何一个表达的
以下makefile:
<强> 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
如何在不添加完整整套的情况下完成我想要的任务 像这样的每个.cpp文件的标头 (因为对于较大的项目,这可能变得非常麻烦)
确实会这样,因此GCC编译器已经有很长一段时间了
用于生成表示依赖性的迷你makefile的功能
将在每个头文件上生成的目标文件
被读取以便制作目标文件。 GNU make可以利用此功能
生成那些依赖文件并将它们包含在makefile中以构建GCC目标。这种合作之间
GCC和make
称为自动依赖生成(或类似)。该
如何在makefile中执行此操作的问题与this one重复
如果你谷歌,例如“gcc auto generate dependencies”你也可以找到guru治疗。
在评论中,您建议您还没有足够的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
。