nmake リファレンス

nmake のリファレンスです。
Makefile の書き方を忘れたときに、すぐに参照出来るよう１ページにまとめました。

## nmake の特殊マクロ
|マクロ|説明|例|
|:--|:--|:--|
|$@|現在指定されている、現在のターゲットのフルネーム (パス、ベース名、拡張子)。|c:\temp\target.txt|
|$$@|現在指定されている、現在のターゲットのフルネーム (パス、ベース名、拡張子)。<br>依存関係の依存ファイルとしてだけ有効です。|c:\temp\target.txt|
|$*|現在のターゲットのパスとベース名。拡張子は含まれません。|c:\temp\target|
|$**|現在のターゲットのすべての依存ファイル。|
|$?|現在のターゲットよりタイムスタンプの新しいすべての依存ファイル。|
|$<|現在のターゲットよりタイムスタンプの新しい依存ファイル。 <br>推論規則のコマンドだけで有効です。|
既定のファイル名マクロの一部を指定するには，マクロ修飾子を追加し，修飾したマクロを括弧で囲みます。

|修飾子|結果として得られるファイル名部分|例 (c:\temp\target.txt)|
|:--|:--|:--|
|D|ドライブとディレクトリ|$(@D) -> C:\temp|
|B|基本名|$(@B) -> target|
|F|基本名と拡張子|$(@F) -> target.txt
|R|ドライブとディレクトリと基本名|$(@R) -> c:\temp\target|

## 再帰マクロ
|マクロ|定義|
|:--|:--|
|MAKE|NMAKE を呼び出すために最初に使用されたコマンド。<br>$(MAKE) マクロは nmake.exe への完全パスを提供します。|
|MAKEDIR|NMAKE が呼び出されたときの現在のディレクトリ。|
|MAKEFLAGS|現在有効なオプション。 <br>/$(MAKEFLAGS) のように使用します。<br>/F が含まれていないことに注意してください。|


## コマンド マクロとオプション マクロ
|Microsoft 製品|コマンド マクロ|定義|オプション マクロ|
|:--|:--|:--|:--|
|Macro Assembler|AS|ml|AFLAGS
|Basic Compiler|BC|bc|BFLAGS|
|C Compiler|CC|cl|CFLAGS|
|C++ Compiler|CPP|cl|CPPFLAGS|
|C++ Compiler|CXX|cl|CXXFLAGS|
|Resource Compiler|RC|rc|RFLAGS

## .mak ファイル内の特殊文字
nmake の特殊文字をリテラル文字として使用するには、特殊文字の前にキャレット (^) を挿入します。
特殊文字以外の文字の前に付けられているキャレットは無視されます。nmake の特殊文字は次のとおりです。

|特殊文字|名前|使用上の注意|
|:--|:--|:--|
|:|コロン||
|;|セミコロン||
|#|番号記号|コメントの先頭には番号記号 (#) を付けます。<br>番号記号と次の改行文字の間のテキストは無視されます。|
|(|始め丸かっこ|
|)|終わり丸かっこ|
|$|ドル記号|
|^|キャレット|引用符で囲まれた文字列内のカレットは、リテラルのカレット文字として扱われます。<br>また、行末にカレットを使用すると、文字列またはマクロにリテラルの改行文字が挿入されます。<br>次のコード例は、リテラルの番号記号を、直前にカレット (^) を付けて指定する方法を示しています。<br>`DEF = ^#define #C プリプロセス ディレクティブのマクロ`
|\|円記号|マクロでは、改行文字の前の円記号は、スペースに置き換えられます。|
|{|始め中かっこ|
|}|終わり中かっこ|
|!|感嘆符|
|@|アットマーク|
|-|ハイフン|
|%|パーセント記号|コマンドの場合、パーセント記号はファイル指定子です。<br>コマンド内でリテラルの % を示すには、パーセント記号を 1 つ入れるところに 2 つ (%%) 指定します。<br>コマンド以外の場合では、nmake は % をリテラルとして扱いますが、<br>2 つの %% は常に 1 つの % として解釈されます。<br>したがって、リテラルの %% を指定する場合は、パーセント記号を 3 つ (%%%) または 4 つ (%%%%) 指定します。|
|$|ドル記号|コマンドでリテラルの $ を指定するには、ドル記号を 2 つ ($$) 指定します。<br>コマンド以外の場合でも、^$ の代わりに $$ を使用できます。|
|*|アスタリスク|ファイル名のワイルドカードです。<br>依存関係行にあるファイル名のワイルドカードは、nmake によって展開されます。<br>コマンド内に指定されたワイルドカードは、コマンドに渡され、nmake による展開は行われません。|
|" "|二重引用符|長いファイル名を使用する場合は、二重引用符 (" ") で囲みます。<br>次のコード例では、長いファイル名が使用されています。<br>`All : "VeryLongFileName.exe"`|


## 記述ブロック
```
targets... : dependents...
    commands...
```
依存関係行では、1 つ以上のターゲットと 0 個以上の依存ファイルを指定します。
ターゲットは、行の先頭で指定する必要があります。 ターゲットと依存ファイルはコロン (:) で区切ります。
依存関係行では空白やタブを使用できます。 行を分割するには、ターゲットまたは依存ファイルの後に円記号 (\\) を使用します。
ターゲットが存在しない場合、ターゲットのタイムスタンプが依存ファイルのタイムスタンプより古い場合、
またはターゲットが疑似ターゲットである場合、NMAKE はコマンドを実行します。
依存ファイルがほかの依存関係行ではターゲットである場合、その依存ファイルが存在しないか、
またはそれ自身の依存ファイルと比べて古いと、現在の依存関係の更新前に依存ファイルが更新されます。

## 規則の定義
```
.fromext.toext:
   commands
```
拡張子では、大文字と小文字が区別されません。
fromext および toext を表すために、マクロを呼び出すことができます。マクロは、プリプロセス時に展開されます。
fromext の前のピリオド (.) は、行の先頭に配置する必要があります。
コロン (:) の前には、0 個以上の空白またはタブを配置します。
コロンの後に続けられるのは、空白またはタブ、コマンドを指定するためのセミコロン (;)、
コメントを指定するためのシャープ記号 (#)、あるいは改行文字だけです。
ほかの空白を入れることはできません。コマンドは、記述ブロックでの場合と同じように指定します。

## 規則の検索パス
```
{frompath}.fromext{topath}.toext:
   commands
```
依存関係で指定されたパスが推論規則のパスと正確に一致する場合だけ、推論規則が依存関係に適用されます。
依存ファイルのディレクトリは frompath で指定し、ターゲットのディレクトリは topath で指定します。
空白を入れることはできません。 パスは、拡張子ごとに 1 つだけ指定します。
一方の拡張子でパスを指定した場合は、もう一方の拡張子でもパスを指定する必要があります。
現在のディレクトリを指定するには、ピリオド (.) または空の中かっこ ({ }) を使用します。
マクロでは、frompath と topath を表すことができます。マクロは、プリプロセス時に呼び出されます。

```Makefile:sample
{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) $<
```

## バッチモード規則
```
{frompath}.fromext{topath}.toext::
	commands
```
バッチモード推論規則では、N 個のコマンドで推論規則が利用されるときに、その推論規則が一度だけ呼び出されます。 
バッチモード推論規則を使用しない場合は、N 個のコマンドを呼び出す必要があります。 N は、推論規則を呼び出す依存ファイルの数です。
標準の推論規則との構文的な違いは、バッチモード推論規則が二重のコロン (::) で終わることだけです。

```Makefile:test.mak
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) :
```
バッチモード推論規則を使用しない場合、NMAKE の出力は次のようになります。

```dos:output
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 の結果は次のようになります。

```dos:output
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...
```

## ドット ディレクティブ
ドット ディレクティブは、記述ブロックの外側で、行の先頭に指定します。
ドット ディレクティブはピリオド ( .) で始まり、その後にコロン (:) が続きます。
空白とタブは使用できます。 ドット ディレクティブの名前には、大文字を使用します。

|ディレクティブ|目的|
|:--|:--|
|.IGNORE :|指定された位置からメイクファイルの最後まで、コマンドから返される 0 以外の終了コードを無視します。 既定では、コマンドで 0 以外の終了コードが返されると NMAKE は中断します。 エラー チェックを元に戻すには、!CMDSWITCHES を使用します。 1 つのコマンドで終了コードを無視するには、ダッシュ (–) 修飾子を使用します。 ファイル全体で終了コードを無視するには、/I を使用します。|
|.PRECIOUS : targets|targets を更新するコマンドが中止された場合に、targets をディスクに保存します。ファイルを削除することによりコマンドで割り込みが処理される場合は無効です。 複数のターゲット名は、空白またはタブで区切ります。 既定では、Ctrl キーを押しながら C キーまたは Break キーを押すことでビルドが中断された場合、ターゲットは削除されます。 .PRECIOUS は、使用されるたびにメイクファイル全体に適用され、指示内容が累積されます。|
|.SILENT :|指定された位置からメイクファイルの最後まで、実行されたコマンドを表示しません。 既定では、NMAKE が呼び出すコマンドが表示されます。 エコーを元に戻すには、!CMDSWITCHES を使用します。 1 つのコマンドでエコーを中止するには、@ 修飾子を使用します。 ファイル全体でエコーを中止するには、/S を使用します。
|.SUFFIXES : list|推論規則で使用する拡張子を列挙します。拡張子 .exe .obj .asm .c .cpp .cxx .bas .cbl .for .pas .res .rc .f .f90 が含まれるようにあらかじめ定義されています。|

.SUFFIXES リストの順序を変更するか、または新しいリストを指定するには、リストの内容をクリアし、新しい設定を指定します。 
リストの内容をクリアするには、次のようにコロンの後に拡張子がない状態にします。

```
.SUFFIXES :
```

リストにサフィックスを追加するには、次のように指定します。

```
.SUFFIXES : suffixlist
```
suffixlist は、追加するサフィックスのリストです。複数のサフィックスは、空白またはタブで区切ります。
.SUFFIXES の現在の設定を確認するには、/P を使用して NMAKE を実行します。

## メイクファイルのプリプロセス ディレクティブ

プリプロセス ディレクティブの表記では、大文字と小文字が区別されません。
先頭の感嘆符 (!) は、行の先頭で指定する必要があります。
感嘆符の後には、インデントのために 0 個以上の空白またはタブを配置できます。

|ディレクティブ|目的|
|:--|:--|
|!CMDSWITCHES|{+ &#124; –}option... リストにある各 option をオンまたはオフにします。 空白やタブは、+ 演算子または – 演算子の前に配置する必要があります。演算子とオプション文字の間には何も配置できません。 文字では大文字と小文字が区別されず、スラッシュ (/) なしで指定します。 一部のオプションをオンにし、残りのオプションをオフにするには、それぞれに !CMDSWITCHES を指定します。メイクファイルで使用できるのは、/D、/I、/N、および /S だけです。 Tools.ini では、/F、/HELP、/NOLOGO、/X、および /? を除くすべてのオプションを使用できます。 記述ブロックで指定された変更は、次の記述ブロックまで有効にはなりません。 このディレクティブでは、MAKEFLAGS が更新されます。MAKEFLAGS が指定されている場合は、変更が再帰時に継承されます。|
|!ERROR text|エラー U1050 で text を表示し、/K、/I、.IGNORE、!CMDSWITCHES、またはダッシュ (–) コマンド修飾子が使用されている場合でも、NMAKE を中断します。 text の前の空白やタブは無視されます。|
|!MESSAGE text|text を標準出力に表示します。 text の前の空白やタブは無視されます。|
|!INCLUDE[] <ファイル名>[]|filename をメイクファイルとして読み取り、現在のメイクファイルで処理を続けます。 NMAKE は、指定されたディレクトリまたは現在のディレクトリの、再帰的に親メイクファイルのディレクトリを通じて filename が 山かっこで囲まれている)、INCLUDE 環境変数< >に初期設定された INCLUDE マクロで指定されたディレクトリで囲まれている場合は、最初に、検索します。 .SUFFIXES 設定、.PRECIOUS、および推論規則を再帰的なメイクファイルに渡すために使用すると便利です。|
|!IF constantexpression|constantexpression が 0 以外の値に評価される場合に、!IF と次の !ELSE または !ENDIF の間のステートメントを処理します。|
|!IFDEF macroname|macroname が定義されている場合に、!IFDEF と次の !ELSE または !ENDIF の間のステートメントを処理します。 null マクロは、定義されているものと判断されます。|
|!IFNDEF macroname|macroname が定義されていない場合に、!IFNDEF と次の !ELSE または !ENDIF の間のステートメントを処理します。|
|!ELSE[IF constantexpression <br>&#124; IFDEF macroname<br>&#124; IFNDEF macroname]|前の !IF ステートメント、!IFDEF ステートメント、または !IFNDEF ステートメントが 0 に評価された場合に、!ELSE と次の !ENDIF の間のステートメントを処理します。 省略可能なキーワードを使用すると、プリプロセスをさらに細かく制御できます。|
|!ELSEIF|!ELSE IF と同義です。|
|!ELSEIFDEF|!ELSE IFDEF と同義です。|
|!ELSEIFNDEF|!ELSE IFNDEF と同義です。|
|!ENDIF|!IF、!IFDEF、!IFNDEF の各ブロックの終了を示します。 同じ行の !ENDIF の後のテキストは無視されます。|
|!UNDEF macroname|macroname を未定義にします。|

## nmake 起動オプション
|オプション|目的|
|:--|:--|
|/A|評価対象をすべてビルドします|
|/B|タイム スタンプが等しい場合でもビルドします|
|/C|メッセージを出力しません|
|/D|ビルド情報を表示します|
|/E|環境変数をメイクファイルのマクロ定義より優先します|
|/ERRORREPORT:<br>{NONE&#124;PROMPT&#124;QUEUE&#124;SEND}|エラーを Microsoft に報告します|
|/G|!include ファイル名を表示します|
|/HELP|使い方に関する概要を表示します|
|/I|コマンドからの終了コードを無視します|
|/K|エラーが返されても、関連のない依存関係行をビルドします|
|/N|コマンドの表示だけ行い、実行はしません|
|/NOLOGO|著作権メッセージが表示されないようにします|
|/P|NMAKE の情報を表示します|
|/Q|タイム スタンプはチェックしますがビルドは実行しません|
|/R|前に定義された推論規則とマクロを無視します|
|/S|実行されるコマンドを表示しません|
|/T|タイム スタンプを変更しますがビルドを実行しません|
|/U|インライン ファイルをダンプします|
|/Y|バッチモードを無効にします|
|/?|使い方に関する概要を表示します|

## 参照URL
- NMAKE リファレンス
http://msdn.microsoft.com/ja-jp/library/dd9y37ha.aspx