プログラミングユーティリティ

make の拡張機能のまとめ

以下では、make に新しく追加された機能について説明しています。

デフォルトのメークファイル

make の暗黙の規則およびマクロ定義は、このバージョンでは make プログラム中に定義 (ハードコード) されずに、デフォルトのメークファイルである /usr/share/lib/make/make.rules に含まれています。ローカルディレクトリに make.rules というファイルがある場合を除き、このデフォルトのメークファイルを自動的に読み取ります。ローカルディレクトリにある make.rules ファイルを使用する際は、標準の暗黙の規則および定義済みマクロを取得するために、デフォルトの make.rules ファイルをインクルードする指示を追加する必要があります。

状態ファイル .make.state

make は、状態ファイル .make.state も読み取ります。特殊ターゲットの .KEEP_STATEメークファイル中で使用されている場合は、make は、隠れた依存関係のリスト (cpp などのコンパイル処理によりレポートされます) と、各ターゲットを構築するために使用された最新の規則が記述されている、各ターゲットのについての記録をこのファイルに書き込み蓄積します。状態ファイルの書式は、通常のメークファイルの書式とほぼ同じです。

隠れた依存関係の検査

make.KEEP_STATE ターゲットにより起動された場合は、 cccppf77ldmakepc などのコンパイルコマンドによって報告された情報を使用して、ターゲットファイルにインクルードされたヘッダーファイル (場合によってはライブラリ) に対して依存関係の検査を実行します。これらの隠れた依存ファイルは、依存関係リストには記述されていません。多くの場合はローカルディレクトリ以外の場所に存在しています。

コマンド依存関係の検査

.KEEP_STATE が有効な場合に、ターゲットを構築するために使用されるコマンド行が以前の make 実行時から変更された場合 (メークファイルを編集したりマクロの値を変更した場合など)、ターゲットは最新でないとして扱われ、(ターゲットが依存するファイルよりもターゲットが新しい場合でも) make はターゲットを再構築します。

SCCS ファイルの自動取り出し

この節では、sccs が管理しているファイルの自動取り出しの規則を説明します。

チルド規則について

このバージョンの make は、ターゲットファイルを構築する規則がない場合には、sccs getx を適宜自動的に実行します。接尾辞リストで接尾辞の後にチルド (‾) が付いている場合は、sccs によって依存ファイルを取り出すのが適切であることを示します。このバージョンの make は、sccs ファイルの現在のバージョンを取り出すためのコマンドを含むチルドの接尾辞の規則をサポートしていません。

現在の sccs のバージョンの自動取り出しを禁止または許可するには、.SCCS_GET という特殊ターゲットを再定義します。このターゲットの規則を空白にすると、すべてのファイルに対して自動取り出しを禁止します。

パターンマッチングの規則

ユーザー定義の暗黙の規則を簡単にプロジェクトに追加する方法を簡素化するために、パターンマッチングの規則が追加されています。

tp%ts : dp%ds
      rule

この形式のターゲットエントリは、関連する依存ファイルからターゲットを構築するパターンマッチングの規則を定義します。tp はターゲット名の接頭辞、ts はその接尾辞です。dp は依存ファイル名の接頭辞、ds はその接尾辞です。% 記号は、ターゲットと依存ファイルの名前の両方に共通する、0 文字または 1 文字以上の連続した文字列を示すワイルドカードです。たとえば、以下のターゲットエントリは、接尾辞が .ms-ms というマクロパッケージを使用するファイルから接尾辞が .trtroff 出力ファイルを構築するパターンマッチングの規則を定義します。

%.tr: %.ms
		troff -t -ms $< > $@

メークファイルにこのエントリが含まれている場合に、以下のコマンドを実行します。

make doc.tr

結果は以下のようになります。

$ make doc.tr 
troff -t -ms doc.ms > doc.tr

doc2.ms というファイルがある場合に同じエントリを使用して、以下のコマンドを実行します。

make doc2.tr

結果は以下のようになります。

$ make doc2.tr 
troff -t -ms doc2.ms > doc2.tr

明示的なターゲットエントリは、ターゲットに適用されるパターンマッチングの規則よりも優先されます。パターンマッチングの規則は、通常は暗黙の規則よりも優先されます。例外的に、パターンマッチングの規則のターゲットエントリにおいて、規則の部分にコマンドが含まれていない場合は、make はターゲットを構築するための規則の検索を続行し、その依存関係として (依存関係) パターンに一致したファイルを使用します。

パターン置換マクロ参照

接尾辞の規則およびパターンマッチングの規則と同様に、指定したマクロ参照の語を変更する方法として、マクロ参照で接尾辞を置換する既存の方法よりもさらに汎用性が高い、パターン置換マクロ参照が追加されました。パターン置換マクロ参照は、以下の形式で記述します。

$(macro:p%s=np %ns)

ここで、p は既存の接頭辞 (ある場合)、s は既存の接尾辞 (ある場合)、np および ns は新しい接頭辞および接尾辞、% は 0 文字または 1 文字以上の一致文字列を示すワイルドカードです。

接頭辞および接尾辞の置換は、既存のパターンに一致するマクロの値中のすべての語に適用されます。この機能は、特にサブディレクトリの名前をそのサブディレクトリに含まれる各ファイルの接頭辞として使用する場合に便利です。以下にメークファイルの例を示します。

SOURCES= x.c y.c z.c 
SUBFILES.o= $(SOURCES:%.c=subdir/%.o) 

all: 
        	@echo $(SUBFILES.o)

結果は以下のようになります。

$ make
subdir/x.o subdir/y.o subdir/z.o

= 記号の右側 (置換後の語) では、任意の数だけワイルドカードの % を必要に応じて使用できます。以下に例を示します。

...
NEW_OBJS= $(SOURCES:%.c=%/%.o)

この置換は、以下のような結果になります。

...
x/x.o y/y.o z/z.o

パターン置換マクロ参照は、パターンマッチングの規則が記述されているターゲットエントリの依存関係を示す行では使用しないでください。使用した場合は、予期しない結果が生じます。以下にその例を示します。

OBJECT= .o 

x: 
%: %.$(OBJECT:%o=%Z) 
        	cp $< $@

このメークファイルは、makex.Z というファイルから x を構築しようとして記述したものです。しかし、依存関係の行に複数含まれている % のうち、どれをパターンマッチングの規則で使用し、どれをマクロ参照に適用するかを、make が特定できないため、パターンマッチングの規則は認識されません。

したがって、x.Z のターゲットエントリは実行されません。このような問題を回避するため、他の行で中間マクロを使用できます。

OBJECT= .o 
ZMAC= $(OBJECT:%o=%Z) 

x: 
%: %$(ZMAC) 
        	cp $< $@

新しいオプション

新しいオプションは、以下のとおりです。

-d

処理した各ターゲットの依存関係の検査結果を表示します。新しい依存関係、あるいはターゲットがコマンドの依存関係の結果構築されたことを示す依存関係をすべて表示します。

-dd

旧バージョンの make-d と同一の機能を実行します。内部状態など、make のすべての実行情報を表示します。

-D

メークファイルのテキスト (内容) を読み取り時に表示します。

-DD

メークファイルおよび使用されているデフォルトのメークファイルのテキストを表示します。

-p

マクロ定義およびターゲットエントリを出力します。

-P

ターゲットを再構築せずに、その依存関係をすべてレポートします。

C++ および Modula-2 のサポート

このバージョンの make には、C++ プログラムをコンパイルするための定義済みマクロが含まれています。また、Modula-2 をコンパイルするための定義済みマクロおよび暗黙の規則も含まれています。

定義済みマクロの命名規約

定義済みマクロの命名規約が合理的になりました。新しい命名規約に合わせて暗黙の規則が変更されました。マクロおよび暗黙の規則は、既存のメークファイルに対して上位互換性があります。

標準のコンパイルコマンド用のマクロを例に示します。

LINK.c

これは、実行可能ファイルを生成するための標準の cc コマンド行です。

COMPILE.c

これは、オブジェクトファイルを生成するための標準の cc コマンド行です。

新しい特殊ターゲット

.KEEP_STATE

メークファイルに記述されている場合は、隠れた依存関係およびコマンドの依存関係の検査を有効にします。また、make は、実行後に状態ファイル .make.state を更新します。


注 -

.KEEP_STATE ターゲットは、make の実行で使用したことがある場合は削除しないでください。


.INIT および .DONE

make 実行時に、最初と最後に実行するコマンドを指定します。

.FAILED

make が失敗したときに実行するコマンドを指定します。

.PARALLEL

ターゲットを並行処理するか逐次処理するかを指定します。

.SCCS_GET

このターゲットには、sccs 履歴ファイルから現在のバージョンのファイルを取り出す規則を指定します。

.WAIT

このターゲットが依存関係リストに記述されている場合は、並行処理の場合でも、make は先行する依存関係の処理が終了するまでそれ以降の処理を行わずに待機します。

lint の新しい暗黙の規則

lint を使用した差分検査をサポートするため、暗黙の規則が追加されました。

マクロ処理の変更

このバージョンでは、マクロの値を任意の長さにすることができます。また、旧バージョンではマクロの値から最後の空白文字だけが削除されましたが、このバージョンでは最初と最後の両方の空白文字が削除されます。

マクロ : 定義、置換、接尾辞置換

新しい追加演算子

+=

マクロの既存の値に、先頭にスペースが付いた文字列を追加します。

条件付きマクロ定義

:=

ターゲットの条件付きマクロ定義を示す演算子です。

target := macro = value

このようにメークファイルで記述すると、target およびその依存関係を処理する際には、macrovalue に指定された値になります。

条件付きマクロのパターン

make は、条件付きマクロ定義のターゲット部分において、ワイルドカードパターンである % を認識します。以下に例を示します。

profile_% := CFLAGS += -pg

この例は、profile_ という接頭辞を持つすべてのターゲットについて、CFLAGS マクロを変更します。条件付き定義の値では、パターン置換を使用できます。以下に例を示します。

profile_% := OBJECTS = $(SOURCES:%.c=profile_%.o)

この例は、SOURCES 値に指定されているすべての .c ファイルのベース名の前後に、profile_ という接頭辞および .o という接尾辞を追加します。

接尾辞の置換の優先度

部分文字列の置換は、参照されるマクロが展開されてから実行されます。旧バージョンの make では、置換が先に実行されるため、結果を直観的に理解しにくくなっていました。

入れ子にしたマクロ参照

このバージョンの make は、内側の参照を展開してから外側の参照を展開します。以下に例を示します。

CFLAGS-g = -I../include
  OPTION = -g
  $(CFLAGS$(OPTION))

この例の入れ子にした参照の値は、旧バージョンでは NULL 値になりましたが、このバージョンでは -I../include になります。

クロスコンパイルマクロ

定義済みマクロの HOST_ARCH および TARGET_ARCH をクロスコンパイルで使用できます。デフォルトでは、arch マクロは、arch コマンドが返す値に設定されます。

マクロでのシェルコマンド出力

以下の定義は、command で指定されたコマンドの標準出力を MACRO の値として設定します。

MACRO :sh = command

出力に含まれる復帰改行は、空白文字に置換されます。コマンドは、定義が読み込まれたときに 1 回だけ実行されます。標準エラー出力は無視されます。コマンドがゼロ以外の終了ステータスを返した場合は、make はエラーを表示して停止します。

$(MACRO :sh)

このマクロ参照は、参照が評価されるときに MACRO に設定されているコマンド行出力に展開されます。復帰改行は、空白文字に置換されます。標準エラー出力は無視されます。コマンドがゼロ以外の終了ステータスを返した場合は、make はエラーを表示して停止します。

ar ライブラリのサポートについて

make は、ar フォーマットのライブラリのメンバーを、そのメンバーと名前が同じファイルから自動的に更新します。また、このバージョンの make では、以下の形式で、依存関係の名前としてメンバーのリストを指定できます。

lib.a: lib.a(member member ...)

ターゲットグループ

このバージョンでは、複数ターゲットファイルで構成されるグループを生成するように規則を指定することができます。ターゲットエントリ中で各ターゲット名が + 記号で区切られている場合は、指定したターゲットがグループを構成していることを示します。ターゲットグループの規則は、make の実行 1 回につき 1 度だけ実行されます。