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.
Conclusion
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' (http://www.gnu.org/software/make/manual/make.html#Target_002dspecific) and 'Pattern-specific Variable Values' (http://www.gnu.org/software/make/manual/make.html#Pattern_002dspecific).
No comments:
Post a Comment