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


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


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.)


You must log in to answer this question.

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