我正在学习Makefiles,并决定写下我的第一个练习。我有一个包含两个文件的目录:
Makefile makefile.cpp
这是makefile.cpp(惊喜!):
#include <iostream>
int main() {
std::cout << "Hello World!\n";
return 0;
}
这是Makefile:
CC = g++
FILES = makefile.cpp
OUT_EXE = makefileout
build: $(FILES)
$(CC) -o $(OUT_EXE) $(FILES)
然后我运行make -d并得到一个很长的日志:
$ make -d GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for x86_64-pc-linux-gnu Reading makefiles... Reading makefile `Makefile'... Updating makefiles.... Considering target file `Makefile'. Looking for an implicit rule for `Makefile'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.o'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.c'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.cc'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.C'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.cpp'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.p'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.f'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.F'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.r'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.s'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.S'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.mod'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.sh'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile,v'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `RCS/Makefile,v'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `RCS/Makefile'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `s.Makefile'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `SCCS/s.Makefile'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.o'. Looking for a rule with intermediate file `Makefile.o'. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.c'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.cc'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.C'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.cpp'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.p'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.f'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.F'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.r'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.s'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.S'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.mod'. Trying pattern rule with stem `Makefile.o'. Trying implicit prerequisite `Makefile.o,v'. Trying pattern rule with stem `Makefile.o'. Trying implicit prerequisite `RCS/Makefile.o,v'. Trying pattern rule with stem `Makefile.o'. Trying implicit prerequisite `RCS/Makefile.o'. Trying pattern rule with stem `Makefile.o'. Trying implicit prerequisite `s.Makefile.o'. Trying pattern rule with stem `Makefile.o'. Trying implicit prerequisite `SCCS/s.Makefile.o'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.c'. Looking for a rule with intermediate file `Makefile.c'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.y'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.l'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.w'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.w'. Trying pattern rule with stem `Makefile.c'. Trying implicit prerequisite `Makefile.c,v'. Trying pattern rule with stem `Makefile.c'. Trying implicit prerequisite `RCS/Makefile.c,v'. Trying pattern rule with stem `Makefile.c'. Trying implicit prerequisite `RCS/Makefile.c'. Trying pattern rule with stem `Makefile.c'. Trying implicit prerequisite `s.Makefile.c'. Trying pattern rule with stem `Makefile.c'. Trying implicit prerequisite `SCCS/s.Makefile.c'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.y'. Looking for a rule with intermediate file `Makefile.y'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.y'. Trying implicit prerequisite `Makefile.y,v'. Trying pattern rule with stem `Makefile.y'. Trying implicit prerequisite `RCS/Makefile.y,v'. Trying pattern rule with stem `Makefile.y'. Trying implicit prerequisite `RCS/Makefile.y'. Trying pattern rule with stem `Makefile.y'. Trying implicit prerequisite `s.Makefile.y'. Trying pattern rule with stem `Makefile.y'. Trying implicit prerequisite `SCCS/s.Makefile.y'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.l'. Looking for a rule with intermediate file `Makefile.l'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.l'. Trying implicit prerequisite `Makefile.l,v'. Trying pattern rule with stem `Makefile.l'. Trying implicit prerequisite `RCS/Makefile.l,v'. Trying pattern rule with stem `Makefile.l'. Trying implicit prerequisite `RCS/Makefile.l'. Trying pattern rule with stem `Makefile.l'. Trying implicit prerequisite `s.Makefile.l'. Trying pattern rule with stem `Makefile.l'. Trying implicit prerequisite `SCCS/s.Makefile.l'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.w'. Looking for a rule with intermediate file `Makefile.w'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.w'. Trying implicit prerequisite `Makefile.w,v'. Trying pattern rule with stem `Makefile.w'. Trying implicit prerequisite `RCS/Makefile.w,v'. Trying pattern rule with stem `Makefile.w'. Trying implicit prerequisite `RCS/Makefile.w'. Trying pattern rule with stem `Makefile.w'. Trying implicit prerequisite `s.Makefile.w'. Trying pattern rule with stem `Makefile.w'. Trying implicit prerequisite `SCCS/s.Makefile.w'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.w'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.cc'. Looking for a rule with intermediate file `Makefile.cc'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.cc'. Trying implicit prerequisite `Makefile.cc,v'. Trying pattern rule with stem `Makefile.cc'. Trying implicit prerequisite `RCS/Makefile.cc,v'. Trying pattern rule with stem `Makefile.cc'. Trying implicit prerequisite `RCS/Makefile.cc'. Trying pattern rule with stem `Makefile.cc'. Trying implicit prerequisite `s.Makefile.cc'. Trying pattern rule with stem `Makefile.cc'. Trying implicit prerequisite `SCCS/s.Makefile.cc'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.C'. Looking for a rule with intermediate file `Makefile.C'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.C'. Trying implicit prerequisite `Makefile.C,v'. Trying pattern rule with stem `Makefile.C'. Trying implicit prerequisite `RCS/Makefile.C,v'. Trying pattern rule with stem `Makefile.C'. Trying implicit prerequisite `RCS/Makefile.C'. Trying pattern rule with stem `Makefile.C'. Trying implicit prerequisite `s.Makefile.C'. Trying pattern rule with stem `Makefile.C'. Trying implicit prerequisite `SCCS/s.Makefile.C'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.cpp'. Looking for a rule with intermediate file `Makefile.cpp'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.cpp'. Trying implicit prerequisite `Makefile.cpp,v'. Trying pattern rule with stem `Makefile.cpp'. Trying implicit prerequisite `RCS/Makefile.cpp,v'. Trying pattern rule with stem `Makefile.cpp'. Trying implicit prerequisite `RCS/Makefile.cpp'. Trying pattern rule with stem `Makefile.cpp'. Trying implicit prerequisite `s.Makefile.cpp'. Trying pattern rule with stem `Makefile.cpp'. Trying implicit prerequisite `SCCS/s.Makefile.cpp'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.p'. Looking for a rule with intermediate file `Makefile.p'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.web'. Trying pattern rule with stem `Makefile.p'. Trying implicit prerequisite `Makefile.p,v'. Trying pattern rule with stem `Makefile.p'. Trying implicit prerequisite `RCS/Makefile.p,v'. Trying pattern rule with stem `Makefile.p'. Trying implicit prerequisite `RCS/Makefile.p'. Trying pattern rule with stem `Makefile.p'. Trying implicit prerequisite `s.Makefile.p'. Trying pattern rule with stem `Makefile.p'. Trying implicit prerequisite `SCCS/s.Makefile.p'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.web'. Looking for a rule with intermediate file `Makefile.web'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.web'. Trying implicit prerequisite `Makefile.web,v'. Trying pattern rule with stem `Makefile.web'. Trying implicit prerequisite `RCS/Makefile.web,v'. Trying pattern rule with stem `Makefile.web'. Trying implicit prerequisite `RCS/Makefile.web'. Trying pattern rule with stem `Makefile.web'. Trying implicit prerequisite `s.Makefile.web'. Trying pattern rule with stem `Makefile.web'. Trying implicit prerequisite `SCCS/s.Makefile.web'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.f'. Looking for a rule with intermediate file `Makefile.f'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.F'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.r'. Trying pattern rule with stem `Makefile.f'. Trying implicit prerequisite `Makefile.f,v'. Trying pattern rule with stem `Makefile.f'. Trying implicit prerequisite `RCS/Makefile.f,v'. Trying pattern rule with stem `Makefile.f'. Trying implicit prerequisite `RCS/Makefile.f'. Trying pattern rule with stem `Makefile.f'. Trying implicit prerequisite `s.Makefile.f'. Trying pattern rule with stem `Makefile.f'. Trying implicit prerequisite `SCCS/s.Makefile.f'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.F'. Looking for a rule with intermediate file `Makefile.F'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.F'. Trying implicit prerequisite `Makefile.F,v'. Trying pattern rule with stem `Makefile.F'. Trying implicit prerequisite `RCS/Makefile.F,v'. Trying pattern rule with stem `Makefile.F'. Trying implicit prerequisite `RCS/Makefile.F'. Trying pattern rule with stem `Makefile.F'. Trying implicit prerequisite `s.Makefile.F'. Trying pattern rule with stem `Makefile.F'. Trying implicit prerequisite `SCCS/s.Makefile.F'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.r'. Looking for a rule with intermediate file `Makefile.r'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.l'. Trying pattern rule with stem `Makefile.r'. Trying implicit prerequisite `Makefile.r,v'. Trying pattern rule with stem `Makefile.r'. Trying implicit prerequisite `RCS/Makefile.r,v'. Trying pattern rule with stem `Makefile.r'. Trying implicit prerequisite `RCS/Makefile.r'. Trying pattern rule with stem `Makefile.r'. Trying implicit prerequisite `s.Makefile.r'. Trying pattern rule with stem `Makefile.r'. Trying implicit prerequisite `SCCS/s.Makefile.r'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.F'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.r'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.s'. Looking for a rule with intermediate file `Makefile.s'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.S'. Trying pattern rule with stem `Makefile.s'. Trying implicit prerequisite `Makefile.s,v'. Trying pattern rule with stem `Makefile.s'. Trying implicit prerequisite `RCS/Makefile.s,v'. Trying pattern rule with stem `Makefile.s'. Trying implicit prerequisite `RCS/Makefile.s'. Trying pattern rule with stem `Makefile.s'. Trying implicit prerequisite `s.Makefile.s'. Trying pattern rule with stem `Makefile.s'. Trying implicit prerequisite `SCCS/s.Makefile.s'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.S'. Looking for a rule with intermediate file `Makefile.S'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.S'. Trying implicit prerequisite `Makefile.S,v'. Trying pattern rule with stem `Makefile.S'. Trying implicit prerequisite `RCS/Makefile.S,v'. Trying pattern rule with stem `Makefile.S'. Trying implicit prerequisite `RCS/Makefile.S'. Trying pattern rule with stem `Makefile.S'. Trying implicit prerequisite `s.Makefile.S'. Trying pattern rule with stem `Makefile.S'. Trying implicit prerequisite `SCCS/s.Makefile.S'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.S'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.mod'. Looking for a rule with intermediate file `Makefile.mod'. Avoiding implicit rule recursion. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.mod'. Trying implicit prerequisite `Makefile.mod,v'. Trying pattern rule with stem `Makefile.mod'. Trying implicit prerequisite `RCS/Makefile.mod,v'. Trying pattern rule with stem `Makefile.mod'. Trying implicit prerequisite `RCS/Makefile.mod'. Trying pattern rule with stem `Makefile.mod'. Trying implicit prerequisite `s.Makefile.mod'. Trying pattern rule with stem `Makefile.mod'. Trying implicit prerequisite `SCCS/s.Makefile.mod'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.c'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.cc'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.C'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.cpp'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.p'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.f'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.F'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.r'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.s'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.S'. Trying pattern rule with stem `Makefile'. Rejecting impossible implicit prerequisite `Makefile.mod'. Trying pattern rule with stem `Makefile'. Trying implicit prerequisite `Makefile.sh'. Looking for a rule with intermediate file `Makefile.sh'. Avoiding implicit rule recursion. Trying pattern rule with stem `Makefile.sh'. Trying implicit prerequisite `Makefile.sh,v'. Trying pattern rule with stem `Makefile.sh'. Trying implicit prerequisite `RCS/Makefile.sh,v'. Trying pattern rule with stem `Makefile.sh'. Trying implicit prerequisite `RCS/Makefile.sh'. Trying pattern rule with stem `Makefile.sh'. Trying implicit prerequisite `s.Makefile.sh'. Trying pattern rule with stem `Makefile.sh'. Trying implicit prerequisite `SCCS/s.Makefile.sh'. No implicit rule found for `Makefile'. Finished prerequisites of target file `Makefile'. No need to remake target `Makefile'. Updating goal targets.... Considering target file `build'. File `build' does not exist. Considering target file `makefile.cpp'. Looking for an implicit rule for `makefile.cpp'. Trying pattern rule with stem `makefile.cpp'. Trying implicit prerequisite `makefile.cpp,v'. Trying pattern rule with stem `makefile.cpp'. Trying implicit prerequisite `RCS/makefile.cpp,v'. Trying pattern rule with stem `makefile.cpp'. Trying implicit prerequisite `RCS/makefile.cpp'. Trying pattern rule with stem `makefile.cpp'. Trying implicit prerequisite `s.makefile.cpp'. Trying pattern rule with stem `makefile.cpp'. Trying implicit prerequisite `SCCS/s.makefile.cpp'. No implicit rule found for `makefile.cpp'. Finished prerequisites of target file `makefile.cpp'. No need to remake target `makefile.cpp'. Finished prerequisites of target file `build'. Must remake target `build'. g++ -o makefileout makefile.cpp Putting child 0x01a6de60 (build) PID 6157 on the chain. Live child 0x01a6de60 (build) PID 6157 Reaping winning child 0x01a6de60 PID 6157 Removing child 0x01a6de60 PID 6157 from chain. Successfully remade target file `build'.
我的问题:我做错了吗?为什么这么简单的例子会产生如此多的日志?
此外,即使源代码早于最新的make
,我的Makefile也似乎总是重新编译目标代码。换句话说,我从未见过这样的信息:“没有什么可做的。”
答案 0 :(得分:5)
因为您将“-d”传递给“make”。 “-d”参数是产生所有噪音的原因。
-d Print debugging information in addition to normal processing. The
debugging information says which files are being considered for
remaking, which file-times are being compared and with what
results, which files actually need to be remade, which implicit
rules are considered and which are applied---everything interest‐
ing about how make decides what to do.
因此,请停止传递-d
,然后您将获得您可能期望的输出。
答案 1 :(得分:5)
好吧,您已经要求使用-d
选项进行调试。你说对了。如果你问为什么GNU make有如此多的隐式规则,每次make进程都会检查Makefile - 这主要是出于历史原因。有构建系统(例如Ninja)没有这么长的开发历史,因此内部的东西较少。
答案 2 :(得分:2)
默认情况下,make有很多关于通过编译构建应用程序的预定义规则。见https://www.gnu.org/software/make/manual/make.html#Implicit-Rules
通过将.SUFFIXES:
添加到makefile中,您可以大幅减少所需的工作量。因此,由于许多规则现在不再存在,这可能会削弱您的制作。
我发现即使我使用.SUFFIXES:
,由于Makefile位于git checkout中,我仍然会得到隐式规则。我的项目与编译应用程序无关。
减少工作量的另一种方法是从命令行禁用后缀。使用-r
或--no-builtin-rules
标志会导致默认的后缀列表为空。
答案 3 :(得分:1)
我将解决编辑问题:
我的Makefile似乎总是重新编译对象代码,即使是 源代码比最新的make
旧
在这个答案中。
考虑你的Makefile:
CC = g++
FILES = makefile.cpp
OUT_EXE = makefileout
build: $(FILES)
$(CC) -o $(OUT_EXE) $(FILES)
这里唯一的目标是build
,这是永远不会构造的(这就是为什么你每次都看到编译的原因)。对此最简单的解决方法应该是:
CC = g++
FILES = makefile.cpp
OUT_EXE = makefileout
${OUT_EXE}: $(FILES)
$(CC) -o $(OUT_EXE) $(FILES)
新规则make
会检查makefileout
而非build
,从而提供预期的行为。
如果您想进行更多实验,可以使用Makefile发出以下命令:
rm -f makefileout
touch build
make
即使可执行文件不存在,您也会认为make
无法编译它。我告诉你为什么(一个简单的)练习。
答案 4 :(得分:0)
将-d flag
传递给make会产生打印附加信息的效果,这有时有助于调试问题。