Trendingat

02Home & Garden · Updated

What Does $@ Mean in a Makefile?

Short answer

$@ expands to the current target name

In a Makefile recipe, $@ is an automatic variable that expands to the name of the target currently being built. It lets one recipe work with different target names without repeating them.

MeaningCurrent target’s filenameExplained in: How automatic variables work
Related variable$< names the first prerequisiteExplained in: How automatic variables work
Reading time5 min8 sections, about 1,250 words

What $@ means in a Makefile

Make is a build tool: it reads rules from a file, commonly named Makefile, and runs commands to create or update specified targets. A target is often a file, such as an executable or an object file, though it can also be a named task that does not produce a file.

Within a recipe—the indented command lines belonging to a rule—$@ stands for the rule’s target. For example:

program: main.o helper.o
	cc -o $@ main.o helper.o

When Make runs this recipe, it substitutes program for $@, so the command becomes cc -o program main.o helper.o. The variable is especially useful when a pattern rule or a set of similar rules builds several outputs using the same command structure.

The characters are literal syntax: dollar sign followed by an at sign. This is not an environment variable, shell variable, or special filename. It is Make’s own automatic variable, whose value depends on the rule being processed.

How automatic variables work

Automatic variables give a recipe information about the current rule. Make determines their values when it runs a recipe, rather than treating them as ordinary variables set earlier in the file. Their scope is tied to the rule whose recipe is running.

A rule usually has this general shape:

target: prerequisite prerequisite ...
	command

The target is what the rule builds or updates; prerequisites are inputs that the target depends on. Make checks those inputs and decides whether the recipe needs to run. When it does, automatic variables can insert the relevant target or prerequisite names into the command.

Here are common automatic variables:

  • $@: the target name.
  • $<: the first prerequisite, commonly the source file in a pattern rule.
  • $^: all prerequisites, with duplicate names removed.
  • $+: all prerequisites, retaining duplicates and their order.
  • $?: prerequisites that are newer than the target.

These shorthand variables can make rules easier to reuse, but they do not replace understanding what each rule’s target and inputs are. If a command needs a particular ordering or a subset of prerequisites, choose the variable that expresses that requirement.

Examples of $@ in rules

In a simple explicit rule, $@ saves little typing, but it still shows the variable’s meaning:

notes.txt: notes.in
	cp $< $@

For this rule, the first prerequisite is notes.in and the target is notes.txt. The recipe therefore runs cp notes.in notes.txt. Here $< supplies the input and $@ supplies the output.

Its benefit is clearer in a pattern rule, which describes how to build files matching a pattern:

%.o: %.c
	$(CC) -c $< -o $@

If Make uses this rule to build parser.o from parser.c, then $@ becomes parser.o and $< becomes parser.c. The same recipe can build other matching object files without writing a separate command for each one.

A target can also be a label rather than a file:

.PHONY: clean
clean:
	rm -f program *.o

This is a conventional cleanup target. A phony target represents an action and is not expected to correspond to a file named clean. Although $@ in this recipe would expand to clean, it is not necessarily useful in the cleanup command. Automatic variables provide values; they do not decide whether those values belong in a particular command.

When to use it—and when not to

Use $@ when the command needs the target name and repeating that name would make a rule less reusable or more prone to mismatches. It is common in compile, link, copy, and code-generation recipes where the output path is determined by the rule.

  • Use it for an output argument: tool -o $@ $< directs a command to write the current target.
  • Pair it with inputs: use $<, $^, or another appropriate variable for prerequisite names.
  • Keep fixed names explicit when clearer: a one-off command may be easier to understand with a literal filename.
  • Check unusual target types: grouped targets, pattern rules, and special rules can have details that differ from a basic one-target rule.

Make’s syntax and the recipe shell’s syntax are separate layers. Make processes automatic variables before it passes a command to the shell. For example, shell syntax such as $HOME is not the same thing as Make’s $@. To pass a dollar sign through Make so the shell can interpret it, Makefiles commonly use $$; the precise command still depends on the shell and recipe.

Common mistakes and misconceptions

A frequent error is using $@ where the source file is needed. In the rule %.o: %.c, $@ is the object-file target, while $< is the corresponding C source prerequisite. Swapping them can make a command read its output as though it were an input.

Another mistake is expecting $@ to work everywhere in a Makefile. It is most meaningful in a recipe. At the top level, outside a rule’s recipe, there may be no current target for it to name. Likewise, automatic variables generally are not expanded in prerequisite lists in the same straightforward way they are in recipes; Make has special mechanisms for cases that require deferred prerequisite expansion.

Do not confuse $@ with $(@). The latter is not the standard spelling of this automatic variable. Also, in a shell recipe, an at sign by itself has no connection to Make’s target variable; the dollar sign is essential.

Finally, remember that Make expands the variable based on the rule being executed. A recipe shared through features such as implicit or pattern rules can therefore receive different target names on different runs. That is the point of the shorthand, but it also means the rule must be designed so every matching target is valid for the command.

Frequently Asked Questions

What does $@ stand for in Make?

It is an automatic variable that expands to the target name for the rule whose recipe Make is running.

What is the difference between $@ and $<?

$@ names the target, while $< names the first prerequisite. In a common pattern rule, that means output file versus source file.

Can I use $@ in a pattern rule?

Yes. In a pattern rule such as %.o: %.c, it expands to the particular target being built, such as parser.o.

Why is $@ empty or not working?

Check that it appears in a recipe where Make is processing a rule, and verify that the command is being run by Make rather than entered directly in a shell. Also check that you have typed the dollar sign and at sign exactly.

Does $@ mean the same thing in a shell script?

No. In Make, $@ is the current target. Shells have their own variable conventions, and Make processes recipe text before the shell receives it.

Background and further reading

Automatic variables are part of GNU Make’s rule and recipe syntax, and related make implementations may document compatible behavior or differences. When a Makefile relies on a less common rule type, consult the documentation for the specific Make implementation in use. For everyday recipes, remembering that $@ is the current target—and distinguishing it from prerequisite variables—is the key.

Further reading: GNU Make. Details can change, so check the official page for anything that matters to you. Spotted a mistake? Tell us. How we write an answer.