10.8 Sequence of NMAKE Operations

When you are writing a complex description file, it can be helpful to know the sequence in which NMAKE performs operations. This section describes those operations and their order.

Summary: NMAKE first looks for a description file.

When you run NMAKE from the command line, NMAKE's first task is to find the description file:

1.If the /F option is used, NMAKE searches for the filename specified in the option. If NMAKE cannot find that file, it returns an error.

2.If the /F option is not used, NMAKE looks for a file named MAKEFILE in the current directory. If there are targets on the command line, NMAKE builds them according to the instructions in MAKEFILE. If there are no targets on the command line, NMAKE builds only the first target it finds in MAKEFILE.

3.If NMAKE cannot find MAKEFILE, NMAKE looks for target files on the command line and attempts to build them using inference rules (either defined by the user in TOOLS.INI or predefined by NMAKE). If no target is specified, NMAKE returns an error.

Summary: Macro definitions follow a priority.

NMAKE then assigns macro definitions with the following precedence (highest first):

1.Macros defined on the command line

2.Macros defined in a description file or include file

3.Inherited macros

4.Macros defined in the TOOLS.INI file

5.Predefined macros (such as CC and RFLAGS)

Macro definitions are assigned in order of priority, not in the order in which NMAKE encounters them. For example, a macro defined in an include file overrides a macro with the same name from the TOOLS.INI file. Note that a macro within a description file can be redefined; the most recent definition in the description file is used.

Summary: Inference rules also follow a priority.

NMAKE also assigns inference rules, using the following precedence (highest first):

1.Inference rules defined in a description file or include file

2.Inference rules defined in the TOOLS.INI file

3.Predefined inference rules (such as .c.obj)

You can use command-line options to change some of these precedences.

The /E option allows macros inherited from the environment to override macros defined in the description file.

The /R option tells NMAKE to ignore macros and inference rules that are defined in TOOLS.INI or are predefined.

Summary: NMAKE preprocesses directives before running the description-file commands.

Next, NMAKE evaluates any preprocessing directives. If an expression for conditional preprocessing contains a program in square brackets ([]), the program is invoked during preprocessing, and the program's exit code is used in the expression. If an !INCLUDE directive is specified for a file, NMAKE preprocesses the included file before continuing to preprocess the rest of the description file. Preprocessing determines the final description file that NMAKE reads.

Summary: NMAKE updates targets in the description file.

NMAKE is now ready to update the targets. If you specified targets on the command line, NMAKE updates only those targets. If you did not specify targets on the command line, NMAKE updates just the first target it finds in the description file. (This behavior differs from the MAKE utility's default; see Section 10.10, “Differences between NMAKE and MAKE.”) If you specify a pseudotarget, NMAKE always updates the target. If you use the /A option, NMAKE always updates the target, even if the file is not out-of-date.

If the dependents of the targets are themselves out-of-date or do not exist yet, NMAKE updates them first. If the target has no explicit dependent, NMAKE looks in the current directory for one or more files with the same base name as the target and whose extensions are in the .SUFFIXES list. (See Section 10.3.6, “Directives,” for a description of the .SUFFIXES list.) If it finds such files, NMAKE treats them as dependents and updates the target according to the commands.

Summary: Errors usually stop the build.

NMAKE normally stops processing the description file when a command returns a nonzero exit code. In addition, if NMAKE cannot tell whether the target was built successfully, it deletes the target. If you use the /I command-line option, NMAKE ignores error codes and attempts to continue processing. The .IGNORE directive has the same effect as the /I option. To prevent NMAKE from deleting the partially created target if you interrupt the build with CTRL+C or CTRL+BREAK, specify the target name in the .PRECIOUS directive.

Alternatively, you can use the dash () command modifier to ignore the error code for an individual command. An optional number after the dash tells NMAKE to continue if the command returns an exit code that is less than or equal to the number, and to stop if the exit code is greater than the number.

You can document errors by using the !ERROR directive to print descriptive text. The directive causes NMAKE to print some text, then stop, even if you use /I, .IGNORE, or the dash () modifier.