Reputation:
I am learning about Makefiles and decided to write my first exercise. I have a directory with two files:
Makefile makefile.cpp
Here is makefile.cpp (surprise surprise!):
#include <iostream>
int main() {
std::cout << "Hello World!\n";
return 0;
}
And here is Makefile:
CC = g++
FILES = makefile.cpp
OUT_EXE = makefileout
build: $(FILES)
$(CC) -o $(OUT_EXE) $(FILES)
And then I run make -d and get a very long log:
$ 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'.
The question I have: Am I doing something wrong? Why is so much logging being produced for such a simple example?
Also, my Makefile always seems to recompile the object code even if the source code is older than the latest make
. In other words, I have never seen the message, "There is nothing to do."
Upvotes: 4
Views: 2809
Reputation: 3988
By default, make has a lot of predefined rules regarding the building of application by compilation. See https://www.gnu.org/software/make/manual/make.html#Implicit-Rules
You can drastically reduce the amount of effort make goes through by adding .SUFFIXES:
to your makefile. As a consequence, this could cripple your make as a lot of rules are now no longer going to be present.
I've found that even if I use .SUFFIXES:
, I'll still get implicit rules due to the Makefile sitting in a git checkout. My project is NOT related to compiling applications.
Another way to reduce the amount of effort is to disable the suffixes from the command line. Using the -r
or --no-builtin-rules
flag causes the default list of suffixes to be empty.
Upvotes: 2
Reputation: 8032
I'll address the edit:
my Makefile always seems to recompile the object code even if the source code is older than the latest make
in this answer.
Consider your Makefile:
CC = g++
FILES = makefile.cpp
OUT_EXE = makefileout
build: $(FILES)
$(CC) -o $(OUT_EXE) $(FILES)
Here the only target is build
, which is something that is NEVER constructed (and that's why you see the compilation occurring every time). The simplest fix to this should be:
CC = g++
FILES = makefile.cpp
OUT_EXE = makefileout
${OUT_EXE}: $(FILES)
$(CC) -o $(OUT_EXE) $(FILES)
With the new rule make
will check for makefileout
and not build
, thus providing the expected behavior.
If you want to experiment a little more you may use your Makefile issuing the following commands:
rm -f makefileout
touch build
make
You'll se that even if the executable is not present, make
won't compile it. I leave to you the question why as (a simple) exercise.
Upvotes: 1
Reputation: 104494
Because you are passing "-d" to "make". The "-d" parameter is what's generating all the noise.
-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.
So stop passing -d
to make and you'll get the output you likely expect.
Upvotes: 5
Reputation: 4951
passing the -d flag
to make has the effect of printing additional information which is sometimes helpful in debugging problems.
Upvotes: 0
Reputation: 17455
Well, you have asked for debug with -d
option. You got it. If you ask why GNU make has so much implicit rules which are checked everytime make processes a Makefile - that's mainly for historical reasons. There're build systems (e.g. Ninja) which don't have such a long development history and thus have less stuff within.
Upvotes: 6