make, the percent sign is used for pattern matching, and it requires one in the target as well as (at least) one in the prerequisites:
$(CC) $(CFLAGS) -c -o $@ $<
With this makefile, we specify that in order to build something whose file name ends with
.o, you need to have a file that has the same prefix, but then ends with
.c rather than
In order to be able to construct those rules, you obviously need to be able to refer to the target as well as the prerequisites; this is where the
$< variables come in.
$@ means 'the target of this rule', and
$< means 'this rule's first listed prerequisite'. If you need to construct a command that uses all prerequisites (e.g., to link an executable), then you can use the variable
%: %.o lib.o
$(CC) $(LDFLAGS) -o $@ $^
If you combine the above two example makefile snippets in one makefile, and you have a file 'lib.c' with some common code that you want to use in a number of C programs in that same directory, then you can add any random
.c file, say
foo.c, and compile it into a program
foo that also links in the code in
lib.c, without requiring any changes to your makefile.
Note that it is also possible to have patterns with the same target, as long as the prerequisites are different; e.g., the following will work:
that is, it will work as expected as long as you don't have any C++ source files in this directory that happen to have the same name (sans extension) as a C source file. If that does happen to be the case, the C++ version will be ignored and the C source will be compiled instead (because the C rule is listed first in the makefile)
For more info, see the relevant section in the GNU make manual.