我正在尝试编写一个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
Run Code Online (Sandbox Code Playgroud)
当和,和更改的任何组合时a.h,我希望重新编译.尽管如此,只有重新编译时或发生变化,到最后一行似乎被忽略.b.hmain.cppprogproga.hmain.cpp
我做错了什么,如何在不向每个单独的.cpp文件添加完整和完整的标题集的情况下完成我想要的任务(因为对于较大的项目,这可能变得非常麻烦):
prog: main.cpp a.h b.h
g++ ...
Run Code Online (Sandbox Code Playgroud)
我做错了什么
你的规则:
a.h: b.h
Run Code Online (Sandbox Code Playgroud)
只是告诉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
Run Code Online (Sandbox Code Playgroud)
此外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变化.您希望在任何更改时重建prog.你想要的是由以下任何makefile表达的:
1
prog: main.cpp a.h b.h
g++ main.cpp -o prog
Run Code Online (Sandbox Code Playgroud)
2
prog: main.cpp a.h
g++ main.cpp -o prog
prog: b.h
Run Code Online (Sandbox Code Playgroud)
3
prog: main.cpp b.h
g++ main.cpp -o prog
prog: a.h
Run Code Online (Sandbox Code Playgroud)
4
prog: main.cpp
g++ main.cpp -o prog
prog: a.h b.h
Run Code Online (Sandbox Code Playgroud)
五
prog: main.cpp
g++ main.cpp -o prog
prog: a.h
prog: b.h
Run Code Online (Sandbox Code Playgroud)
(还有一些).他们都是等同的.他们都说这prog取决于main.cpp,a.h而且b.h他们都说prog需要重新制作时要做什么
,即:
g++ main.cpp -o prog
Run Code Online (Sandbox Code Playgroud)
如何在不向每个单独的.cpp文件添加完整和完整的标头集的情况下完成我想要的工作(因为对于较大的项目,这可能变得非常麻烦)
实际上它会,并且因此GCC编译器在很长一段时间内都有一个生成mini-makefile的功能,它表示将在每个读取的头文件上生成的目标文件的依赖关系,以便制作目标文件.GNU make可以利用此功能生成这些依赖项文件,并将它们包含在makefile中以构建GCC目标.GCC之间的这种合作make被称为自动依赖生成(或类似).如何在makefile中执行此操作的问题与此相关
,如果您使用google,例如"gcc auto generate dependencies",您还可以找到guru处理.
在评论中,您建议您尚未充分了解GNU make,以便对这些答案中说明的自动依赖生成技术充满信心.好吧,您可以通过简单的实现开始了解它(这也使得makefile在其他方面更正常):
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
Run Code Online (Sandbox Code Playgroud)
-MMD是生成依赖项文件的GCC预处理器选项
prog.d.这是文档-MMD
prog.d 是一个迷你makefile:
$ cat prog.d
prog.o: main.cpp a.h b.h
Run Code Online (Sandbox Code Playgroud)
表达的所有依赖关系prog.o.第一次运行时,include-ed makefile prog.d将不存在,这将是一个致命的make
错误,但-前缀告诉make忽略该错误.因此make,无论何时
需要重新编译任何规则(包括规则本身),所以继续进行所有事情,包括prog.d获取,然后
prog.d再进行.prog.dprog.o