So I’m learning about makefiles, however the $< and $? are really confusing me. Speaking of which, $@ also confuses me.
What if there are multiple targets, then what does $@ refer to, the first one? And what if you want to refer to the second target, are you just screwed?
With $<, my teacher told me it refers to the current prerequisite. However, he had an example in his slide as follows:
.SUFFIXES: .c .o .cxx
.c.o:;$(CC) $(CFLAGS) -c $<
.cxx.o:; $(CXX) $(CXXFLAGS) -c $<
This doesn’t make any sense to me. How the hell can $< refer to anything if there are no dependencies? In lines 2 and 3 there aren’t any dependencies.
As far as $? goes, I heard it was the newer prerequisite list, and this is just total jargon to me.
Thanks for any help guys, I’ve tried google for the past hour but it’s all in the same terse UNIX speech that is somewhat hard for me to understand.
EDIT: I should add, I’m confused by the notation in lines 2 and 3. In the beginning of each line, what does it mean to have each suffix(.c.o and .cxx.o respectively) crammed together like that without any spaces?
First, realize that make is NOT running a program. A make file is a set of inference rules.
You tell make how to turn one thing into another, then give it a goal. It then combines your inference rules together to figure out the steps, and along the way checks timestamps on the files to make sure it doesn’t repeat unneeded work.
SUFFIXES tells make what suffixes should be recognized on files.
The rules that list two suffixes: .c.o indicate a rule to take a SINGLE file with a .c suffix and turn it into a SINGLE FILE with a .o suffix.
builds x.o. So,
says “take whatever source file is in $<, and turn it into a .o file using this command”
Then you can make a rule like this:
and if you have three c file (x.c, y.c, and z.c) in the current directory, make will be able to infer that when you want to make mycmd, it needs the .o files, and it knows it can make .o from .c, so it will.
The special variable definitions are here: http://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
So, when you type (at the command line):
make looks through the list of rules and sees: OH, to make that, I need x.o, y.o, and z.o
Then it goes to the disk. Say it finds x.c, x.o, y.c, and z.c. Now it thinks:
I have x.o…but .o files are made from .c files…I should check to see if the source has changed. It checks the timestamps, and if the .c file is newer than the .o file, it rebuilds it.
For the y.c and z.c, it knows it can use cc to turn those into .o files.
Assuming x.o is newer than x.c, make will:
if you then run make again, it does the same steps, but this time finds that myprog is newer than all of the .o files, which are all newer than the .c files…so it does nothing.
Now, say you edit x.c and run the make again: It will go through the whole sequence of checks again, find the x.c is newer than x.o, so it will rebuild it, and then it will notice that mycmd is now older than x.o, so it will re-link it.
So, for a very short set of rules, you get quite a lot of work done for you.