Jonathan
Jonathan

Reputation: 69

makefile default behaviour, no command

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

Answers (1)

John Bollinger
John Bollinger

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

Related Questions