1

Trying a Makefile rule like the following did not work (GNU Make 4.0):

foo:   [email protected] other.o

bar:   bar.o other.o

The file foo.c was compiled (to foo.o), but the link command was cc -o .o.

In contrast, bar was compiled and linked correctly as cc bar.o other.o -o bar.

Who can explain the difference (or the problem)?

1 Answer 1

4

This is addressed in the section on Automatic variables in the GNU Make manual:

It’s very important that you recognize the limited scope in which automatic variable values are available: they only have values within the recipe. In particular, you cannot use them anywhere within the target list of a rule; they have no value there and will expand to the empty string. Also, they cannot be accessed directly within the prerequisite list of a rule. A common mistake is attempting to use $@ within the prerequisites list; this will not work.

The rest of the paragraph gives one possible solution, albeit a GNU Make-specific one: secondary expansion. Writing your Makefile as

.SECONDEXPANSION:

foo:   [email protected] other.o

bar:   bar.o other.o

allows $$@ to be given the appropriate value, and then

$ make foo
cc    -c -o foo.o foo.c
cc    -c -o other.o other.c
cc   foo.o other.o   -o foo

does what you’re hoping it to do.

(In my experience, there are usually better ways of addressing a problem than resorting to secondary expansion, but that can only be determined by understanding the overall goal of what you’re trying to do.)

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .