Makefile variables ($@, $< ...)

Ever wondered what the funny-looking vars in the GNU Makefiles are? These two are the most common ones:  $@ and @< there are some other are special vars as well.

Here’s what these two mean, and you can look up the rest on the GNU Makefile “Automatic Variables” help page:

$@     -is the name of the target currently being processed.

$<     -is the name of the first dependency.

1. So if you have a makefile target that looks like this:

all: clean libs app
    @echo 'Building target: $@. First dependency is: $<
    ...

Then when you invoke  ‘make all’  you will see the message:
 Building target: all. First dependency is: clean.'

2. It becomes more interesting when the first dependency is a list of several values, e.g.:

OBJS := lib1/src1.c lib1/src2.c lib2/src2.c lib2/src3.c
...
myapp: $(OBJS) $(USER_OBJS)

@echo 'Building target: $@. First dep: $<'
$(CC) $(USER_FLAGS) -o $@ $(OBJS) $(LIBS)
@echo 'Finished building target: $@'

In this case the first dependency which is the variable OBJS is evaluated. It resolves to a list of values and the first value ‘lib1/src1.c’ will be assigned to the ‘$<‘ variable.

So when making  ‘myapp’  you will see the message:

 Building target: myapp. First dependency is: lib1/src1.c.'

One more thing to look for, particularly if you are using echo messages to debug your make process:
Your first dependency may often be another target in the make file! In the first example (all: clean libs app) the dependencies are ‘clean’, ‘libs’ and ‘app’ and by the looks of it these are most likely other targets. Now, what I wanted point out is that if one of these targets prints a message… Then the sequence of the messages you see may not be what you expected!  Or worse yet – if one of these pre-requisite targets breaks the build (!) then you may never see your message! Just keep these in mind when debugging your makefiles…

3 thoughts on “Makefile variables ($@, $< ...)

  1. It’s easy to debug a makefile in the target sections, just add a echo somewhere within your target section :

      some-target:
            @echo Value of VAR1=$VAR1

    But sometimes you really need to check some value before your targets. What can you do? You can’t use echo in the definitions section…

    This will do the trick! 😉

      $(error VAR1 = $(VAR1).)

    It will do the job of printing the value of the variable from within your makefile’s definitions section… Of course it WILL also break the build… but I am assuming that if you’re at the stage of debugging environment variables in your makefiles then this is probably not be your major concern at this very moment… 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *