Programming Utilities Guide

Makefile for a Program with Separate Variants

The following example shows a makefile for a C program with separately maintained variants. First, the .INIT special target creates the debug_dir and profile_dir subdirectories (if they do not already exist), which will contain the debugging and profiling object files and executables.


Note -

make performs the rule in the .INIT target just after the makefile is read.


The variant executables are made to depend on the object files listed in the VARIANTS.o macro. This macro is given the value of OBJECTS by default; later on it is reassigned using a conditional macro definition, at which time either the debug_dir/ or profile_dir/ prefix is added. Executables in the subdirectories depend on the object files that are built in those same subdirectories.

Next, pattern-matching rules are added to indicate that the object files in both subdirectories depend upon source (.c) files in the working directory. This is the key step needed to allow all three variants to be built and maintained from a single set of source files.

Finally, the clean target has been updated to recursively remove the debug_dir and profile_dir subdirectories and their contents, which should be regarded as temporary. This is in keeping with the custom that derived files are to be built in the same directory as their sources, since the subdirectories for the variants are considered temporary.

Table 4-13 Sample Makefile for Separate Debugging and Profiling Program Variants
# Simple makefile for maintaining separate
# debugging and profiling program variants.  

CFLAGS= -O 

SOURCES= main.c rest.c 
OBJECTS= $(SOURCES:%.c=$(VARIANT)/%.o) 
VARIANT= .

functions profile debug: $$(OBJECTS) 
 $(LINK.c) -o $(VARIANT)/$@ $(OBJECTS) 

debug := VARIANT = debug_dir
debug := CFLAGS = -g 
profile := VARIANT = profile_dir
profile := CFLAGS = -O -pg 

.KEEP_STATE:
.INIT:  profile_dir debug_dir
profile_dir debug_dir:
 test -d $@ || mkdir $@ 
 $$(VARIANT)/%.o: %.c 
 $(COMPILE.c) $< -o $@ 
clean:  
 rm -r profile_dir debug_dir $(OBJECTS) functions