Target-specific and Pattern-specific GNU Make macros


VAR is $(VAR)


[email protected] In $@ VAR is $(VAR)

bar: VAR = local scope

bar: baz

[email protected] In $@ VAR is $(VAR)


[email protected] In $@ VAR is $(VAR)

f%: VAR = starts with f

Now if you run make you get the following output:

In foo VAR is starts with f

In baz VAR is local scope

In bar VAR is local scope

In all VAR is global scope

This is the same as above except that in the rule for foo the value of VAR has been set to starts with f by the pattern-specific definition.

It's worth noting that this is unrelated to normal GNU Make pattern rules.  The pattern-specific macro definition can be used to change the value of a macro in a normal rule (as above).  It can also be used with a pattern rule.

For example, you could change the value of DEBUG to 1 within all %.o files (that could be built using the standard %.o: %.c pattern rule) by writing:

%.o: DEBUG = 1

A practical example

It's not uncommon in a project to have a standard rule for compiling files (perhaps even using the built-in GNU Make rule) and to need to have a slightly different version of that rule for a specific file, or set of files, that otherwise use the same command.

For example, here's a Makefile that builds all the C files in two subdirectories (lib1 and lib2) using a pattern rule.

lib1_SRCS := $(wildcard lib1/*.c)

lib2_SRCS := $(wildcard lib2/*.c)

lib1_OBJS := $(lib1_SRCS:.c=.o)

lib2_OBJS := $(lib2_SRCS:.c=.o)

.PHONY: all

all: $(lib1_OBJS) $(lib2_OBJS)

%.o: %.c

   @$(COMPILE.C) -o $@ $<

First the Makefile gets the list of all C files in lib1 in the variable lib1_SRCS and the C files in lib2 in lib2_SRCS and then it converts those to a list of object files to build using a substitution reference to change .c to .o creating lib1_OBJS and lib2_OBJS.

The pattern rule uses the GNU Make built-in variable COMPILE.C to run a compiler that compiles a .c into a .o.   The Makefile knows to build all the objects in lib1_OBJS and lib2_OBJS because they are prerequisites of all.

This works fine if all the .c files have the same compilation options.

Now suppose that the C file lib1/special.c requires the -Wcomment option to prevent the compiler from warning about an oddly written comment.   Obviously is would be possible to change the value of CPPFLAGS globally by adding

CPPFLAGS += -Wcomment

in the Makefile.  But that change affects every compilation and is probably undesirable.

Luckily, a target-specific variable can be used to just alter the value of CPPFLAGS for that single file.  By writing

lib1/special.o: CPPFLAGS += -Wcomment

the value of CPPFLAGS will be altered just for the creation of lib1/special.o.

Now suppose that an entire subdirectory requires a special CPPFLAGS option to maximize optimization for speed (the -fast option to gcc, for example).

Here a pattern-specific macro definition is ideal.  Adding

lib1/%.o: CPPFLAGS += -fast

does the trick.  Any .o files that are built in lib1/ will have the -fast command-line option.


Target-specific and pattern-specific macros are worth reading about because they are a very handy feature of GNU Make when a small change is needed for a limited set of targets.

Further reading can be found in the GNU Make manual sections 'Target-specific Variable Values' ( and 'Pattern-specific Variable Values' (

And Robert Mecklenburg's 'Managing Projects with GNU Make' book contains an explanation of target-specific variables in Chapter 3 (

About the author

AgileConnection is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.