For example in
$(CC) $(CFLAGS) -c -o $@ $<
what do they mean?
The $@ and $< are called automatic variables. The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.
Inside actions we can use: $@ to represent the full target name of the current target $? returns the dependencies that are newer than the current target $* returns the text that corresponds to % in the target $< returns the name of the first dependency $^ returns the names of all the dependencies with space as the ...
This special significance of ' $ ' is why you must write ' $$ ' to have the effect of a single dollar sign in a file name or recipe. Variable references can be used in any context: targets, prerequisites, recipes, most directives, and new variable values.
?= indicates to set the KDIR variable only if it's not set/doesn't have a value. For example: KDIR ?= "foo" KDIR ?= "bar" test: echo $(KDIR) Would print "foo"
$@ The file name of the target.
$< The name of the first dependency.
For more details: Makefile symbol reference
$@
is the name of the target being built - the program or object file being created.
$<
is the name of the file that caused it to be rebuilt is the name of the file 'whose existence allowed the inference rule to be chose for the target'.
In the example, you might have:
program.o: program.c
${CC} ${CFLAGS} -c -o $@ $<
In this case, $@
is 'program.o' and $<
is 'program.c'. (The rule must be generating an object file because of the '-c
' option.)
Beware '$<'; if there was a header that was more recent than the program, '$<' would match that instead - and then the compile line wouldn't work. As shown, it is safe enough, though.
Beta comments about '$<'...
The POSIX definition of 'make' says:
$<
In an inference rule, the $< macro shall evaluate to the filename whose existence allowed the inference rule to be chosen for the target. In the .DEFAULT rule, the $< macro shall evaluate to the current target name. The meaning of the $< macro shall be otherwise unspecified.
For example, in the .c.a inference rule, $< represents the prerequisite .c file.
So, in the example I gave, '$<' is technically 'unspecified'. And, in the correct context, which would be:
.c.o:
${CC} ${CFLAGS} -c -o $@ $<
Then '$<' is unconditionally 'progname.c' when 'progname.o' is being built.
Some versions of 'make' used to do weird things with it; both GNU Make (3.81) and Solaris 10 make seem to behave sanely. I'm caught in a time-warp, I suspect. I used the following makefile:
all: x.o
x.o: x.c
${CC} ${CFLAGS} -c -o $@ $<
x.o: x.h
I used 'echo "int main(){return 0;}" > x.c
' and 'echo > x.h
' to create the code. It didn't matter which file was touched out of 'x.c' and 'x.h'; either way, the compilation was 'correct'. I have an old make-derivative which was, circa 1992, compatible with Sun MAKE of the time in most respects, that mishandles it.
The 7th Edition UNIX Programmer's Manual says:
The rule to create a file with suffix s2 that depends on a similarly named file with suffix s1 is specified as an entry for the ‘target’ s1s2. In such an entry, the special macro $* stands for the target name with suffix deleted, $@ for the full target name, $< for the complete list of prerequisites, and $? for the list of prerequisites that are out of date.
It doesn't say anything about what it means outside that context. I note that 7th Edition 'make' would list both 'x.c' and 'x.h' for '$<' - but POSIX says that is incorrect.
The SUN "make User's Guide" (Revision A of 16 March 1987) says:
$<
The name of the dependency file, as if selected bymake
for use with an implicit rule.
That more or less conforms to what you now see.
Oh well, such is life; things change around you. Sometimes you spot it happening; sometimes you don't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With