tags:

views:

92

answers:

3

For example in

$(CC) $(CFLAGS) -c -o $@ $<

what do they mean?

+2  A: 
$@  The file name of the target. 

$<  The name of the first dependency. 

For more details: Makefile symbol reference

codaddict
A: 

From here:

$@ is a macro for the name of the file to be made.

$< is a macro for the name of the related file that caused the action (the first dependency).

Matt Ball
This is not correct, $< is the first dependency in the list, not necessarily one that caused the action.
Beta
Then my (admittedly sketchy-looking) reference is wrong.
Matt Ball
+2  A: 

$@ 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 by make 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.

Jonathan Leffler
This is not correct, $< is the first dependency in the list, not necessarily the one that caused the target to be rebuilt.
Beta
P.S. $? is the list of prerequisites newer than the target (or PHONY), so these are the ones that will cause this target to be remade.
Beta
@Beta: OK - I've fixed things up, I think, with some historical commentary.
Jonathan Leffler
I confess I'd never heard of the POSIX make specs, but experiments (like yours with x.c and x.h) show what's really going on.
Beta