This is a static pattern rule. The first field is a list of targets, the second is a target pattern which Make uses to isolate a target's "stem", the third is the prerequisite pattern which Make uses to construct the list of prerequisites.
Suppose you have
SRCDIR = src
OBJDIR = obj
OBJECTS = obj/foo.o obj/bar.o obj/baz.o
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o $@
If you make obj/foo.o
, Make first identifies this rule as the one to use (since obj/foo.o
is in the target list $(OBJECTS)
), matches it against the target pattern obj/%.o
and finds that the stem (the part matched by the wildcard %
) is foo
, then plugs that into the prereq pattern src/%.c
and finds that the prerequisite is src/foo.c
.
If you've also defined the variables
CC = gcc
CFLAGS = -thisflag -thatflag=something
Then the command in the rule becomes
@gcc -thisflag -thatflag=something -c src/foo.c -o obj/foo.o
(Note that $<
is the first prerequisite and $@
is the target name.)
In answer to your other question: Yes, a makefile can handle a dependency on a header file (x.h
) so that if the header has been modified, Make will rebuild the target. No, this makefile doesn't do that. You can modify the makefile by hand, adding rules like
a.o: x.h
assuming you know what the inclusions actually are, or you can have the makefile do it automatically, which is an advanced technique you probably shouldn't attempt yet.