The following examples illustrate several ways to write inference rules.
Example 1
The following makefile contains an inference rule and a minimal description block:
.c.obj:
cl /c $<
sample.obj :
The inference rule tells NMAKE how to build a .OBJ file from a .C file. The predefined macro $< represents the name of a dependent that has a later time stamp than the target. The description block lists only a target, SAMPLE.OBJ; there is no dependent or command. However, given the target's base name and extension, plus the inference rule, NMAKE has enough information to build the target.
After checking to be sure that .c is one of the extensions in the .SUFFIXES list, NMAKE looks for a file with the same base name as the target and with the .C extension. If SAMPLE.C exists (and no files with higher-priority extensions exist), NMAKE compares its time to that of SAMPLE.OBJ. If SAMPLE.C has changed more recently, NMAKE compiles it using the CL command listed in the inference rule:
cl /c sample.c
Example 2
The following inference rule compares a .C file in the current directory with the corresponding .OBJ file in another directory:
{.}.c{c:\objects}.obj:
cl /c $<;
The path for the .C file is represented by a period. A path for the dependent extension is required because one is specified for the target extension.
This inference rule matches a dependency line containing the same combination of paths, such as:
c:\objects\test.obj : test.c
This rule does not match a dependency line such as:
test.obj : test.c
In this case, NMAKE uses the predefined inference rule for .c.obj when building the target.
Example 3
The following inference rule uses macros to specify paths in an inference rule:
C_DIR = proj1src
OBJ_DIR = proj1obj
{$(C_DIR)}.c{$(OBJ_DIR)}.obj:
cl /c $
If the macros are redefined, NMAKE uses the definition that is current at that point during preprocessing. To reuse an inference rule with different macro definitions, you must repeat the rule after the new definition:
C_DIR = proj1src
OBJ_DIR = proj1obj
{$(C_DIR)}.c{$(OBJ_DIR)}.obj:
cl /c $<
C_DIR = proj2src
OBJ_DIR = proj2obj
{$(C_DIR)}.c{$(OBJ_DIR)}.obj:
cl /c $<