Reputation: 69
I wrote this Makefile:
.PHONY: all clean test
all: my_grep
clean:
-rm my_grep *.o
test:
~/grep_tests/beta.sh
my_grep: main.o line.o input.o
gcc -o my_grep main.o line.o input.o
main.o: main.c input.h line.h
line.o: line.c line.h
input.o: input.c input.h
When writing the following command in the terminal:
make line.o
I get this message:
cc -c -o line.o line.c
How come the Makefile knows what to do? There are no instructions written after the line:
line.o: line.c line.h
so I expected nothing to happen. Any explanation?
Upvotes: 2
Views: 936
Reputation: 180058
make
automatically provides a set of rules that are always available, even when there is no Makefile at all. The POSIX specifications for make
call them "default rules", and the GNU make
documentation calls them "built-in rules". These are suffix rules or substantially equivalent pattern rules that match targets to prerequisites and designate build recipes based on filename suffixes, and are therefore appropriate to many cases.
Additionally, you need to appreciate that a make
rule without a recipe does not express that there isn't any recipe for the target anywhere. Rather, such a "prerequisite-only" rule specifies a non-exclusive prerequisite list for the target, without speaking to a recipe for building the target. This allows one to use multiple rules to specify prerequisites for a target, provided that no more than one explicit rule defines a recipe for the target. In particular, it allows one to define additional prerequisites for targets whose recipes are provided by default / built-in rules.
Among the default rules of GNU make
and substantially every POSIX-conforming make
implementation is one for building .o
files from corresponding .c
files, and that rule is the one that provides the recipe in this case. GNU provides a pattern rule equivalent to this for the purpose:
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
That differs slightly from the POSIX specification, which omits $(CPPFLAGS)
from its default rule for this purpose, though that doesn't matter for the purposes of the question posed.
Upvotes: 1