推斷規則
NMAKE 中的推斷規則會提供命令來更新目標,以及推斷目標的相依專案。 推斷規則中的延伸模組會比對具有相同基底名稱的單一目標與相依性。 推斷規則是使用者定義的或預先定義的;預先定義的規則可以重新定義。
如果過期的相依性沒有命令,而且如果 .SUFFIXES
包含相依的延伸模組,NMAKE 會使用符合目標的規則,以及目前或指定目錄中的現有檔案。 如果一個以上的規則符合現有的檔案,清單會 .SUFFIXES
決定要使用哪一個;清單優先順序會從左到右遞減。 如果相依檔案不存在且未列在另一個描述區塊中作為目標,推斷規則可以從具有相同基底名稱的另一個檔案建立遺漏的相依性。 如果描述區塊的目標沒有相依專案或命令,推斷規則可以更新目標。 即使沒有任何描述區塊存在,推斷規則仍可建置命令行目標。 NMAKE 可能會叫用推斷相依性的規則,即使已指定明確相依性也一樣。
定義規則
from_ext代表相依檔案的擴展名,to_ext代表目標檔案的擴展名。
.from_ext.to_ext:
commands
擴充功能不區分大小寫。 您可以叫用巨集來表示 from_ext 和 to_ext;巨集會在前置處理期間展開。 from_ext之前的句點 (.
) 必須出現在行的開頭。 冒號 (:
) 前面有零個或多個空格或索引標籤。 後面只能加上空格或索引標籤、分號 (;
) 來指定命令、數位元號 (#
) 以指定批註或換行符號。 不允許其他空格。 命令會在描述區塊中指定為 。
在規則中搜尋路徑
{from_path}.from_ext{to_path}.to_ext:
commands
只有在相依性中指定的路徑完全符合推斷規則路徑時,推斷規則才會套用至相依性。 在 from_path 中指定相依的目錄,並在 to_path 中指定目標目錄;不允許空格。 為每個延伸模組只指定一個路徑。 某個延伸模組上的路徑需要另一個延伸模組的路徑。 若要指定目前目錄,請使用句號 (.
) 或空白大括弧 ({ }
)。 巨集可以代表 from_path 和 to_path;它們會在前置處理期間叫用。
搜尋路徑的範例
{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) $<
批次模式規則
{from_path}.from_ext{to_path}.to_ext::
commands
當 N 命令通過這個推斷規則時,批次模式推斷規則只會提供推斷規則的一個叫用。 如果沒有批次模式推斷規則,則需要叫用 N 個命令。 N 是觸發推斷規則的相依項目數目。
標準推斷規則的唯一語法差異是批次模式推斷規則結尾為雙冒號 (::
)。
注意
叫用的工具必須能夠處理多個檔案。 批次模式推斷規則必須使用 $<
做為巨集來存取相依檔案。
批次模式推斷規則可以加速建置程式。 以批次模式將檔案提供給編譯程式的速度較快,因為只會叫用編譯程式驅動程式一次。 例如,C 和 C++ 編譯程式在處理一組檔案時執行得更快,因為它可以在整個程式期間保持記憶體常駐。
下列範例示範如何使用批次模式推斷規則:
#
# 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 會產生下列沒有批次模式推斷規則的輸出:
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 會使用批次模式推斷規則產生下列結果:
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...
預先定義的規則
預先定義的推斷規則會使用 NMAKE 提供的命令和選項巨集。
規則 | Command | 默認動作 | 批次規則 | 平台 |
---|---|---|---|---|
.asm.exe |
$(AS) $(AFLAGS) $< |
ml $< |
否 | x86 |
.asm.obj |
$(AS) $(AFLAGS) /c $< |
ml /c $< |
是 | x86 |
.asm.exe |
$(AS) $(AFLAGS) $< |
ml64 $< |
否 | x64 |
.asm.obj |
$(AS) $(AFLAGS) /c $< |
ml64 /c $< |
是 | x64 |
.c.exe |
$(CC) $(CFLAGS) $< |
cl $< |
否 | 全部 |
.c.obj |
$(CC) $(CFLAGS) /c $< |
cl /c $< |
是 | 全部 |
.cc.exe |
$(CC) $(CFLAGS) $< |
cl $< |
否 | 全部 |
.cc.obj |
$(CC) $(CFLAGS) /c $< |
cl /c $< |
是 | 全部 |
.cpp.exe |
$(CPP) $(CPPFLAGS) $< |
cl $< |
否 | 全部 |
.cpp.obj |
$(CPP) $(CPPFLAGS) /c $< |
cl /c $< |
是 | 全部 |
.cxx.exe |
$(CXX) $(CXXFLAGS) $< |
cl $< |
否 | 全部 |
.cxx.obj |
$(CXX) $(CXXFLAGS) /c $< |
cl /c $< |
是 | 全部 |
.rc.res |
$(RC) $(RFLAGS) /r $< |
rc /r $< |
否 | 全部 |
推斷相依和規則
如果適用的推斷規則存在,NMAKE 會假設目標的推斷相依性。 如果下列專案適用規則:
to_ext符合目標的擴充功能。
from_ext符合具有目標基底名稱且存在於目前或指定目錄中之檔案的擴展名。
from_ext位於 中
.SUFFIXES
;比對規則中沒有其他from_ext優先順序較高.SUFFIXES
。沒有明確的相依性具有較高的
.SUFFIXES
優先順序。
推斷的相依專案可能會導致非預期的副作用。 如果目標的描述區塊包含命令,NMAKE 會執行這些命令,而不是規則中的命令。
推斷規則的優先順序
如果多次定義推斷規則,NMAKE 會使用最高優先順序的定義。 下列清單顯示優先順序從最高到最低:
makefile 中定義的推斷規則;較新的定義具有優先順序。
中
Tools.ini
定義的推斷規則;稍後的定義具有優先順序。預先定義的推斷規則。