10.3.7 Preprocessing Directives

NMAKE preprocessing directives are similar to compiler preprocessing directives. You can use the !IF, !IFDEF, !IFNDEF, !ELSE, and !ENDIF directives to conditionally process the description file. With other preprocessing directives you can display error messages, include other files, undefine a macro, and turn certain options on or off. NMAKE reads and executes the preprocessing directives before processing the description file as a whole.

Preprocessing directives (listed in Table 10.8) begin with an exclamation point (!), which must appear at the beginning of the line. You can place spaces between the exclamation point and the directive keyword. These directives are not case sensitive.

Table 10.8 Preprocessing Directives

Directive Description
!CMDSWITCHES {+|}opt... Turns on or off NMAKE options /D, /I, /N, and /S. (See Section 10.4, “Command-Line Options.”) Do not specify the slash (/). If !CMDSWITCHES is specified with no options, all options are reset to the values they had when NMAKE was started. This directive updates the MAKEFLAGS macro. Turn an option on by preceding it with a plus sign (+), or turn it off by preceding it with a minus sign ().
!ERROR text Prints text, then stops execution.
!IF constantexpression Reads the statements between the !IF keyword and the next !ELSE or !ENDIF keyword if constantexpression evaluates to a nonzero value.
!IFDEF macroname Reads the statements between the !IFDEF keyword and the next !ELSE or !ENDIF keyword if macroname is defined. NMAKE considers a macro with a null value to be defined.
!IFNDEF macroname Reads the statements between the !IFNDEF keyword and the next !ELSE or !ENDIF keyword if macroname is not defined.
!ELSE Reads the statements between the !ELSE and !ENDIF keywords if the preceding !IF, !IFDEF, or !IFNDEF statement evaluated to zero. Anything following !ELSE on the same line is ignored.
!ENDIF Marks the end of an !IF, !IFDEF, or !IFNDEF block. Anything following !ENDIF on the same line is ignored.
!INCLUDE filename Reads and evaluates the description file filename before continuing with the current description file. If filename is enclosed by angle brackets (<>), NMAKE searches for the file first in the current directory and then in the directories specified by the INCLUDE macro. Otherwise, it looks only in the current directory. The INCLUDE macro is initially set to the value of the INCLUDE environment variable.
!UNDEF macroname Marks macroname as undefined in NMAKE's symbol table.

10.3.7.1 Expressions in Preprocessing

The constantexpression used with the !IF directive can consist of integer constants, string constants, or program invocations. Integer constants can use the unary operators for numerical negation (), one's complement (~), and logical negation (!). They can also use any binary operator listed in Table 10.9.

Table 10.9 Preprocessing-Directive Binary Operators

Operator Description
+ Addition
Subtraction
* Multiplication
/ Division
% Modulus
& Bitwise AND
| Bitwise OR
^ Bitwise XOR
&& Logical AND
|| Logical OR
<< Left shift
>> Right shift
== Equality
!= Inequality
< Less than
> Greater than
<= Less than or equal to
>= Greater than or equal to

You can group expressions by enclosing them in parentheses. NMAKE treats numbers as decimal unless they start with 0 (octal) or 0x (hexadecimal). Use the equality (==) operator to compare two strings for equality, or the inequality (!=) operator to compare for inequality. Enclose strings in double quotation marks.

Example

The following example shows how preprocessing directives can be used to control whether the linker inserts CodeView information into the .EXE file:

!INCLUDE <infrules.txt>

!CMDSWITCHES +D

winner.exe : winner.obj

!IFDEF debug

! IF "$(debug)"=="y"

LINK /CO winner.obj;

! ELSE

LINK winner.obj;

! ENDIF

!ELSE

! ERROR Macro named debug is not defined.

!ENDIF

In this example, the !INCLUDE directive inserts the INFRULES.TXT file into the description file. The !CMDSWITCHES directive sets the /D option, which displays the times of the files as they are checked. The !IFDEF directive checks to see if the macro debug is defined. If it is defined, the !IF directive checks to see if it is set to y. If it is, NMAKE reads the LINK command with the /CO option; otherwise, NMAKE reads the LINK command without /CO. If the debug macro is not defined, the !ERROR directive prints the specified message and NMAKE stops.

10.3.7.2 Executing a Program in Preprocessing

Summary: NMAKE can invoke programs and check their status.

You can invoke any program from within NMAKE by placing the program's name or path name within square brackets ([]). The program is executed during preprocessing, and its exit code replaces the program specification in the description file. A nonzero exit code usually indicates an error. You can use this value to control execution, as in the following example:

!IF [c:\util\checkdsk] != 0

! ERROR Not enough disk space; NMAKE terminating.

!ENDIF