Automatic variables are an advance feature you may use inside your rules. These variables expand to very specific values regarding data available on rule’s header.
$@ | $(@D) | $(@F) | Target's name |
$< | $(<D) | $(<F) | First prerequisites |
$^ | $(^D) | $(^F) | All prerequisites without duplicates |
$* | $(*D) | $(*F) | Implicit rule stem |
Note D and F variations of the variable are actually splitting every word in Directory and File parts:
$ cat Makefile
/tmp/file:
@echo "The directory is $(@D)"
@echo "The file is $(@F)"
$ make
The directory is /tmp
The file is file
Let’s see the those in action with a complete example. Imagine you want to build a C program which needs one source file and at least 2 header files. $ tree
.
├── header1.h
├── header2.h
└── program.c
So to build the program you need to generate a couple of implicit rules (You may use the built-in rules but you are stubborn and a DIY guy) so: $ cat Makefile
headers:= header1.h header2.h
program: program.o
$(CC) $(CFLAGS) -o $@ $<
program.o: program.c $(headers)
$(CC) -c $(CFLAGS) -o $@ $<
$ make program
cc -c -o program.o program.c
cc -o program program.o
This example is a little more complex so I’m going to take a closer look to every part of the line. – We decided to store all header file names in a variable so we can use it later. This is an easy task. headers:= header1.h header2.h
– Now we define our first target: program which has a prerequisite on it’s object. program: program.o
$(CC) $(CFLAGS) -o $@ $<;
Here we used 2 automatic variables. And the expansion of the recipe looks like: cc -o program program.o
As you can see the automatic variables has done their work pretty well!
– Last we can see the rule for making the object file and it’s output fits what was described.
program.o: program.c $(headers)
$(CC) -c $(CFLAGS) -o $@ $<
cc -c -o program.o program.c
Make is mixing that information together an executing the proper commands in the proper order. But for a better explanation about how rules works see the section dedicated to rules.