18.11 A Sample NMAKE Makefile

The following example illustrates many of NMAKE's features. The makefile creates an executable file from C-language source files:

# This makefile builds SAMPLE.EXE from SAMPLE.C,

# ONE.C, and TWO.C, then deletes intermediate files.

CFLAGS = /c /AL /Od $(CODEVIEW) # controls compiler options

LFLAGS = /CO # controls linker options

CODEVIEW = /Zi # controls debugging information

OBJS = sample.obj one.obj two.obj

all : sample.exe

sample.exe : $(OBJS)

link $(LFLAGS) @<<sample.lrf

$(OBJS: =+^

)

sample.exe

sample.map;

<<KEEP

sample.obj : sample.c sample.h common.h

CL $(CFLAGS) sample.c

one.obj : one.c one.h common.h

CL $(CFLAGS) one.c

two.obj : two.c two.h common.h

CL $(CFLAGS) two.c

clean :

-del *.obj

-del *.map

-del *.lrf

Assume that this makefile is named SAMPLE.MAK. To invoke it, enter

NMAKE /F SAMPLE.MAK all clean

NMAKE builds SAMPLE.EXE and deletes intermediate files.

Here is how the makefile works. The CFLAGS, CODEVIEW, and LFLAGS macros define the default options for the compiler, linker, and inclusion of debugging information. You can redefine these options from the command line to alter or delete them. For example,

NMAKE /F SAMPLE.MAK CODEVIEW= CFLAGS= all clean

creates an .EXE file that does not contain debugging information.

The OBJS macro specifies the object files that make up the executable file SAMPLE.EXE, so they can be reused without having to type them again. Their names are separated by exactly one space so that the space can be replaced with a plus sign (+) and a carriage return in the link response file. (This is illustrated in the second example in “Substitution Within Macros”.)

The all pseudotarget points to the real target, sample.exe. If you do not specify any target on the command line, NMAKE ignores the clean pseudotarget but still builds all because all is the first target in the makefile.

The dependency line containing the target sample.exe makes the object files specified in OBJS the dependents of sample.exe. The command section of the block contains only link instructions. No compilation instructions are given since they are given explicitly later in the file. (You can also define an inference rule to specify how an object file is to be created from a C source file.)

The link command is unusual because the LINK parameters and options are not passed directly to LINK. Rather, an inline response file is created containing these elements. This eliminates the need to maintain a separate link response file.

The next three dependencies define the relationship of the source code to the object files. The .H (header or include) files are also dependents since any changes to them also require recompilation.

The clean pseudotarget deletes unneeded files after a build. The dash () command modifier tells NMAKE to ignore errors returned by the deletion commands. If you want to save any of these files, don't specify clean on the command line; NMAKE then ignores the clean pseudotarget.