マクロ定義

置換え参照(substitute reference)

$(OBJ:.o=.c) のようにかくと,$(OBJ)の中のサフィックス“.o”を“.c”に置き換えられる.

パターン一致(%)を使うと次のような凝ったこともできる(gmake拡張機能).

FILES = a.o b.o c.o
OBJS  = $(FILES:%=lib/%)
SRCS  = $(OBJS:obj/%.o=src/%.c)

文字列の追加

マクロTARGET = a b cに対して, abcの後ろに.cを追加して, a.cb.cc.cにするには $(TARGET:=.c)とすればよい.

TARGET   = a b c
echo:
        @echo $(TARGET:=.c)

注意点:置換は文字列の末尾だけに適用される

文字列の末尾(または空白の直前)でしか置換が起こらない. これはおそらくサフィックス部分を置換することを想定しているために,このような仕様になっているのではないかと思う.

Makefile
# Makefile

SRCS  = abcx xabc xabcx
OBJS  = $(SRCS:abc=ABC)

echo:
        @echo $(OBJS)

実行結果 説明
$ make
abcx xABC xabcx

xabcだけが置き換わって, abcxxabcxは置き換えの対象にならない.

文字列連結演算が可能だったりする

実はmakeでも演算(文字列連結演算)ができたりする.

OBJS  = a.o b.o c.o
OBJS += d.o e.o f.o

シェルスクリプトのように値を前に差し込むこともできるが,その場合“:=”演算子を使う必要がある.

OBJ  = a.o b.o c.o
OBJ := 1.o 2.o 3.o $(OBJS)

makeのマクロ展開方法には,再起展開マクロ(=)単純展開マクロ(:=)があり, 単純展開マクロは,makeの処理がその行に達した時点の右辺のマクロ値を使用し, 再起展開マクロは,makeがMakefileを末尾まで処理し終わって, すべてのマクロの最終的な値が決定した後に後退しながらマクロ定義を完成させるようになっている (したがって,再起展開マクロが無限ループするような定義を含んでいるとエラーになる).

これを考慮すると, 次の記述は予想とは違う動きになるかもしれないことが理解できると思う.

BASEDIR = /usr/ccs
INCLUDE = $(BASEDIR)/includes
BASEDIR = /usr/local
LIB     = $(BASEDIR)/lib

Makefileは記述順に対する依存はめったにない. ただし,依存記述行にマクロをかいた場合については時系列を意識しなければならない.

INCFILES =
sub1.o: sub1.c $(INCFILES)

INCFILES = sub2.h
sub2.o: sub2.c $(INCFILES)

INCFILES =
sub3.o: sub3.c $(INCFILES)

これは,マクロの再帰的定義とは異なり,時系列に依存する. すなわち,2番目だけsub2.o: sub2.c sub2.hとなり, 1番目と3番目は$(INCFILES)は空になる(依存関係記述行に書くときは単純代入になるため).

マクロの参照についての注意点

定義済みマクロ

定義済みマクロ 用途
CC
CFLAGS
CPPFLAGS Cプリプロセッサのオプション
AS
ASFLAGS
YACC
YFLAGS
LEX
LFLAGS
FC Fortranコンパイラ
LINT
LINTFLAGS
CO RCSのco(チェックアウト)コマンド
RM rm(remove ファイル削除)コマンド

動的マクロ

動的マクロ 機能
$@
$<
$*
動的マクロ(gmake拡張機能)
$^ 依存ファイルのファイル名. $<の違いは依存ファイルが複数個書かれている場合の動作. $<だと最初のファイル名になるが, $^だと,すべての依存ファイルを並べたものに置き換わる.
$+ 依存ファイルのファイル名. $^との違いは,依存ファイル群の中に同じファイル名が複数回現れる場合の動作. $^は重複をとりのぞくが, $+は重複をそのまま残す仕様になっている(どういうときに役立つのか理解できないけど…).
$? $^のうち,ターゲットより新しいもののを抽出したものになる.

さらにDFを組み合わせてディレクトリおよびファイル名を取り出すことができる. 例えば,$(@D)とすると,ターゲットファイルのディレクトリ名, $(@F)とすると,ターゲットファイルのパスを除いたファイル名部分が取り出せる.

make -p:デフォルト ルールの表示

現在定義されているルールを表示させるには“make -p”とすればよい. Makefileが存在しているディレクトリで“make -p”とすると, Makefileで定義されているルール+デフォルト ルールが表示されるので, 純粋に初期状態で登録されているデフォルト ルールだけを参照したい場合には Makefileのないディレクトリで実行するか, “make -p -f nothing”のように存在しないファイル名を指定して実行すればよい.


はたいたかし
トップ > 開発ツール > make