Skip to content

Latest commit

 

History

History
184 lines (129 loc) · 7.93 KB

inference-rules.md

File metadata and controls

184 lines (129 loc) · 7.93 KB
titledescriptionms.datehelpviewer_keywords
Inference rules
Learn more about: NMAKE inference rules
09/30/2021
inference rules in NMAKE
rules, inference
NMAKE program, inference rules
search paths in NMAKE inference rules
defining inference rules
batch-mode inference rules in NMAKE
rules, predefined
NMAKE program, predefined rules
predefined rules in NMAKE
rules, inferred
inferred dependents in NMAKE
inferred rules in NMAKE
dependents, inferred
precedence, inference rule

Inference rules

Inference rules in NMAKE supply commands to update targets and to infer dependents for targets. Extensions in an inference rule match a single target and dependent that have the same base name. Inference rules are user-defined or predefined; predefined rules can be redefined.

If an out-of-date dependency has no commands, and if .SUFFIXES contains the dependent's extension, NMAKE uses a rule whose extensions match the target and an existing file in the current or specified directory. If more than one rule matches existing files, the .SUFFIXES list determines which to use; list priority descends from left to right. If a dependent file doesn't exist and isn't listed as a target in another description block, an inference rule can create the missing dependent from another file that has the same base name. If a description block's target has no dependents or commands, an inference rule can update the target. Inference rules can build a command-line target even if no description block exists. NMAKE may invoke a rule for an inferred dependent even if an explicit dependent is specified.

Defining a rule

The from_ext represents the extension of a dependent file, and to_ext represents the extension of a target file.

.from_ext.to_ext: commands

Extensions aren't case-sensitive. Macros can be invoked to represent from_ext and to_ext; the macros are expanded during preprocessing. The period (.) that precedes from_ext must appear at the beginning of the line. The colon (:) is preceded by zero or more spaces or tabs. It can be followed only by spaces or tabs, a semicolon (;) to specify a command, a number sign (#) to specify a comment, or a newline character. No other spaces are allowed. Commands are specified as in description blocks.

Search paths in rules

{from_path}.from_ext{to_path}.to_ext: commands

An inference rule applies to a dependency only if paths specified in the dependency exactly match the inference-rule paths. Specify the dependent's directory in from_path and the target's directory in to_path; no spaces are allowed. Specify only one path for each extension. A path on one extension requires a path on the other. To specify the current directory, use either a period (.) or empty braces ({ }). Macros can represent from_path and to_path; they are invoked during preprocessing.

Example of search paths

{dbi\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $(YUDBI) $< {ilstore\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $< {misc\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $(YUPDB) $< {misc\}.c{$(ODIR)}.obj:: $(CC) $(CFLAGS) $< {msf\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $< {bsc\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $(YUPDB) $< {mre\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $(YUPDB) $< {namesrvr\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $(YUPDB) $< {src\cvr\}.cpp{$(ODIR)}.obj:: $(CC) $(CFLAGS) $<

Batch-mode rules

{from_path}.from_ext{to_path}.to_ext:: commands

Batch-mode inference rules provide only one invocation of the inference rule when N commands go through this inference rule. Without batch-mode inference rules, it would require N commands to be invoked. N is the number of dependents that trigger the inference rule.

The only syntactical difference from the standard inference rule is that a batch-mode inference rule ends with a double colon (::).

Note

The tool being invoked must be able to handle multiple files. The batch-mode inference rule must use $< as the macro to access dependent files.

The batch-mode inference rules can speed up the build process. It's faster to supply files to the compiler in batch mode, because the compiler driver is invoked only once. For example, the C and C++ compiler runs faster when handling a set of files, because it can remain memory resident during the entire process.

The following example shows how to use batch-mode inference rules:

## sample makefile to illustrate batch-mode inference rules#O = . S = . Objs = $O/foo1.obj $O/foo2.obj $O/foo2.obj $O/foo3.obj $O/foo4.obj CFLAGS = -nologo all : $(Objs) !ifdef NOBatch {$S}.cpp{$O}.obj: !else {$S}.cpp{$O}.obj:: !endif $(CC) $(CFLAGS) -Fd$O\ -c $< $(Objs) : #end of makefile

NMAKE produces the following output without batch-mode inference rules:

E:\tmp> nmake -f test.mak -a NOBatch=1 Microsoft (R) Program Maintenance Utility Version 7.00.0000 Copyright (C) Microsoft Corp 1988-2001. All rights reserved. cl -nologo -Fd.\ -c .\foo1.cpp foo1.cpp cl -nologo -Fd.\ -c .\foo2.cpp foo2.cpp cl -nologo -Fd.\ -c .\foo3.cpp foo3.cpp cl -nologo -Fd.\ -c .\foo4.cpp foo4.cpp

NMAKE produces the following result with the batch-mode inference rules:

E:\tmp> nmake -f test.mak -a Microsoft (R) Program Maintenance Utility Version 7.00.0000 Copyright (C) Microsoft Corp 1988-2001. All rights reserved. cl -nologo -Fd.\ -c .\foo1.cpp .\foo2.cpp .\foo3.cpp .\foo4.cpp foo1.cpp foo2.cpp foo3.cpp foo4.cpp Generating Code...

Predefined rules

Predefined inference rules use NMAKE-supplied command and options macros.

RuleCommandDefault actionBatch rulePlatform
.asm.exe$(AS) $(AFLAGS) $<ml $<nox86
.asm.obj$(AS) $(AFLAGS) /c $<ml /c $<yesx86
.asm.exe$(AS) $(AFLAGS) $<ml64 $<nox64
.asm.obj$(AS) $(AFLAGS) /c $<ml64 /c $<yesx64
.c.exe$(CC) $(CFLAGS) $<cl $<noall
.c.obj$(CC) $(CFLAGS) /c $<cl /c $<yesall
.cc.exe$(CC) $(CFLAGS) $<cl $<noall
.cc.obj$(CC) $(CFLAGS) /c $<cl /c $<yesall
.cpp.exe$(CPP) $(CPPFLAGS) $<cl $<noall
.cpp.obj$(CPP) $(CPPFLAGS) /c $<cl /c $<yesall
.cxx.exe$(CXX) $(CXXFLAGS) $<cl $<noall
.cxx.obj$(CXX) $(CXXFLAGS) /c $<cl /c $<yesall
.rc.res$(RC) $(RFLAGS) /r $<rc /r $<noall

Inferred dependents and rules

NMAKE assumes an inferred dependent for a target if an applicable inference rule exists. A rule applies if:

  • to_ext matches the target's extension.

  • from_ext matches the extension of a file that has the target's base name and that exists in the current or specified directory.

  • from_ext is in .SUFFIXES; no other from_ext in a matching rule has a higher .SUFFIXES priority.

  • No explicit dependent has a higher .SUFFIXES priority.

Inferred dependents can cause unexpected side effects. If the target's description block contains commands, NMAKE executes those commands instead of the commands in the rule.

Precedence in inference rules

If an inference rule is defined more than once, NMAKE uses the highest-precedence definition. The following list shows the order of precedence from highest to lowest:

  1. An inference rule defined in a makefile; later definitions have precedence.

  2. An inference rule defined in Tools.ini; later definitions have precedence.

  3. A predefined inference rule.

See also

NMAKE reference

close