There is the original file(in English) here.
最初,,,最後のページ,目次 に移動.

暗黙ルールの利用

 標準的なターゲットファイル更新の手法の中にはかなり頻繁に使うものもあります。例えば、オブジェクトファイルを作成するにはccというCコンパイラを使ってCソースファイルから作るという方法が習慣的なものの一つです。

 習慣的な技術の利用方法をわざわざ詳細に指定しなくてもいいようにmakeに伝えてくれるものが暗黙のルールです。例えばCコンパイル作業に働く暗黙のルールがあります。ファイル名でどの暗黙ルールが実行されるのかが決定されるのです。例えばCのコンパイル作業では典型的に`.c'ファイルを受け取り`.o'ファイルを作成します。だからこの二つで終わるファイル名の組を見つけるとmakeはCコンパイルを行う暗黙ルールを適用します。

 暗黙ルールの連鎖が次々に適用されることもあります。例えば`.o'ファイルを更新するのに`.y'ファイルを使う場合それを`.c'のつもりで更新します。 これについては暗黙ルールの連鎖の項を見て下さい。

 ビルトインの暗黙ルールではコマンドの実行に変数をいくつか使っているため、その変数の値を変更すれば暗黙ルールの動作を変更できます。例えばCFLAGSという変数は暗黙ルールでのCコンパイル作業でCコンパイラに渡すフラグを制御しています。 これについては暗黙ルールで用いられる変数の項を見てください。

 型ルールを書けば自分で暗黙ルールを定義することもできるようになります。これについては型ルールの定義と再定義の項を見て下さい。

 サフィックスルールでも暗黙ルールを定義できますがこちらは前のものより限られた用途になります。型ルールのほうがきれいですし一般的なのですが、サフィックスルールは互換性のために残されています。 これについては古いタイプのサフィックスルールの項を見て下さい。

暗黙ルールの利用

 makeに習慣的なターゲットファイル更新方法を探させるにはただ自分でコマンドを書くのを控えるだけでいいのです。つまりコマンド行を全く書かないルールを記述するか、一つのルールについては少しもルールを書かないかのどちらかにして下さい。そうすればmakeがどの暗黙ルールを利用するかを、どういう種類のソースファイルがあるか、またはどのソースファイルが更新可能か、という事に基づいて識別してくれるでしょう。

 例えばmakefileがこのような感じだったとすると…


foo : foo.o bar.o
        cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)

 `foo.o'について言及しているにもかかわらずそれについてのルールを与えていないため、makeが自動的に更新方法を指示する暗黙のルールを探すことになります。これは`foo.o'が存在するかどうかによらず動作します。

 暗黙のルールが発見され次第、コマンドと一つ以上の依存関係(ソースファイル)に供給されます。`foo.o'についてコマンドなしのルールを書きたくなる場合というのは、ヘッダファイルのような暗黙ルールでは供給されない依存関係を追加指定する必要がある場合だと思います。

 それぞれの暗黙ルールにはターゲットの型と依存関係の型があって、多くの暗黙ルールに同じターゲット型を持たせることも可能です。例えば`.o'ファイルを作成するルールが多数あり、一つはCコンパイラで`.c'ファイルから作成するもの、もう一つはPascalコンパイラで`.p'から作成するもの…というようになります。実際に適用されるルールはその依存関係が存在したり作成可能な一つだけです。だから`foo.c'というファイルがあればmakeはCコンパイラを実行しますし、そうでなくて`foo.p'というファイルがあるのならmakeが実行するのはPascalコンパイラ、そうでなければ同じターゲット型の次のルール、というようになります。

 もちろんあなたがmakefileを記述する時はどの暗黙ルールをmakeに使わせたいかわかっていて、関係する依存関係が全部存在することになるのが分かっているのでその使わせたいものが選択されるかを知っていることでしょう。暗黙ルールのカタログの項を見れば予め定義された全ての暗黙ルールのカタログがあります。

 上で言いたかったのは、ある暗黙ルールで要求される依存関係が「存在するか作成可能」であればそのルールが適用される、という事です。あるファイルがmakefileの中の明示的なターゲットか依存関係である場合、またはある暗黙ルールで再帰的にそのファイルの作成方法を示しているなら、そのファイルは「更新可能」になります。ある暗黙の依存関係が別の暗黙ルールの結果であるなら、連鎖と呼ばれるものが起こります。 これについては暗黙ルールの連鎖の項を見て下さい。

 一般的にmakeはコマンドを持たない「ターゲットと二重コロンルール」のそれぞれに対して暗黙ルールを探します。依存関係でしか書かれていないファイルはルールのないターゲットとみなすので、これにも暗黙ルールの検索が行われます。どう検索をするのかの詳細は暗黙ルールの検索アルゴリズムの項にあります。

注意:明示的な依存関係は暗黙ルールの検索に影響しません。例えば次の明示ルールについて考える場合…


foo.o: foo.p

 `foo.p'の依存関係はmakeがオブジェクトファイル(`.o'ファイル)をPascalソースファイル(`.p'ファイル)から作成させる暗黙ルールを使って`foo.o'を更新するということを示す必要はありません。例えばもし`foo.c'も存在するならCソースファイルからオブジェクトファイルを作成する暗黙ルールが代わりに利用されます。これはPascalルールよりもこちらのほうが前定義暗黙ルールのリストの中で先にあるためです(暗黙ルールのカタログの項を参照)。

 コマンドのないターゲットに暗黙のルールを使わせないようにするにはセミコロンを使ってターゲットに空っぽのコマンドを与えて下さい(空のコマンドの利用の項を参照)。

暗黙ルールのカタログ

 makefileで明示的に上書きするかキャンセルさせない限り常に有効な前定義の暗黙ルール(Predefined Implicit Rules)のリストをここに示します。暗黙のルールのキャンセルや上書きについての情報は暗黙のルールをキャンセルするの項を見て下さい。`-r'オプションか`--no-builtin-rules'オプションで全ての前定義ルールをキャンセルします。

 `-r'オプションが与えられていない場合でも全ての暗黙ルールが定義されるというわけではありません。前定義の暗黙ルールの多くはmakeの内部でサフィックスルールとしてインプリメント(履行)されているので、そういうものはサフィックスリスト(.SUFFIXESという特別なターゲットの依存関係のリスト)によって定義されます。デフォルトのサフィックスリストは次のようになります。 .out, .a, .ln, .o, .c, .cc, .C, .p, .f, .F, .r, .y, .l, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch .web, .sh, .elc, .el。 これらサフィックスのうち一つを依存関係として持っている、以下に述べた暗黙のルールはどれも実際にはサフィックスルールです。サフィックスリストを修正した場合、前定義のサフィックスルールのうち有効なものは指定したリストにサフィックスが最低一つあるものだけになり、リストに一つもサフィックスがないルールは無効になります。サフィックスルールについての全詳細は古いタイプのサフィックスルールの項にあります。

Cプログラムのコンパイル
 `n .o'`$(CC) -c $(CPPFLAGS) $(CFLAGS)'という形式のコマンドを使って自動的に`n .c'から作成される。
C++プログラムのコンパイル
 `n .o'`$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)'という形式のコマンドを使って自動的に`n .cc'`n .C'から作成される。C++ソースファイルには`.C'の代わりに`.cc'というサフィックスを使うことを奨励します。
Pascalプログラムのコンパイル
 `n .o'`$(PC) -c $(PFLAGS)'という形式のコマンドを使って自動的に`n .p'から作成される。
FortranプログラムとRatforプログラムのコンパイル
 `n .o'をフォートランコンパイラを実行して自動的に`n .r'`n .F'`n .f'かから作成する。利用する正確なコマンドは以下の通り。
`.f'
`$(FC) -c $(FFLAGS)'.
`.F'
`$(FC) -c $(FFLAGS) $(CPPFLAGS)'.
`.r'
`$(FC) -c $(FFLAGS) $(RFLAGS)'.
FortranプログラムとRatforプログラムのプリプロセス
 `n .f'`n .r'`n .F'かから作成する。このルールではRatforか、プリプロセス可能なフォートランプログラムを厳格なフォートランプログラム(strict Fortran program)にコンバートさせるプリプロセッサを実行するだけです。利用する正確なコマンドは以下の通り。
`.F'
`$(FC) -F $(CPPFLAGS) $(FFLAGS)'.
`.r'
`$(FC) -F $(FFLAGS) $(RFLAGS)'.
Modula-2 プログラムのコンパイル
 `n .sym'`$(M2C) $(M2FLAGS) $(DEFFLAGS)'という形式のコマンドを使って`n .def'から作成する。`n .o'`$(M2C) $(M2FLAGS) $(MODFLAGS)'という形式のコマンドで`n .mod'から作成する。
アセンブリングと、アセンブラプログラムのプリプロセス
 `n .o'を自動的にasというアセンブラを実行して`n .s'から作成する。正確なコマンドは`$(AS) $(ASFLAGS)'  `n .s'を自動的にcppというCプリプロセッサを実行して`n .S'から作成する。正確なコマンドは`$(CPP) $(CPPFLAGS)'
一つのオブジェクトファイルのリンク
 `n 'を自動的にCコンパイラ経由で(普通はldという)リンカを実行して`n .o'から作成する。利用する正確なコマンドは`$(CC) $(LDFLAGS) n .o $(LOADLIBES)'。 このルールは一つのソースだけで一つのプログラムを作るのに見合うルールです。それに(多分種々多様なソースファイルから作成された)複数のオブジェクトファイルがあり、うち一つが実行可能なファイルの名前である場合も正しい事をやってくれるでしょう。だから、

x: y.o z.o

…として、`x.c'`y.c'`z.c'のどれもが存在していれば次のものを実行することになります。

cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
rm -f x.o
rm -f y.o
rm -f z.o

 さらに複雑なケースは、実行可能ファイル名に由来する名前を持つオブジェクトファイルがないような場合があげられます。この場合、リンクさせる明示的なコマンドを記述しなければなりません。 `.o'オブジェクトファイルに自動的に作成されるような類のファイルはそれぞれ`-c'オプションをつけずにコンパイラ(`$(CC)'`$(FC)'`$(PC)'の何れかで、`$(CC)'というCコンパイラは`.s'ファイルをアセンブルするのにも使います)を使って自動的にリンクされる事になるでしょう。`.o'オブジェクトファイルを中間ファイルとして使ってこの作業を行ったほうがコンパイルとリンクの作業が一歩速くなるため、こうされる事もあります。
YaccからCプログラム
 `n .c'`$(YACC) $(YFLAGS)'というコマンドを使ってYaccを実行して`n .y'から自動作成する。
LexからCプログラム
 `n .c'をLexを実行して`n .l'から自動作成する。具体的なコマンドは`$(LEX) $(LFLAGS)'
LexからRatforプログラム
 `n .r'をLexを実行して`n .l'から自動作成する。具体的なコマンドは`$(LEX) $(LFLAGS)'。 Cコードを生成するかRatforコードを生成するかによらず全てのLexファイルについて`.l'という同じサフィックスを利用するという慣習があるため、makeは二つの言語のうちどちらを使っているか個々に自動的に判断する事ができません。make`.l'からオブジェクトファイルを更新するために呼び出す場合、どちらのコンパイラを使うか内部で推測しなければなりませんが、Cコンパイラのほうがより一般的であるためこちらであると推測することになります。Ratforを使っている場合、`n .r'とmakefileで書いてmakeにちゃんとこの事を知らせて下さい。またはCファイルではなくて専らRatforを使われる方は暗黙ルール・サフィックスのリストからこうやって`.c'を削除して下さい。

.SUFFIXES:
.SUFFIXES: .o .r .f .l ...

C、Yacc、LexのどれかのプログラムからLintライブラリを作成する
 `n .ln'lintを実行して`n .c'から作成する。正確なコマンドは`$(LINT) $(LINTFLAGS) $(CPPFLAGS) -i'。 同じコマンドが`n .y'`n .l'から生成されたCコードにも利用されます。
TeXとWeb
 `n .dvi'`$(TEX)'というコマンドを使って`n .tex'から作成する。`n .tex'`$(WEAVE)'を使って`n .web'から作成するか、`$(CWEAVE)'を使って`n .w'から(と`n .ch'が存在するか作成可能ならこれからも)作成する。`n .p'`$(TANGLE)'を使って`n .web'から作成し、`n .c'`$(CTANGLE)'を使って`n .w'から(と、`n .ch'が存在するか作成可能ならこれからも)作成する。
TexinfoとInfo
 `n .dvi'`$(TEXI2DVI) $(TEXI2DVI_FLAGS)'というコマンドを使って`n .texinfo'`n .texi'`n .txinfo'から作成する。`n .info'`$(MAKEINFO) $(MAKEINFO_FLAGS)'というコマンドを使って`n .texinfo'`n .texi'`n .txinfo'から作成する。
RCS
 `n 'というどんなファイルでも、必要であれば`n ,v'`RCS/n ,v'という名前のRCSファイルから抽出される。利用する正確なコマンドは`$(CO) $(COFLAGS)'。既に存在する`n 'についてはRCSのほうが新しくてもRCSから抽出されません。RCSに対するルールはこれが最後のものなので(「何でも一致」型のルールの項を参照)、RCSファイルは他のソースから生成される事がなく、必ず実際に存在していなければなりません。
SCCS
 `n 'というどんなファイルでも、必要であれば`s.n '`SCCS/s.n 'というSCCSファイルから抽出される。利用する正確なコマンドは`$(GET) $(GFLAGS)'。SCCSに対するルールはこれが最後のものなので(「何でも一致」型のルールの項を参照)、SCCSファイルは他のソースから生成される事がなく、必ず実際に存在していなければなりません。 SCCSに都合がいいので`n 'というファイルは`n .sh'からコピーされてから(それ自身だけで)実行可能に作成されます。これはSCCSに入っているのがシェルスクリプトだからです。RCSではファイルの実行権を保存するのでRCSにおいてはこの機能を使う必要がありません。SCCSを利用は控える事をお勧めします。RCSは多方面にわたって優れている上、フリーです。これに匹敵する(または劣る)専売ソフトウェアを使う代わりにフリーソフトウェアを選択する事であなたもフリーソフトウェア運動を支援できます。

 普通は上の表でリストされた変数を変更したがると思います。この方法については後に続く項に述べています。

 ですが、ビルトインの暗黙ルール中のコマンドというのは実際にはCOMPILE.cLINK.pPREPROCESS.Sのような変数を利用し、その値は上でリストしたコマンドを含むものになります。

 make`.x 'ソースファイルをコンパイルするルールではCOMPILE.x という変数を使う、という慣習に従っています。 同じく`.x 'ファイルから実行可能ファイルを生産するルールではLINK.x を、`.x 'ファイルからプリプロセス処理するルールではPREPROCESS.x を使います。

 オブジェクトファイルを生産するルールはどれもOUTPUT_OPTIONという変数を使っています。makeはコンパイル時オプションによって`-o $@'を含めるか、空っぽかのどちらかで変数を定義します。ソースファイルが別のディレクトリにある時はVPATHを利用する場合と同様に`-o'オプションをつけて出力ファイルが正しいファイルであることを確実にする必要があります(ディレクトリから依存ファイルを探すの項を参照)。ですがオブジェクトファイルを作成するのに`-o'スイッチを受け付けないシステムのコンパイラもあります。こういうシステムを利用していてVPATHを使う場合、コンパイラ作業で間違った場所に出力してしまう事になるでしょう。この問題の代替手法としてOUTPUT_OPTION`; mv $*.o $@'という値を与えてください。

暗黙ルールに用いられる変数

 ビルトインの暗黙ルール中にあるコマンドを使えば前定義の変数を自由に利用できます。makefile中、makeの引数、環境のいずれかの方法で変数を変えれば暗黙のルールを再定義しなくても暗黙のルールの動作を変えることができます。

 例えば、Cソースファイルのコンパイルに使われるコマンドでは実際は`$(CC) -c $(CFLAGS) $(CPPFLAGS)'と命令します。利用されている変数のデフォルトの値は`cc'と何もないものなので`cc -c'というコマンドを使います。`CC'`ncc'で再定義すれば暗黙のルールで行われるどのCコンパイルでも`ncc'を実行するようになります。`CFLAGS'の中身がAMP>`-g'になるように再定義すれば各コンパイル作業で`-g'オプションを渡すようになります。`$(CC)'全ての暗黙ルールでCのコンパイル作業でコンパイラプログラム名称を得るのに利用しており、また`$(CFLAGS)'全ての暗黙ルールでCコンパイラに渡す引数としてインクルードされます。

 暗黙のルールに用いられる変数は大別すると二種類に落ち着きます。うち一つは(CCのような)プログラム名称、もう一つは(CFLAGSのような)プログラムへの引数を格納するものです。(「プログラム名称」にコマンド引数がいくつか含まれる事もあり得ますが、必ず実際に実行可能なプログラム名称から始まっていなければいけません。)変数に一つ以上の引数を値として格納させるにはスペースで区切って下さい。

 ここにビルトイン・ルールでプログラム名称として使われている変数の表を示します。

AR
 アーカイブ保全プログラム(Archive-maintaining program)。デフォルトは`ar'
AS
 アセンブリを行わせるプログラム。デフォルトは`as'
CC
 Cプログラムをコンパイルするプログラム。デフォルトは`cc'
CXX
 C++プログラムをコンパイルするプログラム。デフォルトは`g++'
CO
 RCSからファイルの抽出を行うプログラム。デフォルトは`co'
CPP
 Cプリプロセッサを実行し、標準出力に結果を出力するプログラム。デフォルトは`$(CC) -E'
FC
 FortranプログラムとRatforプログラムのコンパイル・プリプロセスのいずれかを行うプログラム。デフォルトは`f77'
GET
 SCCSからファイルを抽出するプログラム。デフォルトは`get'
LEX
 Lexの文法をCプログラムかRatforプログラムに変換するのに利用するプログラム。デフォルトは`lex'
PC
 Pascalプログラムをコンパイルするプログラム。デフォルトは`pc'
YACC
 Yaccの文法をCプログラムに変換するのに利用するプログラム。デフォルトは`yacc'
YACCR
 Yaccの文法からRatforプログラムに変換するのに利用するプログラム。デフォルトは`yacc -r'
MAKEINFO
 TexinfoソースからInfoファイルにコンバートするプログラム。デフォルトは`makeinfo'
TEX
 TeXソースからTex DVIファイルを作成するプログラム。デフォルトは`tex'
TEXI2DVI
 TexinfoソースからTeX DVIファイルを作成するプログラム。デフォルトは`texi2dvi'
WEAVE
 WebをTeXに翻訳するプログラム。デフォルトは`weave'
CWEAVE
 C WebをTeXに翻訳するプログラム。デフォルトは`cweave'
TANGLE
 WebをPascalに翻訳するプログラム。デフォルトは`tangle'
CTANGLE
 C WebをCに翻訳するプログラム。デフォルトは`ctangle'
RM
 ファイルを削除するコマンド。デフォルトは`rm -f'

 次に上のプログラムに追加の引数を渡すのに使う変数の表を示します。個別に書いていないものについては全ての変数のデフォルト値は空っぽの文字列です。

ARFLAGS
 アーカイブ保全プログラム(archive-maintaining program)に与えるフラグ。デフォルトは`rv'
ASFLAGS
 (`.s'`.S'ファイルによって明示的に発動した場合)アセンブラに与える追加フラグ。
CFLAGS
 Cコンパイラに与える追加フラグ。
CXXFLAGS
 C++コンパイラに与える追加フラグ。
COFLAGS
 coというRCS用プログラムに与える追加フラグ。
CPPFLAGS
 Cプリプロセッサとそれを利用するプログラム(CかFortranのコンパイラ)に与える追加フラグ。
FFLAGS
 Fortranコンパイラに与える追加フラグ。
GFLAGS
 getというSCCS用プログラムに与える追加フラグ。
LDFLAGS
 `ld'というリンカを呼び出してくれるコンパイラに、リンク実行時に与える追加フラグ。
LFLAGS
 Lexに与える追加フラグ。
PFLAGS
 Pascalコンパイラに与える追加フラグ。
RFLAGS
 Raftorプログラム用に呼び出した時にFortranコンパイラに与える追加フラグ。
YFLAGS
 Yaccに与える追加フラグ。

暗黙ルールの連鎖

 暗黙ルールの連続実行でファイルを作成する場合が時折あります。例えば`n .o'というファイルを`n .y'から作成する場合、まずはじめにYaccを実行し、その次にcc、となるでしょう。こういう連続実行を連鎖といいます。

 `n .c'が存在するか、このことについてmakefileで書いている場合は特別な検索作業が要求される事がなく、make`n .c'をCコンパイルすればこのオブジェクトファイルが作成できるのに気づいて、その後`n .c'を作成する方法について模索した時にYaccを実行するルールを利用してくれます。それで最終的に`n .c'`n .o'の両方が更新されることになります。

 ですが`n .c'が存在せずそれについて何も書かれていない場合でさ、え、`n .o'`n .y'の処理間のつながりが欠落した部分(ミッシングリンク)を想定する術をmakeは知っているのです! この場合は`n .c'中間ファイルと呼ばれます。ひとたび中間ファイルの用途を決めてしまえばmakeはそれがmakefileで書かれていた場合と同じように、作成方法を指示する暗黙ルールと一緒にデータベースに格納します。

 中間ファイルに対しては、他のどのファイルとも全く同じように、作成させるルールを用意して更新します。ただし中間ファイルの扱いについては相違点が二点あります。

 第一に中間ファイルが存在しない時には他のファイルと違う動作になります。b という普通のファイルが存在しない時にb に依存するターゲットを処理する場合、makeは相変わらずにb を作成してb からターゲットを更新します。ところがb が中間ファイルの場合makeは処理を実行しなくてもいいのです。b を更新しなくても良い場合というのはb の依存関係が最終目標のターゲットより新しくなく、ターゲットを更新するような理由が他にない場合です。

 第二にmakeが他の何かを更新するためにb を作成する場合に、b が必要でなくなり次第削除されるという点が違います。そのため、make実行前に存在していなかった中間ファイルはmake実行後も存在しない事になります。どのファイルを削除したか、というのはmake`rm -f'コマンドを出力して報告してくれます。

 普通はmakefileでターゲットか依存関係として書かれているファイルは中間ファイルになり得ませんが、.INTERMEDIATEという特別なターゲットの依存関係として中間ファイルとさせたいファイルを明示的にリストしておけばmakefileに書かれているファイルについても中間ファイルにできます。この手法は他の方法で明示的に述べられたファイルについても効果があります。

 派生(secondary)ファイルとしてマークしておけばその中間ファイルの自動削除を防ぐ事が可能です。マークするには.SECONDARYという特別なターゲットの依存関係として記述して下さい。ファイルが派生である場合、既存のファイルではないからという理由だけでファイルを作成しなくなり、makeが自動削除することもなくなります。派生ファイルとしてマークしたファイルは同時に中間ファイルとしても扱われることになります。

 (`%.o'のような)暗黙ルールのターゲットの型を.PRECIOUSという特別なターゲットの依存関係に記述すると、ターゲットの型が一致するファイル名を持つ中間ファイルが暗黙ルールで作成された場合に保存するようになります。これについては makeを邪魔するか中断させるの項を見て下さい。

 3つ以上の暗黙ルールが一度に連鎖発動する事もあります。たとえば`RCS/foo.y,v'から`foo'を作ることもできますがこの場合はRCS、Yacc、ccを実行します。`foo.y'`foo.c'の二つは中間ファイルなので最後に削除されます。

 一度の連鎖で一つの暗黙ルールが何度か起こるという事はありえません。なぜなら`foo.o.o'から`foo'を作るのにリンカを二度も実行するような馬鹿げた事をmakeは考えないからです。これを強制させているお蔭で暗黙ルールの連鎖の検索において無限ループが起こる事がない、という利点があります。

 別の方法によってルールの連鎖で処理しているものを最大限に利用するための特別な暗黙ルール、というのもあります。例えば`foo.c'から`foo'を作るにはコンパイルとリンクを二つのわけ隔てられたルールを`foo.o'を中間ファイルとして使って連鎖させて処理することが可能ですが、実際にはこのケースのための特別なルールでccコマンドを一つ使うだけでコンパイルとリンクを行ってくれます。オプティマイズ(最大限に利用する)ルールを使えばルールを順番に連鎖するよりも速くなるので、オプティマイズルールが優先的に使われます。

型ルールの定義と再定義

 型ルールを書けば暗黙のルールをあなた自身で定義する事ができます。型ルールはターゲット(のうち、正確には一つ)が`%'という文字を含んでいるという事意外は普通のルールと同じです。この文字を含んだターゲットはファイル名を一致させるための型として認識され、`%'の部分は空っぽでなければどんな部分文字列にも一致し、かつ一方でその他の文字は全く一致していなければなりません。同様に`%'を使った依存関係ではターゲット名にどういう名前が関連しているか、という事を示します。

 だから`%.o : %.c'という型ルールは`語幹 .c'という全てのファイルから`語幹 .o'という別のファイルを作成する方法を命令します。

注意:型ルールの`%'の展開は、makefile読み込み時の変数・関数の展開が全部終わった後に行われます。これについては変数の利用法の項とテキスト変形関数の項を見て下さい。

型ルール入門

 型ルールではターゲット(のうちの一つ…正確には。)に`%'という文字を含んでいて、これを含んでいなければ普通のルールと全く同じになってしまいます。型ルールのターゲットはファイル名に一致させる型で、普通の文字の部分はそれ自身と同じ文字を一致させなければなりませんが、`%'には空っぽでさえなければどういう部分文字列にも当てはまります。

 例えば`%.c'は、`.c'で終わるどのファイル名にも一致する型です。また`s.%.c'は、`s.'で始まり`.c'で終わり、長さが5文字以上の全てのファイル名に一致する型です。(`%'に一致させるのは一文字以上でなければならない。) `%'に一致する部分の文字列を語幹(stem)といいます。

 型ルールの依存関係に`%'を使うと、ターゲットの`%'で一致した語幹と同じものを表すようになります。型ルールを適用するには、ターゲット型に当てはまるファイル名があり、さらに依存関係の型で(ターゲット一致の結果)命名されるファイルが存在しているか作成できるものでなければならず、それにも当てはまる場合そのファイルがターゲットの依存関係になります。

 だから次のようなルールでは…


%.o : %.c ; command ...

依存関係にある`n .c'というファイルが存在するか作成可能な場合に`n .c'から`n .o'というファイルを作成する方法を指定しています。

 型ルールで作成する全てのファイルに対して依存関係を添付したいような場合は`%'を使わない依存関係があっても構いません。そういう不変の依存関係が便利なこともありますから。

 型ルールを書く上で`%'を含む依存関係を書く必要はありませんし、実際のところ依存関係自体必要ではなく、そういうルールは一般的なワイルドカードのようになります。つまりターゲット型に一致するどのファイルについても作成する方法を提供するようになる、という事です。これについては最後の手段を定義するデフォルトルールの項を見て下さい。

 型ルールに一つ以上のターゲットを与えると、普通のルールとは違い「同じ依存関係とコマンドを適用するたくさんの異なるルール」のような振る舞いはしません。型ルールに複数のターゲットがある場合、makeは全てのターゲットについてそのコマンドがターゲット作成について重要なものだとわかっているので、全てのターゲットをまとめて一度にそのコマンドを使って作成します。あるターゲットに一致する型ルールを検索するとき、そのターゲットに一致するターゲット型を持つルールが他に持っている型ルールは付随扱いになります。つまりmakeは現在問題になっているファイルに対してのみコマンドと依存関係を与えるのですが、そのファイルのコマンドが実行される時に他のターゲットについてもそれ自身更新されている、という扱いになります。

 makefileにある他の型ルールについても書かれている順番が判断の順番になるため重要なものです。等しく適用できるルールが見つかった場合最初のものだけを採用し、ビルトインと重複する場合あなたが書いたものを優先させますが、ここで注意しておいてほしいのは、他の場所で明記しているか実際に存在している依存関係のルールは常に暗黙ルールの連鎖で構成される依存関係のルールより優先扱いになります。

型ルールの例

 ここにmakeで実際に前定義されている型ルールの例を示します。まず始めに`.c'`.o'ファイルにコンパイルするルールは、


%.o : %.c
        $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

…であり、`x .o'というファイルは全て`x .c'から作成が可能である、と定義するルールです。コマンドに`$@'`$<'という自動変数を使っているのはターゲットファイルの名前とソースファイルの名前をルールが適用されるそれぞれの箇所で読み替えさせるためです(自動変数の項を参照)。

 二つ目のビルトインルールは…


% :: RCS/%,v
        $(CO) $(COFLAGS) $<

…というもので、`x ,v'というファイルが`RCS'というサブディレクトリ内にあればそのxに相当する`x 'というファイルを作成できるルールを定義します。`%'がターゲットなのでこのルールは充当する依存関係ファイルが存在するという条件に合いさえすればどんなファイルにも適用されます。二重コロンで書かれたルールなのでこのルールが終着点(terminal)になり、そのためこのルールの依存関係が中間ファイルになることはありません(「何でも一致」型のルールの項を参照)。

 次の型ルールには二つのターゲットがあります。


%.tab.c %.tab.h: %.y
        bison -d $<

 このルールでは`bison -d x .y'というコマンドが`x .tab.c'`x .tab.h'の両方を作成するコマンドだと伝えます。`foo'というファイルが`parse.tab.o'`scan.o'に依存していて、`scan.o'というファイルは`parse.tab.h'というファイルに依存している、という場合、`parse.y'が変更されると`bison -d parse.y'というコマンドを一度だけ実行して`parse.tab.o'`scan.o'に対する処理を完了する事になります。(`foo'`parse.tab.o'`scan.o'や他の依存関係からリンクされる時に、おそらく`parse.tab.o'`parse.tab.c'から、`scan.o'`scan.c'から再コンパイルされ、以降適切に処理すべき事をやってくれるでしょう。)

自動変数

 `.c'ファイルから`.o'ファイルにコンパイルする型ルールを記述する際、正しいソースファイルに対して`cc'コマンドを実行するにはどう書けば良いのでしょうか? 暗黙ルールが実行される時々で名前が異なるため、コマンドに対しては名前を書けません。

 自動変数というmakeの特別な機能を使えばそれが可能になります。この変数ではルールが実行されるその都度、ルールのターゲットと依存関係に基づいて値を計算します。上の問題では`$@'をオブジェクトファイル名に、`$<'をソースファイル名に利用します。

 ここに自動変数の表を示します。

$@
 ルールのターゲットのファイル名。ターゲットがアーカイブメンバであるなら、`$@'はアーカイブファイルの名前になります。複数のターゲットを持つ型ルール(型ルール入門の項を参照)では、ルールのコマンドを実行したターゲットの名前が`$@'に入る。
$%
 ターゲットがアーカイブメンバだった時のターゲットメンバ名。これについてはアーカイブファイル更新にmakeを利用するの項を見て下さい。例えば`foo.a(bar.o)'がターゲットの場合、`$%'`bar.o'になり、`$@'`foo.a'になります。ターゲットがアーカイブメンバではない場合`$%'は空っぽになります。
$<
 最初の依存関係の名前。ターゲットが暗黙のルールからコマンドを受け取ると、暗黙ルールで最初の依存関係が追加されることになります(暗黙ルールの利用の項を参照)。
$?
 ターゲットより新しい全ての依存関係の名前のそれぞれの間にスペースを挟んで並べたもの。アーカイブメンバになっている依存関係については利用されるメンバ名のみが入る(アーカイブファイル更新にmakeを利用するの項を参照)。
$^
 全ての依存関係の名前のそれぞれの間にスペースを挟んで並べたもの。アーカイブメンバになっている依存関係については利用されるメンバ名のみが入る(アーカイブファイル更新にmakeを利用するの項を参照)。依存するファイルのそれぞれについて、依存関係として何度ファイルが並べられても一つのターゲットにつき一つだけの依存関係になります。だから、あるターゲットに対して一度以上以上依存関係として挙げても$^の値にはその名前は一つしかコピーされません。
$+
 `$^'と似ていますが、一度以上依存関係に並べられたものはmakefileで並んでいる順番で複製されます。これはライブラリファイル名を特定の順番で繰り返す事に意味がある場合の、リンクするコマンドを使うときに便利です。
$*
 暗黙のルールで一致した語幹(どんな型が一致するか)。ターゲット型が`a.%.b'で当てはまったターゲットが`dir/a.foo.b'の場合、語幹は`dir/foo'になります。語幹というのは関係するファイル名を構築するのに便利です。  静的な型ルールでは語幹はファイル名のうちターゲット型の`%'に一致している部分になります。 (暗黙のルールに対して)明示ルールでは語幹は存在せず、この方法では`$*'が不定になります。そのため代わりに、ターゲット名の最後が認識できるサフィックス(接尾語。古いタイプのサフィクスルールの項を参照)だった場合、`$*'にはターゲット名からサフィックスを引いたものがセットされます。例えばターゲット名が`foo.c'なら`.c'がサフィックスになるので`$*'には`foo'が入ります。GNU makeがこんな奇妙な動作をするのは他のmake製品との互換性のためで、普通は暗黙ルールと静的な型ルールだけで`$*'を使うべきです。有効なサフィックスで終わらないターゲットを持つ明示ルールでは`$*'が空っぽになります。

 変更のあった依存関係だけに作用させたい場合は明示ルールでも`$?'が便利です。例えば`lib'という名前のアーカイブにいくつかのオブジェクトファイルの複製版を格納させたいとすると、次のルールを使えば変更があったファイルだけをアーカイブにコピーしてくれます。


lib: foo.o bar.o lose.o win.o
        ar r lib $?

 上で列挙した変数群のうち4つは一つのファイル名を値とするもので、2つはファイル名のリストを値としています。これら6つの変数にはファイルのディレクトリ名だけやディレクトリ内のファイル名だけを取得する変形版(バリアント)が存在します。それぞれの変数名に`D'`F'を付加したものが変形版の変数名になります。実はGNU makeではこれらの変形版というのはdirnotdirという関数(ファイル名のための関数の項を参照)を使えば似たような効果を得られるのでやや時代遅れなのですが、ここで注意。変形版にする`F'を使った場合はdir関数の出力で現れる全部の最後のスラッシュが省略される事を覚えておいて下さい。ここに変形版の表を示します。

`$(@D)'
 ターゲットファイル名のディレクトリ部分の末尾のスラッシュを除去したもの。`$@'の値が`dir/foo.o'なら`$(@D)'`dir'になります。`$@'にスラッシュが含まれないとこの変数の値は`.'になってしまいます。
`$(@F)'
 ターゲットファイル名のディレクトリ内ファイル部分。`$@'の値が`dir/foo.o'なら`$(@F)'`foo.o'になります。`$(@F)'`$(notdir $@)'と同等です。
`$(*D)'
`$(*F)'
 語幹のディレクトリ部分とディレクトリ内ファイル部分で、先の例では`dir'`foo'になる。
`$(%D)'
`$(%F)'
 ターゲットアーカイブメンバ名のディレクトリ部分とディレクトリ内ファイル部分。`archive (member)'という形式のアーカイブメンバがターゲットの時のみ用を成し、member にディレクトリ名が含まれる場合のみ有用です。(ターゲットとしてのアーカイブメンバーの項を見て下さい。)
`$(<D)'
`$(<F)'
 最初の依存関係のディレクトリ部分とディレクトリ内ファイル部分。
`$(^D)'
`$(^F)'
 全依存関係のディレクトリ部分とディレクトリ内ファイル部分の各リスト。
`$(?D)'
`$(?F)'
 依存関係のうちターゲットより新しいもの全てのディレクトリ部分とディレクトリ内ファイル部分の各リスト。

注意:自動変数について述べる場合、objectsCFLAGSのような普通の変数の事を書くように「<という変数」と書くのではなくて「`$<'の値」としたほうが自然に感じると思うので特別なケースとしてこういう特別な慣習に従っています。ですがくれぐれも`$(CFLAGS)'CFLAGSという名前の変数を参照するのと全く同じように`$<'<という名前の変数を参照しているのだ、というような深い意味があるとは考えないで下さい。`$<'の代わりに`$(<)'とするのは構いません。

どんな型が一致するか

 ターゲット型はプリフィックス(接頭語)とサフィックス(接尾語)の間に`%'を挟んだもので構成され、両端が空っぽであっても構いません。型が一致するのは対象のファイル名が型のプリフィックスで始まり、同サフィックスで終わり、かつその二つが重複しない場合です。プリフィックスとサフィックスの間の文字列は語幹(stem)といいます。だから`%.o'という型に`test.o'というファイル名が引っかかった時は`test'が語幹になります。型ルールの依存関係は語幹が`%'という文字に代入されて実際のファイル名になります。つまり先の例で依存関係の一つが`%.c'と書かれていた場合は`test.c'が展開されます。

 ターゲット型にスラッシュが含まれなければ(というか普通は含まれませんが)、ファイル名のディレクトリ名部分はターゲットのプリフィックスとサフィックスの比較が行われる前に削除されます。そのディレクトリ名は後で末尾のスラッシュと一緒に、ファイル名をターゲット型に比較する作業が終わってから型ルールの依存関係の型から生成されたファイル名と依存関係にもとからあるファイル名に付加されます。利用する暗黙のルールを検索する際だけはディレクトリ名が無視されますが、ルールを使用する時に無視されるわけではありません。つまり`e%t'`src/eat'というファイル名に`src/a'という語幹で一致します。依存関係がファイル名に変わる時には語幹のディレクトリ部分は一番前に付加されて、一方残りの部分は`%'に代入します。`src/a'という語幹を`c%r'という依存関係の型に充てる場合はファイル名は`src/car'になります。

「何でも一致」型のルール

 型ルールのターゲットがただ`%'だけの場合はファイル名が何であろうと一致するため、こういうルールを「なんでも一致(match-anything)」ルールと呼んでいます。こういうルールはとても便利ですがターゲットとして並んでいるファイルも依存関係として並んでいるファイルもとにかく全てのファイルについてこのルールが当てはまるか判断しなければならないため、makeの処理時間が増える事になってしまいます。

 `foo.c'について書かれたmakefileを想定すると、このターゲットに対して`foo.c.o'というオブジェクトファイルからリンクして作成できるか、`foo.c.c'から一気にCコンパイルとリンクができないか、`foo.c.p'からPascalコンパイルとリンクができないか、などなどmakeはたくさんの可能性を考慮しなければならなくなるでしょう。

 `foo.c'はCソースファイルであって実行可能ファイルではないのでこういう可能性は全く馬鹿げたものだということはわかり切っています。makeがこれらの可能性を調べても`foo.c.o'やら`foo.c.p'というファイルが存在しないはずなので最終的にその可能性を拒否することになるのですが、その可能性が非常に多数であるためそれをmakeが判断しなければならないと実行速度がかなり遅くなってしまいます。

 速度向上のため、makeに「何でも一致」ルールを判断させる上でさまざまな事を強制させるようにしました。適用され得る強制は毛色の異なるものが二つ存在し、「何でも一致」ルールを定義する時は必ずそのルールに対してどちらか一つを選ばなければなりません。

 一つ目の選択は「何でも一致」ルールを二重コロンで定義して終点(terminal)にしてしまう事です。ルールがそれで終点なら実在しない依存関係には適用されなくなり、別の暗黙ルールから作成できる依存関係には不適になります。言い換えればターミナル(終点)ルールではそれ以上の連鎖が許されません。

 例えばRCSとSCCSファイルからソースを取り出すというビルトインの暗黙ルールは終点なので、結果として`foo.c,v'が存在しなければmakeはそれが中間ファイルとして作成しようとせず、そのため`foo.c,v.o'`RCS/SCCS/s.foo.c,v'があっても関係ありません。RCSとSCCSは一般的に他のファイルからは作成されるべきではない最終的なソースファイルなので、makeはそれらを更新する方法を探さないようにして時間を節約できるのです。

 「何でも一致」ルールを終点というしるしをつけなかった場合、それが終点ではなくなります。終点ではない「なんでも一致」ルールでは特定の形式のデータをさすファイル名は適用できません。特定な形式のデータをさすファイル名、とは「何でも一致」ではない暗黙ルールのターゲットに一致するファイル名の事で、そういうファイルには適用できません。

 例えば、`foo.c'というファイル名は(Yaccを実行するルールである)`%.c : %.y'という型ルールのターゲットに一致します。(`foo.y'というファイルがある場合にのみ実行される)このルールが実際に適用できるかという事にかかわらず、ターゲットが一致するという事実だけで`foo.c'というファイルは終点ではない「何でも一致」ルールでは判断対象にならなくなります。だからmake`foo.c'`foo.c.o'`foo.c.c'`foo.c.p'などから作成できる実行ファイルかという事を判断しなくて済むのです。

 終点ではない「何でも一致」ルールでこの強制をさせるのは(実行可能ファイルのような)特定の形式のデータを含むファイルを作成するのには利用し、かつ(Cソースファイルのような)別の特定の形式のデータだと認識できるサフィックス(接尾語)を持つファイル名のファイル判別させる、という意図からです。

 終点ではない「なんでも一致」ルールで判断対象とさせたくない種類のファイル名をただ識別させたいがために存在するダミー用の特別なビルトインの型ルールもあります。ダミーのルールでは依存関係もコマンドもなく、他の用途に際しては完全に無視されます。例えば次のビルトイン暗黙ルール…


%.p :

…は、`foo.p'のようなPascalソースファイルが特定のターゲット型であり、`foo.p.o'`foo.p.c'を探す手間を省くために存在します。

 `%.p'に対するようなダミーの型ルールは、サフィックスルール(古いタイプのサフィクスルールの項を参照)で使われる有効なサフィックス全てに対して作成されています。

暗黙のルールをキャンセルする

 ビルトインの暗黙ルール(または自分で定義したルール)を、同じターゲットと依存関係でコマンドだけ違う新しい型ルールを定義して上書きすることができます。新しいルールが定義されると暗黙のルールは置き換えられることになり、暗黙のルールの中のどの位置に新しいルールが入るのか、というのはどこに新しいルールを書いたかで決まります。

 ビルトインの暗黙ルールをキャンセルするには同じターゲットと依存関係を持ち、コマンドが全くない型ルールを定義して下さい。例えば次のものはアセンブラを実行させるルールをキャンセルしてくれるでしょう。


%.o : %.s

最後の手段を定義するデフォルトルール

 最後の手段を示す暗黙のルールを定義するには、終点になる「なんでも一致」ルール(「何でも一致」型のルールの項を参照)を依存関係なしで書きます。他の型ルールとの唯一の相違点は、どんなターゲットにも一致する、という事だけですが、この相違点のためにこのルールのコマンドは、コマンドを持たないルールだが暗黙のルールに適用されないターゲットと依存関係の全てについて利用されるものになります。

 例えばmakefileを実行する際ソースファイルがちゃんと中身があるかという事はどうでもよく存在していれば良いなら次のようにできます。


%::
        touch $@

こうすると(依存関係として)必要とされる全てのソースファイルを自動的に作成します。

 そうする代わりに「全くルールのないターゲットだけでなくコマンドを指定しないターゲットでも使うコマンド」を、.DEFAULTというターゲットに対するルールで書いて定義する事もできます。このルールのコマンドは明示ルールでも暗黙ルールでも全くターゲットとして出て来ない依存関係全部に対して利用します。記述しない標準状態では.DEFAULTルールは全く存在しません。

 次に示す通りコマンドや依存関係なしで.DEFAULTを使うと…


.DEFAULT:

.DEFAULTでそれ以前に保管されているコマンドがクリアされ、makeの動作は.DEFAULTを全く定義しなかったのと同様になります。

あるターゲットでコマンドを実行させたくはないが、「なんでも一致」の型ルールや.DEFAULTのコマンドもターゲットに取得させたくないという場合、空のコマンドをそのターゲットに与えればそのようにできます(空のコマンドの利用の項を参照)。

 別のmakefileの一部を上書きするのに最後の手段を定義するルールを使う事もできます。これについては別のMakefileを部分的に無効にするの項を見てください。

古いタイプのサフィクスルール(Suffix Rules)

 makeで暗黙のルールを定義する古い手法としてサフィックスルールというものがありますが、型ルールのほうが一般的で明瞭なので、サフィックスルールは時代遅れとなりました。GNU makeでは古いmakefileとの互換性のためにサフィックスルールをサポートしています。サフィックスルールはダブルサフィックスシングルサフィックスという二種類の役目があります。

 ターゲットサフィックスとソースサフィックスという一対のサフィックスで定義されたのがダブルサフィックスルールで、ターゲットサフィックスで終わる名前のファイルすべてに一致して、これに対応する暗黙の依存関係はそのファイル名のターゲットサフィックス部分をソースサフィックスに置換した名前のファイルになります。ターゲットサフィックスとソースサフィックスが`.o'`.c'である二重サフィックスルールは`%.o : %.c'という型ルールと同等です。

 ソースサフィックスひとつで定義されたのがシングルサフィックスルールで、こちらはどんなファイル名にも一致して対応する暗黙の依存関係の名前はそれにソースサフィックスを添えたものになります。ソースサフィックスが`.c'のシングルサフィックスルールは`% : %.c'という型ルールと同等です。

 サフィックスルール定義は各ルールのターゲットを既知のサフィックスの定義済みリストと比較するという方法でmakeに認識されます。あるルールのターゲットが既知のサフィックスであれば、そのルールはmakeにシングルサフィックスルールとして扱われます。また既知のサフィックス二つがターゲットで一続きになっているなら、そのルールはダブルサフィックスになります。

 たとえば`.c'`.o'は両方とも既知のサフィックスのリストにデフォルトで載っているため、`.c.o'というターゲットのルールを定義すれば、makeではこれを`.c'というソースサフィックスと`.o'というターゲットサフィックスを持つダブルサフィックスルールとして受け取ります。Cソースファイルをコンパイルするルールを定義する古い手法を次に示します。


.c.o:
        $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

 サフィックスルール自身に依存関係を与える事はできません。そうしてしまうと、サフィックスルールとして扱われるのではなく、おかしな名前のファイルとして扱うことになります。だから、次のルールは…


.c.o: foo.h
        $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

`foo.h'という依存関係ファイルから`.c.o'というファイルを作成する方法を指示するようになって、次のような型ルールとはかけ離れたものになってしまいます。


%.o: %.c foo.h
        $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

これは`.c'ファイルから`.o'ファイルを作成する方法を支持するもので、`.o'はすべてこの型ルールを用いて作成し、どれも`foo.h'に依存している、と指示します。

 その上、コマンドのないサフィックスルールは無意味で、コマンドのない型ルールのようにその前のルールを削除してはくれず(暗黙のルールをキャンセルするの項を参照)、ただ単にデータベース中のターゲットとしてひとつのサフィックスあるいは一対のサフィックスが一続きになったものを加えるだけです。

 .SUFFIXESという特別なターゲットの依存関係になっている名前が既知のサフィックスになるだけなので、次のように依存関係を増やしてくれる.SUFFIXESに対するルールを書けば独自のサフィックスを追加できます。


.SUFFIXES: .hack .win

…とすると、`.hack'`.win'をサフィックスのリストの最後に追加します。

 追加する代わりにデフォルトの既知のサフィックスを削除したいなら、依存関係なしで.SUFFIXESに対するルールを書くと特別な動作として.SUFFIXESの依存関係をすべて消去します。こうしておけば所望のサフィックスを追加するルールを書く事ができるようになります。たとえば、


.SUFFIXES:            # デフォルトサフィックスの削除する
.SUFFIXES: .c .o .h   # 好きなサフィックスリストを定義する

 `-r'フラグか`--no-builtin-rules'フラグかを使えばサフィックスのデフォルトリストを空っぽにできます。

 makeはmakefileを読み込む前にサフィックスのデフォルトリストとしてSUFFIXESという変数を定義します。このサフィックスのリストを変更するのは.SUFFIXESという特別なターゲットに対するルールで変更しますが、この変数を改変する、というわけではありません。

暗黙ルールの検索アルゴリズム

 ここではmakeというプロシージャが如何にしてt というターゲットに対する暗黙のルールの検索を行うかを示します。コマンドのない二重コロンルールと、コマンドを持たない普通のルールの各ターゲットと、ルールのターゲットになっていない依存関係のそれぞれにこのプロシージャは従い、暗黙ルールの連鎖の検索でルールにある依存関係にも再帰的に従います。

 サフィックスルールはmakefileが読み込まれた時に一度だけ型ルールと同じになるように変換されるので、このアルゴリズムではサフィックスルールについて述べません。

 `archive(member)'という形式のアーカイブメンバーターゲットに対しては以下のアルゴリズムは二度実行されます。つまり、一度目はt という完全なターゲット名に利用し、二度目は第一の実行でルールが見つからない場合に`(member)'t というターゲットとして利用します。

  1. td というディレクトリ部分とn という残りの部分に分離します。たとえばt`src/foo.o'なら、d`src/'で、n`foo.o'になります。
  2. 全ての型ルールのリストを、tn に一致するターゲットのひとつにしてしまいます。ターゲットの型にスラッシュが含まれればt に対して一致するものとし、そうでなければn に対して一致するものとします。
  3. リスト中のどのルールも「何でも一致」ルールではなかった場合はリストから終点ではない「何でも一致」ルールを全部削除します。
  4. コマンドのないルールは全部リストから削除します。
  5. リスト中の各型ルールに対して…
    1. tn に一致したターゲット型の`%'の部分(空っぽではない)としてs という語幹を見つける。
    2. `%'の部分をs に置き換えて依存関係の名前を作成する。ターゲット型にスラッシュが含まれなければd を各依存関係の名前の前につける。
    3. 全ての依存関係が存在しているか、または存在し得るかをテストする。(ファイル名がmakefile内でターゲットか明示的な依存関係として書かれている場合に「存在し得る」と考えます。) 全ての依存関係が存在するか存在し得るかする、または依存関係が全くないなら、このルールが適用されます。
  6. 型ルールが全然見つからなければ、各型ルールに対してさらに頑張って次の事を試してみます。
    1. ルールが終点(terminal)ならそれを無視して次のルールに移る。
    2. 前に書いたとおりに依存関係の名前を作成する。
    3. 全部の依存関係が存在する、または存在し得るかをテストする。
    4. 存在しない依存関係のそれぞれに対し、このアルゴリズムに再帰的に従わせて暗黙ルールで依存関係を作ることができるのかを調べる。
    5. 全部の依存関係が存在するか、暗黙のルールで作成できるので存在し得るという場合にはこのルールが適用される。
  7. どの暗黙ルールも適用されないルールには.DEFAULTに対するルールが適用される。この場合はt.DEFAULTにあるのと全く同じコマンドを与える。もしくはt にはコマンドがないことになる。

 一旦見つかったものをルールに適用してしまえば、tn に一致するターゲット型とは別に、ルールのターゲット型それぞれに対して型にある`%'の部分がs に置換されて、その結果のファイル名はt というターゲットファイルを更新するコマンドが実行されるまでは保管されます。コマンド実行終了後、保管されていたファイル名はどれも、更新されたファイルやt というファイルと同じ更新ステータスを持つファイルのデータベースに格納されます。

 型ルールのコマンドがt に対して実行される時、ターゲットと依存関係に相当する自動変数がセットされます。これについては自動変数の項を見てください。


最初,,,最後のページ,目次 に移動.