Rückschlussregeln
Inference-Regeln in NMAKE liefern Befehle zum Aktualisieren von Zielen und zum Ableiten von Nachfolgern für Ziele. Erweiterungen in einer Ableitungsregel entsprechen einem einzelnen Ziel und abhängigen Zielen, die denselben Basisnamen aufweisen. Rückschlussregeln sind benutzerdefinierte oder vordefinierte; vordefinierte Regeln können neu definiert werden.
Wenn eine veraltete Abhängigkeit keine Befehle aufweist und wenn .SUFFIXES
sie die Erweiterung des Abhängigen enthält, verwendet NMAKE eine Regel, deren Erweiterungen mit dem Ziel und einer vorhandenen Datei im aktuellen oder angegebenen Verzeichnis übereinstimmen. Wenn mehr als eine Regel mit vorhandenen Dateien übereinstimmt, bestimmt die .SUFFIXES
Liste, welche verwendet werden soll. Die Listenpriorität ist von links nach rechts absteigend. Wenn eine abhängige Datei nicht vorhanden ist und nicht als Ziel in einem anderen Beschreibungsblock aufgeführt ist, kann eine Rückschlussregel die fehlende abhängige Datei aus einer anderen Datei erstellen, die denselben Basisnamen aufweist. Wenn das Ziel eines Beschreibungsblocks keine Abhängigen oder Befehle aufweist, kann eine Ableitungsregel das Ziel aktualisieren. Ableitungsregeln können ein Befehlszeilenziel erstellen, auch wenn kein Beschreibungsblock vorhanden ist. NMAKE kann eine Regel für eine abgeleitete abhängige Funktion aufrufen, auch wenn eine explizite abhängige Angabe erfolgt.
Definieren einer Regel
Die from_ext stellt die Erweiterung einer abhängigen Datei dar, und to_ext stellt die Erweiterung einer Zieldatei dar.
.from_ext.to_ext:
commands
Bei Erweiterungen wird die Groß-/Kleinschreibung nicht beachtet. Makros können aufgerufen werden, um from_ext und to_ext darzustellen. Die Makros werden während der Vorverarbeitung erweitert. Der Punkt (.
) vor from_ext muss am Anfang der Zeile angezeigt werden. Dem Doppelpunkt (:
) wird null oder mehr Leerzeichen oder Tabstopps vorangestellt. Es kann nur von Leerzeichen oder Tabstopps gefolgt werden, einem Semikolon (;
) zum Angeben eines Befehls, eines Nummernzeichens (#
) zum Angeben eines Kommentars oder eines Zeilenumbruchzeichens. Es sind keine anderen Leerzeichen zulässig. Befehle werden wie in Beschreibungsblöcken angegeben.
Suchpfade in Regeln
{from_path}.from_ext{to_path}.to_ext:
commands
Eine Ableitungsregel gilt nur dann für eine Abhängigkeit, wenn pfade, die in der Abhängigkeit angegeben sind, genau mit den Ableitungsregelpfaden übereinstimmen. Geben Sie das Verzeichnis des Abhängigen in from_path und das Verzeichnis des Ziels in to_path an. Es sind keine Leerzeichen zulässig. Geben Sie für jede Erweiterung nur einen Pfad an. Ein Pfad für eine Erweiterung erfordert einen Pfad auf dem anderen. Verwenden Sie zum Angeben des aktuellen Verzeichnisses entweder einen Punkt (.
) oder leere geschweifte Klammern ({ }
). Makros können from_path und to_path darstellen. Sie werden während der Vorverarbeitung aufgerufen.
Beispiel für Suchpfade
{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) $<
Stapelverarbeitungsregeln
{from_path}.from_ext{to_path}.to_ext::
commands
Batchmodus-Ableitungsregeln stellen nur einen Aufruf der Ableitungsregel bereit, wenn N-Befehle diese Rückschlussregel durchlaufen. Ohne Batchmodus-Ableitungsregeln müssten N-Befehle aufgerufen werden. N ist die Anzahl der Abhängigen, die die Ableitungsregel auslösen.
Der einzige syntaktische Unterschied zur Standard-Ableitungsregel besteht darin, dass eine Ableitungsregel im Batchmodus mit einem Doppelpunkt (::
) endet.
Hinweis
Das aufgerufene Tool muss mehrere Dateien verarbeiten können. Die Batchmodus-Ableitungsregel muss als Makro für den Zugriff auf abhängige Dateien verwendet werden $<
.
Die Batchmodus-Ableitungsregeln können den Buildprozess beschleunigen. Es ist schneller, Dateien im Batchmodus an den Compiler zu übermitteln, da der Compilertreiber nur einmal aufgerufen wird. Beispielsweise wird der C- und C++-Compiler bei der Verarbeitung einer Reihe von Dateien schneller ausgeführt, da er während des gesamten Prozesses speicherresidiert bleiben kann.
Das folgende Beispiel zeigt die Verwendung von Batchmodus-Ableitungsregeln:
#
# 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 erzeugt die folgende Ausgabe ohne Batchmodus-Ableitungsregeln:
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 erzeugt das folgende Ergebnis mit den Batchmodus-Ableitungsregeln:
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...
Vordefinierte Regeln
Von vordefinierten Rückschlussregeln werden Befehls- und Optionenmakros von NMAKE verwendet.
Regel | Get-Help | Standardaktion | Batchregel | Plattform |
---|---|---|---|---|
.asm.exe |
$(AS) $(AFLAGS) $< |
ml $< |
Nein | x86 |
.asm.obj |
$(AS) $(AFLAGS) /c $< |
ml /c $< |
ja | x86 |
.asm.exe |
$(AS) $(AFLAGS) $< |
ml64 $< |
Nein | x64 |
.asm.obj |
$(AS) $(AFLAGS) /c $< |
ml64 /c $< |
ja | x64 |
.c.exe |
$(CC) $(CFLAGS) $< |
cl $< |
Nein | alle |
.c.obj |
$(CC) $(CFLAGS) /c $< |
cl /c $< |
ja | all |
.cc.exe |
$(CC) $(CFLAGS) $< |
cl $< |
Nein | alle |
.cc.obj |
$(CC) $(CFLAGS) /c $< |
cl /c $< |
ja | all |
.cpp.exe |
$(CPP) $(CPPFLAGS) $< |
cl $< |
Nein | alle |
.cpp.obj |
$(CPP) $(CPPFLAGS) /c $< |
cl /c $< |
ja | all |
.cxx.exe |
$(CXX) $(CXXFLAGS) $< |
cl $< |
Nein | alle |
.cxx.obj |
$(CXX) $(CXXFLAGS) /c $< |
cl /c $< |
ja | all |
.rc.res |
$(RC) $(RFLAGS) /r $< |
rc /r $< |
Nein | alle |
Hergeleitete abhängige Dateien und Regeln
NMAKE geht von einem abgeleiteten abhängigen Ziel aus, wenn eine entsprechende Ableitungsregel vorhanden ist. Eine Regel gilt, wenn:
to_ext entspricht der Erweiterung des Ziels.
from_ext entspricht der Erweiterung einer Datei, die den Basisnamen des Ziels aufweist und im aktuellen oder angegebenen Verzeichnis vorhanden ist.
from_ext befindet sich in
.SUFFIXES
; keine andere from_ext in einer übereinstimmenden Regel hat eine höhere.SUFFIXES
Priorität.Kein explizit abhängiger Benutzer hat eine höhere
.SUFFIXES
Priorität.
Abgeleitete Nachfolger können unerwartete Nebenwirkungen verursachen. Wenn der Beschreibungsblock des Ziels Befehle enthält, führt NMAKE diese Befehle anstelle der Befehle in der Regel aus.
Vorrang in Rückschlussregeln
Wenn eine Rückschlussregel mehrmals definiert ist, verwendet NMAKE die Definition der höchsten Rangfolge. In der folgenden Liste wird die Reihenfolge der Rangfolge von der höchsten zur niedrigsten Liste angezeigt:
Eine Inferenzregel, die in einer Makefile definiert ist; spätere Definitionen haben Vorrang.
Eine in ; spätere Definitionen definierte
Tools.ini
Ableitungsregel haben Vorrang.Eine vordefinierte Ableitungsregel.