マクロ定義は、メークファイルの任意の行に記述できます。マクロは、長いターゲットリストや式を短縮するために、あるいは繰り返し記述する必要のある長い文字列の代替として使用できます。
また、マクロを使用して、オブジェクトファイルのリストをソースファイルのリストから取得できます。マクロ名は、メークファイルの読み取り時に割り当てられます。マクロ参照の値は、最後に割り当てられた値によって決定されます。
マクロの評価は、実際には上述よりも複雑に行われます。「暗黙の規則と動的なマクロ」を参照してください。
条件付きマクロおよび動的マクロを除き、make はマクロの値をマクロの定義順に割り当てます。
マクロ参照は、他のマクロの参照箇所に組み込むことができます (旧バージョンの make では使用できません)。
$(CPPFLAGS$(TARGET_ARCH))
代入文の += は、指定された文字列をマクロの既存の値の後に追加します。
この場合は、マクロは内側から外側に展開されます。以下の定義例では、make は Sun-4 システム用の正しいシンボルを定義します。
CPPFLAGS-sun4 = -DSUN4 CPPFLAGS += $(CPPFLAGS-$(TARGET_ARCH))
make には、参照されるマクロの値に含まれる特定の接尾辞を置換する機能があります。慣例として、接尾辞はドット (.) で始まりますが、任意の文字列を接尾辞として指定することもできます。
$(macro:old-suffix=new-suffix)
上記の形式は、接尾辞を置換するマクロ参照の書式です。このような参照を使用することによって、以下のようにオブジェクトファイルのリストをソースファイルのリストで表わすことができます。
OBJECTS= $(SOURCES:.c=.o)
この例では、make は値に含まれる接尾辞 .c をすべて .o に置換します。指定された接尾辞が付いていない語に対しては置換は適用されません。
SOURCES= main.c data.c moon OBJECTS= $(SOURCES:.c=.o) all: @echo $(OBJECTS)
例えば、上記のメークファイルで make を実行すると次のような結果になります。
$ make main.o data.o moon
C プログラムをより容易にデバッグおよび管理するには、lint ツールを使用します。lint は、他のアーキテクチャへの移植性がない C の構造体の検査も行います。
lint は、移植性のある C プログラムを記述する際に非常に便利です。C プログラムの検査を行う lint は、発見および追跡するのが難しいバグを防ぐためのツールです。初期化されていないポインタ、関数呼び出しにおける引数の数の不一致、移植不可能な C の構造体の使用、などのバグがないかどうかを検査します。clean と同様に、lint はターゲットの慣用名です。C プログラムを構築するメークファイル中に、lint を含めることをお勧めします。lint は、cpp および lint の最初の (構文解析) 処理過程で処理された出力ファイルを生成します。出力ファイルは、接尾辞が .ln となります。また、接尾辞の置換によって、ソースファイルのリストから lint の出力ファイルを生成することもできます (旧バージョンの lint では不可能な場合があります)。
LINTFILES= $(SOURCES:.c=.ln)
lint のターゲットエントリは、以下のようになります。
lint: $(LINTFILES) $(LINT.c) $(LINTFILES) $(LINTFILES): $(LINT.c) $@ -i
各 .ln ファイルは、対応する .c ファイルから構築するという暗黙の規則があるため、.ln ファイルに対するターゲットエントリは必要ありません。ソースが変更されると、以下のように make を実行するときに .ln ファイルが更新されます。
make lint
LINT.c
という定義済みマクロに lint のオプション指定として LINTFLAGS
マクロへの参照が含まれていますが、通常は特に指定しなくてよいでしょう。lint では cpp を使用するため、コンパイルのプリプロセッサオプション (-I など) に対して、通常は CFLAGS ではなく CPPFLAGS を使用してください。また、LINT.c
マクロには CFLAGS
への参照は含まれていません。
make clean を実行すると、このターゲットによって生成された .ln ファイルが削除されるようにしたいと考えられます。clean ターゲットには、そのようなマクロ参照を簡単に追加することができます。