开发者

What are $@ and $< in a Makefile? [duplicate]

开发者 https://www.devze.com 2022-12-23 16:14 出处:网络
This question already has answers here: 开发者_C百科What do $< and $@ represent in a Makefile?
This question already has answers here: 开发者_C百科What do $< and $@ represent in a Makefile? (2 answers) Closed 7 years ago.

For example in

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

what do they mean?


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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号