Regole di inferenza

Le regole di inferenza in NMAKE forniscono comandi per aggiornare le destinazioni e per dedurre dipendenti per le destinazioni. Le estensioni in una regola di inferenza corrispondono a una singola destinazione e dipendenti con lo stesso nome di base. Le regole di inferenza sono definite dall'utente o predefinite; è possibile ridefinire le regole predefinite.

Se una dipendenza non aggiornata non ha comandi e se .SUFFIXES contiene l'estensione dipendente, NMAKE usa una regola le cui estensioni corrispondono alla destinazione e a un file esistente nella directory corrente o specificata. Se più regole corrispondono a file esistenti, l'elenco .SUFFIXES determina quale usare; la priorità dell'elenco scende da sinistra a destra. Se un file dipendente non esiste e non è elencato come destinazione in un altro blocco di descrizione, una regola di inferenza può creare il dipendente mancante da un altro file con lo stesso nome di base. Se la destinazione di un blocco di descrizione non ha dipendenze o comandi, una regola di inferenza può aggiornare la destinazione. Le regole di inferenza possono compilare una destinazione della riga di comando anche se non esiste alcun blocco di descrizione. NMAKE può richiamare una regola per un dipendente dedotto anche se viene specificato un dipendente esplicito.

Definizione di una regola

Il from_ext rappresenta l'estensione di un file dipendente e to_ext rappresenta l'estensione di un file di destinazione.

.from_ext.to_ext:
   commands

Le estensioni non fanno distinzione tra maiuscole e minuscole. Le macro possono essere richiamate per rappresentare from_ext e to_ext; le macro vengono espanse durante la pre-elaborazione. Il punto (.) che precede from_ext deve essere visualizzato all'inizio della riga. I due punti (:) sono preceduti da zero o più spazi o schede. Può essere seguito solo da spazi o tabulazioni, un punto e virgola (;) per specificare un comando, un segno di numero (#) per specificare un commento o un carattere di nuova riga. Non sono consentiti altri spazi. I comandi vengono specificati come nei blocchi di descrizione.

Percorsi di ricerca nelle regole

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

Una regola di inferenza si applica a una dipendenza solo se i percorsi specificati nella dipendenza corrispondono esattamente ai percorsi inference-rule. Specificare la directory dipendente in from_path e la directory della destinazione in to_path; non sono consentiti spazi. Specificare un solo percorso per ogni estensione. Un percorso in un'estensione richiede un percorso sull'altro. Per specificare la directory corrente, usare un punto (.) o parentesi graffe vuote ({ }). Le macro possono rappresentare from_path e to_path, che vengono richiamate durante la pre-elaborazione.

Esempio di percorsi di ricerca

{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) $<

Regole in modalità batch

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

Le regole di inferenza in modalità batch forniscono una sola chiamata della regola di inferenza quando I comandi N passano attraverso questa regola di inferenza. Senza regole di inferenza in modalità batch, è necessario che vengano richiamati I comandi N. N è il numero di dipendenti che attivano la regola di inferenza.

L'unica differenza sintattica rispetto alla regola di inferenza standard è che una regola di inferenza in modalità batch termina con due punti (::).

Nota

Lo strumento richiamato deve essere in grado di gestire più file. La regola di inferenza in modalità batch deve essere usata $< come macro per accedere ai file dipendenti.

Le regole di inferenza in modalità batch possono velocizzare il processo di compilazione. È più veloce fornire file al compilatore in modalità batch, perché il driver del compilatore viene richiamato una sola volta. Ad esempio, il compilatore C e C++ viene eseguito più velocemente quando si gestisce un set di file, perché può rimanere residente in memoria durante l'intero processo.

L'esempio seguente illustra come usare le regole di inferenza in modalità batch:

#
# 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 produce l'output seguente senza regole di inferenza in modalità batch:

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 produce il risultato seguente con le regole di inferenza in modalità batch:

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...

Regole predefinite

Le regole di inferenza predefinite usano macro di opzioni e comandi forniti da NMAKE.

Regola Comando Azione predefinita Regola batch Piattaforma
.asm.exe $(AS) $(AFLAGS) $< ml $< no x86
.asm.obj $(AS) $(AFLAGS) /c $< ml /c $< x86
.asm.exe $(AS) $(AFLAGS) $< ml64 $< no x64
.asm.obj $(AS) $(AFLAGS) /c $< ml64 /c $< x64
.c.exe $(CC) $(CFLAGS) $< cl $< no tutto
.c.obj $(CC) $(CFLAGS) /c $< cl /c $< tutto
.cc.exe $(CC) $(CFLAGS) $< cl $< no tutto
.cc.obj $(CC) $(CFLAGS) /c $< cl /c $< tutto
.cpp.exe $(CPP) $(CPPFLAGS) $< cl $< no tutto
.cpp.obj $(CPP) $(CPPFLAGS) /c $< cl /c $< tutto
.cxx.exe $(CXX) $(CXXFLAGS) $< cl $< no tutto
.cxx.obj $(CXX) $(CXXFLAGS) /c $< cl /c $< tutto
.rc.res $(RC) $(RFLAGS) /r $< rc /r $< no tutto

Dipendenti e regole dedotti

NMAKE presuppone un dipendente dedotto per una destinazione se esiste una regola di inferenza applicabile. Una regola si applica se:

  • to_ext corrisponde all'estensione della destinazione.

  • from_ext corrisponde all'estensione di un file con il nome di base della destinazione e presente nella directory corrente o specificata.

  • from_ext è in .SUFFIXES; nessun altro from_ext in una regola di corrispondenza ha una priorità più alta.SUFFIXES.

  • Nessun dipendente esplicito ha una priorità più alta .SUFFIXES .

I dipendenti dedotti possono causare effetti collaterali imprevisti. Se il blocco di descrizione della destinazione contiene comandi, NMAKE esegue tali comandi anziché i comandi nella regola.

Precedenza nelle regole di inferenza

Se una regola di inferenza viene definita più volte, NMAKE usa la definizione di precedenza più alta. L'elenco seguente mostra l'ordine di precedenza dal più alto al più basso:

  1. Regola di inferenza definita in un makefile; le definizioni successive hanno la precedenza.

  2. Una regola di inferenza definita in Tools.ini; le definizioni successive hanno la precedenza.

  3. Regola di inferenza predefinita.

Vedi anche

Riferimenti a NMAKE