NMAKE provides several special macros to represent various filenames and commands. One use for these macros is in the predefined inference rules. (For more information, see “Predefined Inference Rules”.) Like user-defined macro names, special macro names are case sensitive. For example, NMAKE interprets CC and cc as different macro names.
The following sections describe the four categories of special macros. The file-name macros offer a convenient representation of filenames from a dependency line. The recursion macros allow you to call NMAKE from within your makefile. The command macros and options macros make it convenient for you to invoke the Microsoft language compilers.
Summary: Filename macros conveniently represent filenames from the dependency line.
NMAKE provides macros that are predefined to represent filenames. The filenames are as you have specified them in the dependency line and not the full specification of the filenames as they exist on disk. As with all one-character macros, these do not need to be enclosed in parentheses. (The $$@ and $** macros are exceptions to the parentheses rule for macros; they do not require parentheses even though they contain two characters.)
$@
The current target's full name (path, base name, and extension), as currently specified.
$$@
The current target's full name (path, base name, and extension), as currently specified. This macro is valid only for specifying a dependent in a dependency line.
$*
The current target's path and base name minus the file extension.
$**
All dependents of the current target.
$?
All dependents that have a later time stamp than the current target.
$<
The dependent file that has a later time stamp than the current target. You can use this macro only in commands in inference rules.
Example 1
The following example uses the $? macro, which represents all dependents that have changed more recently than the target. The ! command modifier causes NMAKE to execute a command once for each dependent in the list. As a result, the LIB command is executed up to three times, each time replacing a module with a newer version.
trig.lib : sin.obj cos.obj arctan.obj
!LIB trig.lib -+$?;
Example 2
In the next example, NMAKE updates a file in another directory by replacing it with a file of the same name from the current directory. The $@ macro is used to represent the current target's full name.
# File in objects directory depends on version in current directory
DIR = c:\objects
$(DIR)\a.obj : a.obj
COPY a.obj $@
Modifying Filename Macros
Summary: Macro modifiers specify parts of the predefined filename macros.
You can append one of the modifiers in the following table to any of the filename macros to extract part of a filename. If you add one of these modifiers to the macro, you must enclose the macro name and the modifier in parentheses.
Modifier | Resulting Filename Part |
D | Drive plus directory |
B | Base name |
F | Base name plus extension |
R | Drive plus directory plus base name |
Example 1
Assume that $@ represents the target C:\SOURCE\PROG\SORT.OBJ. The following table shows the effect of combining each modifier with $@:
Macro Reference | Value |
$(@D) | C:\SOURCE\PROG |
$(@F) | SORT.OBJ |
$(@B) | SORT |
$(@R) | C:\SOURCE\PROG\SORT |
If $@ has the value SORT.OBJ without a preceding directory, the value of $(@R) is SORT, and the value of $(@D) is a period (.) to represent the current directory.
Example 2
The following example uses the F modifier to specify a file of the same name in the current directory:
# Files in objects directory depend on versions in current directory
DIR = c:\objects
$(DIR)\a.obj $(DIR)\b.obj $(DIR)\c.obj : $$(@F)
COPY $(@F) $@
Note:
For another way to represent components of a filename, see “Filename-Parts Syntax”.
Summary: Recursion macros let you use NMAKE to call NMAKE.
There are three macros that you can use when you want to call NMAKE recursively from within a makefile. These macros can make recursion more efficient.
MAKE
Defined as the name which you specified to the operating system when you ran NMAKE; this name is NMAKE unless you have renamed the utility file. Use this macro to call NMAKE recursively. The /N command-line option to prevent execution of commands does not prevent this command from executing. It is recommended that you do not redefine MAKE.
MAKEDIR
Defined as the current directory when NMAKE was called.
MAKEFLAGS
Defined as the NMAKE options currently in effect. This macro is passed automatically when you call NMAKE recursively. However, specification of this macro when invoking recursion is harmless; thus, you can use older makefiles that specify this macro. You cannot redefine MAKEFLAGS. To change the /D, /I, /N, and /S options within a makefile, use the preprocessing directive !CMDSWITCHES. (See “Preprocessing Directives”.) To add other options to the ones already in effect for NMAKE when recursing, specify them as part of the recursion command.
Calling NMAKE Recursively
In a commands block, you can specify a call to NMAKE itself. Either invoke the MAKE macro or specify NMAKE literally. When you call NMAKE recursively by macro rather than by literally specifying the command NMAKE, NMAKE does not run a new copy of itself. Instead, it uses its own stack for the recursive parts of the build. This saves space in memory.
The following NMAKE information is available to the called NMAKE session during recursion:
Environment-variable macros (see “Inherited Macros”). To cause all macros to be inherited, specify the /V option.
The MAKEFLAGS macro. If .IGNORE (or !CMDSWITCHES +I) is set, MAKEFLAGS contains an I when it is passed to the recursive call. Likewise, if .SILENT (or !CMDSWITCHES +S) is set, MAKEFLAGS contains an S when passed to the call.
Macros specified on the command line for the recursive call.
All information in TOOLS.INI.
Inference rules defined in the makefile are not passed to the called NMAKE session. Settings for .SUFFIXES and .PRECIOUS are also not inherited. However, you can make .SUFFIXES, .PRECIOUS, and all inference rules available to the recursive call either by specifying them in TOOLS.INI or by placing them in a file that is specified in an !INCLUDE directive in the makefile for each NMAKE session.
Example
The MAKE macro is useful for building different versions of a program. The following makefile calls NMAKE recursively to build targets in the \VERS1 and \VERS2 directories.
all : vers1 vers2
vers1 :
cd \vers1
$(MAKE)
cd ..
vers2 :
cd \vers2
$(MAKE) /F vers2.mak
cd ..
If the dependency containing vers1 as a target is executed, NMAKE performs the commands to change to the \VERS1 directory and call itself recursively using the MAKEFILE in that directory. If the dependency containing vers2 as a target is executed, NMAKE changes to the \VERS2 directory and calls itself using the file VERS2.MAK in that directory.
Note:
Deeply recursive builds can exhaust NMAKE's run-time stack, causing an error. If this occurs, use the EXEHDR utility to increase NMAKE's stack. See Chapter 17, “Using EXEHDR.”
Summary: Command macros are shortcut calls to Microsoft compilers.
NMAKE predefines several macros to represent commands for Microsoft prod-ucts. You can use these macros as commands in either a description block or an inference rule; they are automatically used in NMAKE's predefined inference rules. (See “Inference Rules”.) You can redefine these macros to represent part or all of a command line, including options.
AS
Defined as ml, the command to run the Microsoft Macro Assembler
BC
Defined as bc, the command to run the Microsoft Basic Compiler
CC
Defined as cl, the command to run the Microsoft C Compiler
COBOL
Defined as cobol, the command to run the Microsoft COBOL Compiler
CPP
Defined as cl, the command to run the Microsoft C++ Compiler
CXX
Defined as cl, the command to run the Microsoft C++ Compiler
FOR
Defined as fl, the command to run the Microsoft FORTRAN Compiler
PASCAL
Defined as pl, the command to run the Microsoft Pascal Compiler
RC
Defined as rc, the command to run the Microsoft Resource Compiler
Summary: Options macros pass preset options to Microsoft compilers.
The following macros represent options to be passed to the commands for invoking the Microsoft language compilers. These macros are used automatically in the predefined inference rules. (See “Predefined Inference Rules”.) By default, these macros are undefined. You can define them to mean the options you want to pass to the compilers, and you can use these macros in commands in description blocks and inference rules. As with all macros, the options macros can be used even if they are undefined; a macro that is undefined or defined to be a null string generates a null string where it is used.
AFLAGS
Passes options to the Microsoft Macro Assembler
BFLAGS
Passes options to the Microsoft Basic Compiler
CFLAGS
Passes options to the Microsoft C Compiler
COBFLAGS
Passes options to the Microsoft COBOL Compiler
CPPFLAGS
Passes options to the Microsoft C++ Compiler
CXXFLAGS
Passes options to the Microsoft C++ Compiler
FFLAGS
Passes options to the Microsoft FORTRAN Compiler
PFLAGS
Passes options to the Microsoft Pascal Compiler
RFLAGS
Passes options to the Microsoft Resource Compiler