[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10. 暗黙のルールの使用

ターゲットファイルの再構成の標準的なある方法がしばしば用いられます。たとえば、 オブジェクトファイルを作成する習慣的な方法は、ccで用いられる Cコンパイラによるソースファイルから作成する方法です。

暗黙のルールmakeに対して習慣的なテックニックの使用を伝えるため、 それを用いる際には詳細に指定をする必要がありません。たとえば、Cのコンパイル には暗黙のルールがあり、ファイル名が暗黙のルールを実行するものを決定します。 また、Cのコンパイルでは一般的に‘.c’ファイルを使って‘.o’ ファイルを作成します。したがって、makeはCのコンパイルにおいては ファイル名の最後を見るという暗黙のルールを適用しているのです。

暗黙のルールの連鎖は順序に適用されます。たとえば、makeは‘.y’ ファイルから‘.c’ファイルを経て‘.o’ファイルを再構成します。

組み込まれた暗黙のルールはコマンドのなかでいくつかの変数を使用します。 そのためその変数の値の変更によって暗黙のルールの動作を変更することが できます。

パターンルールの記述によって独自の暗黙のルールを定義することができます。

サフィックスルールは、暗黙のルールを定義する制限のある方法です。 パターンルールは、より汎用的で明確ですが、サフィックスルールは 互換性のために残されています。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.1 暗黙のルールの使用

ターゲットファイルのアップデートに関する習慣的な方法をmakeが みつけるようにするには、ユーザー自身がコマンドを指定するのを控えることです。 それは、コマンド行を用いずにルールを記述したり、何もルールを 記述しないことです。そうすることによって、存在するソースファイルに 基づいてどの暗黙のルールを適用するかといった動作をmakeが行ないます。

たとえば、このようなmakefileがあるとします。

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

foo.o’に言及してもそれにルールを与えていないため、makeが 自動的にアップデートの仕方を伝える暗黙のルールを探します。これは実際に ‘foo.o’が存在してもしなくても起こります。

暗黙のルールがみつかる場合、コマンドと1つあるいは複数の必要条件 (ソースファイル)を提供できます。ヘッダファイルのような暗黙のルールが 提供できない特定の必要条件が必要な場合は、コマンド行なしで‘foo.o’に 対するルールを記述したいはずです。

個々の暗黙のルールはターゲットパターンと必要条件のパターンを持ちます。また、 同じターゲットパターンを持つ多くの暗黙のルールがあります。たとえば、 多くのルールは‘.o’ファイルを作成しますが、1つはCコンパイラで ‘.c’から作成され、別のものはPascalコンパイラによって‘.p’から 作成されたりします。実際に適用されるルールは、必要条件が存在するか あるいは作成可能であるものとなります。したがって、ファイル‘foo.c’が ある場合、makeはCコンパイラを実行し、反対にファイル‘.p’が ある場合は、Pascalコンパイラを実行するといったことになります。

もちろん、makefileを記述する際、makeがどの暗黙のルールを使用するかを 知っていて、どの必要条件のファイルが存在するかを知っているため、 どれが適用されるかも知っています。 あらかじめ定義されている暗黙のルールのすべてのカタログについては、 See section 暗黙のルールのカタログ.。

上記の場合、必要条件が存在するか作成可能の場合に暗黙のルールが適用されると 書きましたが、ここで作成可能とは、ターゲットあるいは必要条件として明確に makefileで言及されている場合と、どのように作成するかが再帰的に発見される 暗黙のルールがある場合のことです。暗黙の必要条件が別の暗黙のルールの 結果である場合、連鎖が起きていると表現します。 See section 暗黙のルールの連鎖.。

一般的に、makeは個々のターゲットに対して暗黙のルールをサーチし、 コマンドを持たない個々のダブルコロンルールに対しても暗黙のルールを サーチします。必要条件として言及されているファイルは何も指定しない ルールを持つターゲットとしてみなされ、暗黙のルールのサーチがそれに 対して行なわれます。 どのようにサーチが行われるかの詳細については、 See section 暗黙のルールのサーチアルゴリズム.。

明示的な必要条件は暗黙のルールのサーチに対して影響を与えません。たとえば、 この明示的なルールの例です。

 
foo.o: foo.p

foo.p’の必要条件は必ずしもmakeがオブジェクトファイルを 作成する暗黙のルール、すなわち‘.p’ファイルのPascalのソースファイル から‘.o’ファイルを作成するルールを必要としているわけではありません。 たとえば、‘foo.c’もまた存在する場合、暗黙のルールは オブジェクトファイルをCのソースファイルから作成しようとします。 その理由は、事前に定義されたリストのなかではPascalルールよりも先に 現われるからです (see section 暗黙のルールのカタログ.)。

コマンドのないターゲットに対して暗黙のルールが使用されないように望む場合、 セミコロンを使用して空のコマンドをそのターゲットに与えます (see section 空のコマンドの使用.)。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.2 暗黙のルールのカタログ

ここに、事前に定義された暗黙のルールのカタログがあり、それらはmakefileが 明確にオーバーライドするか無効にされない限りつねに利用可能です。 暗黙のルールのキャンセル、もしくはオーバーライドについては、 See section 暗黙のルールのキャンセル.。 ‘-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 です。以下で説明される暗黙のルールのすべては、その必要条件がサフィックスの どれか1つを持っています。サフィックスリストを修正する場合、事前に 定義された有効なサフィックスルールだけが、指定したリストにある1つ あるいは2つのサフィックスによって名前をつけられたルールになります。 リストにないサフィックスのルールは無効になります。 すべてのサフィックスのルールの詳細は、 See section 古いスタイルのサフィックスルール.。

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’はFortranコンパイラの実行によって、‘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のコンバートを行なうプリプロセッサ あるいはプリプロセッサを通すFortranプログラムを正しいFortranプログラムに 変換するだけです。使用される正確なコマンドは以下のようになります。

.F

$(FC) -F $(CPPFLAGS) $(FFLAGS)’.

.r

$(FC) -F $(FFLAGS) $(RFLAGS)’.

Modula-2プログラムのコンパイル

n.sym’は、コマンド‘$(M2C) $(M2FLAGS) $(DEFFLAGS)’によって ‘n.def’から作成されます。‘n.o’は‘n.mod’か ら作成されますが、そのコマンドの書式は、 ‘$(M2C) $(M2FLAGS) $(MODFLAGS)’となります。

アセンブラプログラムのアセンブリとプリプロセッシング

n.o’は、‘n.s’からアセンブラasを実行することで 自動的に作成されます。正確なコマンドは‘$(AS) $(ASFLAGS)’です。

n.s’は、‘n.S’からCのプリプロセッサcppを 実行することで自動的に作成されます。 正確なコマンドは‘$(CPP) $(CPPFLAGS)’です。

単一オブジェクトファイルのリンク

n’は、‘n.o’からリンカ(通常はld)の実行によって Cコンパイラを経由して自動的に作成されます。正確なコマンドは ‘$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)’です。

このルールは、1つのソースファイルから簡単なプログラムのためにあることを します。それは、複数のオブジェクトファイル(おそらくほかのいろいろな ソースファイルからくる)がある場合、そのうちの1つは実行ファイル名と マッチするということです。したがって、

 
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)’は‘.s’ ファイルのアセンブルに使用されます)。この場合、‘.o’ オブジェクトファイルが中間ファイルとして使用されます。しかし、 コンパイルとリンクを1ステップで行なうよりも速く実行できます。

CプログラムのためのYacc

n.c’は、‘n.y’からYaccをコマンド‘$(YACC) $(YFLAGS)’ を実行することで自動的に作成されます。

CプログラムのためのLex

n.c’は、‘n.l’から、Lexを実行することで自動的に 作成されます。実際のコマンドは、‘$(LEX) $(LFLAGS)’です。

RatforプログラムのためのLex

n.r’は、‘n.l’から、Lexを実行することで自動的に 作成されます。実際のコマンドは、‘$(LEX) $(LFLAGS)’です。

CあるいはRatforのコードを作ることにかかわらず、Lexファイルに対して同じ サフィックス‘.l’を使用する習慣は、ある場合においてどちらの言語を 使うかどうかをmakeが決定するのを困難にします。‘.l’ファイルから オブジェクトファイルを作る際にmakeが呼び出された場合、どちらの コンパイラを使用するか決めなければなりませんが、普通はより一般的な Cコンパイラです。Ratforを使用する場合は、makefileのなかに‘n.r’への 言及を置き、makeがそれを認識できるようにしなければなりません。 あるいは排他的にCを使用せずにRatforを使用する場合には、暗黙のルールの サフィックスのリストから‘.c’を取り除いてください。

 
.SUFFIXES:
.SUFFIXES: .o .r .f .l …
C、Yacc、またはLexプログラムから生成されるLintライブラリ

n.ln’は、‘n.c’からlintを実行することで自動的に 作成されます。正確なコマンドは‘$(LINT) $(LINTFLAGS) $(CPPFLAGS) -i’ です。同じコマンドがCのコードを作成される際に‘n.y’あるいは ‘n.l’として使用されます。

TeXとWeb

n.dvi’は、‘n.tex’からコマンド‘$(TEX)’によって 作成されます。また‘n.tex’は、‘n.web’から‘$(WEAVE)’ によって作成されます。あるいは‘n.w’(存在しているか作成可能で あれば)から‘$(CWEAVE)’によって作成されます。また、‘n.p’は、 ‘n.web’から‘$(TANGLE)’で、‘n.c’は、 ‘n.w’(存在しているか作成可能であれば‘n.ch’から)から ‘$(CTANGLE)’で作成されます。

TexinfoとInfo

n.dvi’は、‘n.texinfo’、‘n.texi’あるいは ‘n.txinfo’からコマンド‘$(TEXI2DVI) $(TEXI2DVI_FLAGS)’ によって作成されます。また、‘n.info’は、‘n.texinfo’、 ‘n.texi’あるいは‘n.txinfo’からコマンド ‘$(MAKEINFO) $(MAKEINFO_FLAGS)’によって作成されます。

RCS

どのようなファイル‘n’も必要である場合には、‘n,v’ あるいは‘RCS/n,v’のどちらかの名前のRCSファイルから展開されます。 正確なコマンドは、‘$(CO) $(COFLAGS)’です。ただし、RCSファイルが 新しいものであっても、すでに存在している場合には‘n’は 展開されません。RCSに対するルールは最終的なもので (see section 何にでもマッチするパターンルール.)、ほかの ソースからRCSファイルが生成されることはなく実際に存在していなければなりません。

SCCS

どのようなファイル‘n’も必要である場合には、‘s.n’ あるいは‘SCCS/s.n’のどちらかの名前のSCCSファイルから展開されます。 正確なコマンドは、‘$(GET) $(GFLAGS)’です。SCCSに対するルールは 最終的なもので (see section 何にでもマッチするパターンルール.)、ほかの ソースからRCSファイルが生成されることはなく実際に存在していなければなりません。

ファイル‘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 (see section 必要条件のためのディレクトリサーチ.)を 使用する際は、ソースファイルの場所と異なる場合に正しいファイルに出力が されるように‘-o’オプションを使用する必要があります。しかし、 コンパイラによってはオブジェクトファイルに対しての‘-o’スイッチを 受け入れない場合があります。そのようなシステムの場合でVPATHを 使用する場合は、コンパイルが誤った場所に出力をする場合があります。 このような問題を解決するには、OUTPUT_OPTIONに値 ‘; mv $*.o $@’を与えます。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.3 暗黙のルールで使用される変数

組み込み済みの暗黙のルールにおけるコマンドはある事前に定義された変数の 自由度の高い使用ができます。makeに対する引数や、ルールを再定義すること なしにどのように暗黙のルールが働くかを変更する環境においてmakefileのなかで 変数を変更することができます。その場合、‘-R’あるいは ‘--no-builtin-variables’オプションによって、暗黙のルールで用いられる すべての変数を無効にすることができます。

たとえば、Cのソースファイルをコンパイルする場合の実際のコマンドは、 ‘$(CC) -c $(CFLAGS) $(CPPFLAGS)’です。また、コマンド‘cc -c’ 使用される変数のデフォルトの値は‘cc’だけです。‘CC’を‘ncc’と 再定義することによって、暗黙のルールで行なわれるすべてのCのコンパイルに対して ‘ncc’を起動することができます。また、‘CFLAGS’を‘-g’ であるように再定義すると、‘-g’オプションを個々のコンパイルに 渡すことができます。Cのコンパイルを行なうすべての暗黙のルールは プログラム名を取得するために‘$(CC)’を使用し、コンパイラに 与えられる引数における‘$(CFLAGS)’をすべてインクルードします。

暗黙のルールで用いられる変数は2つのクラスに分けられます。1つはプログラムの 名前(CCのような)、もう1つはプログラムに対する引数を含むもの (CFLAGS)です(ここでプログラム名という場合にはコマンドの引数を含む 場合もあります。しかし名前は必ず実行プログラムの名前で始まります)。変数が、 1つよりも多い引数を含む場合にはスペースで区切ります。

ここに、組み込み済みのルールによるプログラム名として使用される変数の一覧を 示します。

AR

アーカイブのメインテナンスプログラム;デフォルトでは、‘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あるいはRatforに変換するプログラム;デフォルトでは、 ‘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

アーカイブメインテナンスプログラムに与えるフラグ;デフォルトでは、‘rv’。

ASFLAGS

アセンブラに与えるフラグ(‘.s’あるいは‘.S’ファイルについて 明示的に呼び出される場合)。

CFLAGS

Cコンパイラに与えるフラグ。

CXXFLAGS

C++コンパイラに与えるフラグ。

COFLAGS

RCS coプログラムに与えるフラグ。

CPPFLAGS

Cのプリプロセッサとプログラムに与えるフラグ(CとFortranコンパイラ)。

FFLAGS

Fortranコンパイラに与えるフラグ。

GFLAGS

SCCS getプログラムに与えるフラグ。

LDFLAGS

リンカ‘ld’を呼び出すときにコンパイラに与えるフラグ。

LFLAGS

Lexに与えるフラグ。

PFLAGS

Pascalコンパイラに与えるフラグ。

RFLAGS

Ratforプログラムに対するFortranコンパイラに与えるフラグ。

YFLAGS

Yaccに与えるフラグ。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.4 暗黙のルールの連鎖

ファイルは暗黙のルールのシーケンスによって作成される場合があります。 たとえば、ファイル‘n.o’は、最初にYacc、次にccを 実行することによって‘n.y’から作成されます。このような シーケンスを連鎖と呼びます。

ファイル‘n.c’が存在したり、makefileで言及されている場合、 特別なサーチは必要ではありません。makeはオブジェクトファイルが Cのコンパイルによって‘n.c’から作成されることをみつけます。 その後、‘n.c’の作成法を考慮し、Yaccの実行のルールが用いられます。 最終的に、‘n.c’と‘n.o’の両方がアップデートされます。

しかしながら、‘n.c’が存在せず、言及もされない場合でも makeは‘n.o’と‘n.y’のあいだの失われた関係を 想像することができます。この場合は、‘n.c’が中間ファイルと 呼ばれます。いったんmake中間ファイルを使用することを 決定した場合、それはmakefileのなかで言及されているかのごとく、 作成方法を伝える暗黙のルールに沿ってデータベースに入力されます。

中間ファイルは、ほかのすべてのファイルとまったく同じようにルールに基づいて 再作成されます。しかし、2つの事柄において中間ファイルの扱いは異なります。

1番目の違いは、中間ファイルが存在しない場合に起きる事柄です。普通の ファイルbが存在しない場合で、makeがターゲットはbに 依存しているとみなした場合は、bが作成されそれによってターゲットの アップデートが行なわれます。しかし、bが中間ファイルの場合は、 そのままにしておきます。bのいくつかの必要条件がターゲットより 新しいかターゲットをアップデートするなんらかの理由がない限り、bや あるいは最終のターゲットのアップデートは行ないません。

2番目の違いは、何かほかのものをアップデートするためにmakebを 作成する場合、必要がなくなったあとにbを削除することです。 したがって、make以前に存在しない中間ファイルはmakeのあとに 存在しないのです。makeはどのファイルが削除されたかを示すコマンド ‘rm -f’によってその削除を知らせます。

通常、ターゲットや必要条件としてmakefileのなかで言及されている場合にはある ファイルが中間ファイルになることはできません。しかし、特別なターゲットである .INTERMEDIATEの必要条件としてリストされることによって明示的に 中間ファイルとしてマークすることができます。ほかの方法で明示的に 言及されている場合でも、この方法は有効です。

中間ファイルを二次的なファイルとしてマークすることで、自動的な削除を 回避することができます。これを行なうためには、特別なターゲット .SECONDARYの必要条件としてリストすることです。ファイルが 二次的である場合、makeはすでに存在しないためファイルを 作成することはありませんが、自動的に削除することもありません。 ファイルを二次的であるとマークすることは、中間ファイルとしてマークする ことでもあります。

特別なターゲット.PRECIOUSの必要条件として、ファイル名と ターゲットパターンがマッチした暗黙のルールによって作られた中間ファイルを 保存する目的で、暗黙のルール(たとえば‘%.o’のような)の ターゲットパターンをリストすることができます。 makeの中断あるいはkill.を参照してください。

連鎖は2つよりも多い暗黙のルールを含んでいます。たとえば、RCS、Yacc、cc の実行によって、‘RCS/foo.y,v’から‘foo’を作成することができます。 そして、‘foo.y’と‘foo.c’はどちらも中間ファイルで、最後には 削除されます。

単一の暗黙のルールは、連鎖のなかで一度しか現われることができません。 この意味は、makeによってリンカを2度実行して‘foo.o.o’から ‘foo’を作成するような馬鹿なことは起きないことを考慮しているのです。 この強制的な動作は暗黙のルールの連鎖において、サーチの無限ループを 避けることになっています。

ルールの連鎖の違った形で処理される特別なケースを最適化するために、いくつかの 特別な暗黙のルールがあります。たとえば、‘foo.c’から‘foo’を 作成するのはコンパイルとリンクという分離された連鎖ルールで、‘foo.o’を 中間ファイルとして使用します。しかし、実際に起きることは、この場合の ルールは単一のccコマンドでコンパイルとリンクが行なわれることです。 最適化されたルールは段階的な連鎖に対する優位性で用いられ、それはルールの オーダー順によるものです。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5 パターンルールの定義と再定義

パターンルールの記述によって暗黙のルールを定義することが可能です。 パターンルールは普通のルールと似ていますが、‘%’文字をターゲットに 含んでいる点が違います。ターゲットはファイル名にマッチするパターンとして みなされます。‘%’はほかの文字が自分自身としかマッチできなくとも、 空でない部分文字列の何とでもマッチすることが可能です。必要条件はその名前が ターゲット名とどのように関係するかを示すために‘%’を使用します。

したがって、パターンルール‘%.o : %.c’は別のファイル‘stem.c’か ら‘stem.o’を作成する方法を示します。

パターンルールにおいて‘%’を使用した展開は、どんな変数やファンクションの 展開のあとでも、makefileが読み込まれたときに起こることに注意してください。 変数の使用法.と テキスト変換のためのファンクション.を参照してください。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5.1 パターンルールへのイントロダクション

パターンルールはターゲットのなかに‘%’文字を含んでいます。そうでなければ 普通のルールのように見えます。ターゲットはファイル名にマッチしたパターンで、 ‘%’はほかの文字が自分自身としかマッチできなくとも、空でない部分文字列の 何とでもマッチすることが可能です。

たとえば、パターンとしての‘%.c’は‘.c’で終わるどんなファイル名とも マッチします。また、パターンとしての‘s.%.c’は‘s.’で始まり、 ‘.c’で終わる最低5文字の長さのファイル名とマッチします(‘%’と マッチするには最低でも1文字必要です)。‘%’がマッチする部分文字列は stemと呼ばれます。

パターンルールの必要条件の‘%’は、ターゲットの‘%’でマッチした同じ stemと同等です。パターンルールがあてはまるように、そのターゲットパターンは 考慮中のファイル名とマッチしなければならず、その必要条件のパターンは 存在するか作成可能なファイル名をつけなければなりません。それらの ファイルはターゲットの必要条件になります。

したがって、書式のルールは、

 
%.o : %.c ; command

となり、ファイル‘n.o’の作成法を別のファイル‘n.c’を その必要条件として指定します。このとき‘n.c’は存在するか 作成可能です。

%’を使用しない必要条件もあるかもしれません。そのような必要条件は、 このパターンルールで作られたすべてのファイルに付属しています。このような 変化しない必要条件は場合によっては有益です。

%’を含む必要条件をまったく必要としないパターンルールのようなルールは、 ワイルドカードのようなものです。それは、ターゲットパターンにマッチする どんなファイルでも作成できてしまいます。 See section 最後の手段のルールの定義.。

パターンルールは複数のターゲットを持つことができます。通常のルールと違い、 これは同じ必要条件とコマンドによる多くの種々のルールとして動作しません。 もし、パターンルールが複数のターゲットを持つ場合、makeは、ルールの コマンドが、ターゲットのすべてを作成することについて責任があると知っています。 コマンドは、すべてのターゲットを作成するために、1回だけ実行されます。 ターゲットとマッチするようにパターンルールを検索する際には、ルールの 必要なターゲットにマッチしているものを除いたルールのターゲットパターンが 偶然の一致となります。makeは、ファイルに与えるコマンドと必要条件だけに ついて検討します。しかし、このファイルのコマンドが実行されるときには、 ほかのターゲットはそれ自身がアップデートされたかのようにマークされます。

makefileにおいてパターンルールの現われる順序は重要です。なぜなら、それが パターンの考慮の順序になるからです。等しく適用可能なルールでも、 みつけられた最初のものだけが使用されます。組み込まれたルールよりも 記述したルールが優先します。しかし、注意しなければならないのは、ルールの 必要条件が実際に存在していること、あるいは、ほかの暗黙のルールの連鎖によって 作成される必要条件を持つルールよりもつねに優位に言及されていることが必要です。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5.2 パターンルールの例

ここにはいくつかのパターンルールの例があり、それらはmakeにおいて 事前に定義されているものです。最初は、‘.c’ファイルを‘.o’ ファイルにコンパイルするルールです。

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

は、‘x.c’から‘x.o’を何でも作成できるルールです。 コマンドが自動変数‘$@’を使用し、‘$<’でターゲットファイルと ソースファイルを代用するルールです(see section 自動変数.)。

また、2つめの組み込み済みルールがあります。

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

は、サブディレクトリ‘RCS’においてファイル‘x,v’に対応した ファイル‘x’を何でも作成できるルールを定義しています。 ターゲットが‘%’なので、存在する適切な必要条件ファイルのどのような ファイルにでもこのルールを適用できます。ダブルコロンは最終的なもので、 その意味は、その必要条件が中間ファイルではないかもしれないという意味です (see section 何にでもマッチするパターンルール.)。

このパターンルールの場合は2つのターゲットを持ちます。

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

この例では、makeに対してコマンド‘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’が1度だけ実行され、‘parse.tab.o’と ‘scan.o’の両方の必要条件が満足されます。(おそらく、ファイル ‘parse.tab.o’は‘parse.tab.c’から、 ‘scan.o’は‘scan.c’から再コンパイルされ、‘foo’は ‘parse.tab.o’、‘scan.o’とそのほかの必要条件からリンクされ、 うまく実行できるようになるでしょう。)


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5.3 自動変数

.c’ファイルを‘.o’ファイルにコンパイルするパターンルールを 記述するとします。この場合、‘cc’コマンドで正しいファイルを 操作するようにするにはどのように記述したらよいでしょうか。暗黙のルールが 適用されるごとにファイル名が異なるので、コマンドにファイル名を書くことは できません。

この場合、makeの特別な機能、すなわち自動変数を使用することに なります。この変数はルールのターゲットと必要条件に基づいて、ルールが 実行されるたびに計算された値を持ちます。この例では、オブジェクトファイル名に ‘$@’、ソースファイル名に‘$<’を使用します。

自動変数についてまとめた一覧が以下のものです。

$@

ルールにおけるターゲットのファイル名。ターゲットがアーカイブのメンバーで ある場合、‘$@’はそのアーカイブファイルの名前になります。複数の ターゲットを持つパターンルールの場合は (see section パターンルールへのイントロダクション.)、 ‘$@’は、ルールのコマンドが実行されるターゲットのどれかの名前になります。

$%

ターゲットがアーカイブのメンバーの場合は、ターゲットメンバーの名前。 See section アーカイブファイルのアップデートにmakeを使用する.。 たとえば、ターゲットが‘foo.a(bar.o)’ならば、‘$%’は ‘bar.o’で‘$@’は‘foo.a’になります。アーカイブの メンバーでない場合は、‘$%’は空です。

$<

最初の必要条件の名前。ターゲットが暗黙のルールからそのコマンドを取得した 場合、暗黙のルールによって付加された最初の必要条件になります (see section 暗黙のルールの使用.)。

$?

ターゲットよりも新しいすべての必要条件の名前で、スペースで区切られています。 アーカイブメンバーの必要条件の場合は、メンバーの名前が使用されます (see section アーカイブファイルのアップデートにmakeを使用する.)。

$^

スペースで区切られたすべての必要条件の名前。アーカイブメンバーの必要条件の 場合は、メンバーの名前が使用されます(see section アーカイブファイルの アップデートにmakeを使用する.)。ターゲットはほかの ファイルに依存した必要条件を1つだけ持ち、個々のファイルが必要条件として 何回リストされたかは問題ではありません。あるターゲットに関して必要条件を 複数回リストしたとしても、$^の値にはたった1つの名前がコピー されるだけです。

$+

これは‘$^’に似ていますが、makefile中でリストされた順序に従って、 1回以上リストされた必要条件が重複します。ある特別な順序でライブラリの ファイル名を繰り返す場合のリンクコマンドにおいて有益です。

$*

暗黙のルールがマッチするstem(see section パターンマッチの方法.)。 ターゲットが‘dir/a.foo.b’でターゲットパターンが‘a.%.b’の場合、 stemは‘dir/foo’です。stemは関連する名前の構築の際に有用です。

静的なパターンルールでは、stemはファイル名の一部でターゲットパターンに おいては‘%’にマッチします。

明示的なルールの場合にはstemはありません。したがって、‘$*’はこの方法では 決定できません。かわりに、ターゲット名が既知のサフィックスで終わる場合 (see section 古いスタイルのサフィックスルール.)、‘$*’は ターゲット名からサフィックスを取ったものとなります。たとえば、ターゲット名が ‘foo.c’の場合は、‘$*’は‘foo’とセットされます。 なぜなら、‘.c’がサフィックスだからです。ほかのmakeの インプリメンテーションとの互換性のためだけにGNUのmakeはこの奇妙な 動作を行ないます。一般的には、暗黙のルールあるいは静的なパターンルールを 除いて‘$*’の使用は避けたほうがよいのでしょう。

明示的なルールのターゲットが既知のサフィックスで終わっていない場合、‘$*’ はそのルールに関して、空の文字列としてセットされます。

明示的なルールにおいて、変更された必要条件だけを操作したいと考えるときに ‘$?’は有益です。たとえば、アーカイブ名‘lib’はいくつかの オブジェクトファイルのコピーを含むことが考えられますが、このルールは変更の あったオブジェクトファイルだけをアーカイブにコピーします。

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

上記リストにおける4つの変数は単一のファイル名を持ち、3つはファイル名の リストの値を持ちます。これらの7つはファイルのディレクトリ名だけだったり、 そのディレクトリのファイル名だけだったりするバリエーションを持っています。 それらの名前は‘D’あるいは‘F’を追加される書式となります。これらの 変数はGNUのmakeではやや時代遅れとなっています。なぜならば、 同じ効果を持つものとしてファンクションdirnotdirが 使用されるからです (see section ファイル名に対するファンクション.)。 しかしながら、注意してほしいのは、‘F’バリアントはdir ファンクションの出力でつねに現われる後続のスラッシュをすべて省略して しまうことです。以下にバリアントの一覧を示します。

$(@D)

ターゲットのファイル名のディレクトリ部でうしろのスラッシュを除いたもの。 ‘$@’の値が‘dir/foo.o’のとき、‘$(@D)’は‘dir’です。 ‘$@’がスラッシュを含まないときは値は‘.’となります。

$(@F)

ターゲットのファイル名のファイル名の部分。‘$@’の値が ‘dir/foo.o’のときは、‘$(@F)’は‘foo.o’です。‘$(@F)’は ‘$(notdir $@)’と同等です。

$(*D)
$(*F)

ディレクトリ部とstemのファイル名。この例では‘dir’と‘foo’。

$(%D)
$(%F)

ターゲットのアーカイブメンバーのディレクトリ部とファイル名。これは、書式 ‘archive(member)’のアーカイブメンバーのターゲットでしか 意味がありません。また、memberがディレクトリ名を含む場合にだけ有益です (see section ターゲットとしてのアーカイブメンバー.)。

$(<D)
$(<F)

最初の必要条件のディレクトリ部とファイル名。

$(^D)
$(^F)

すべての必要条件のディレクトリ部とファイル名のリスト。

$(?D)
$(?F)

ターゲットよりも新しいすべての必要条件のディレクトリ部とファイル名のリスト。

これらの自動変数について話題にするときに、ある特別な従来からのスタイルを 用いることに注意してください。それは、objectsCFLAGSのように、 通常の変数を記述するように“the variable <”ではなくthe value of ‘$<’と記述することです。この従来のものをこの特別なケースでは 自然であると考えます。とくに深い意味があるわけではなく、‘$<’は<と 名付けられた変数を参照し、ちょうどこれは‘$(CFLAGS)’がCFLAGSと 名付けられた変数を参照することと同じです。したがって、同じように‘$<’の 場所で‘$(<)’を使うことができます。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5.4 パターンマッチの方法

ターゲットパターンは、プレフィックスとサフィックスの2つあるいは両方とも空の 場合も含めて両者のあいだの‘%’から構成されています。オーバーラップなしで、 ファイル名がプレフィックスで始まり、サフィックスで終わる場合にだけパターンは ファイル名にマッチします。プレフィックスとサフィックスのあいだのテキストは stemと呼ばれます。したがって、パターン‘%.o’がファイル名 ‘test.o’にマッチするときのstemは‘test’です。パターンルールの 必要条件はstemを‘%’文字で代用することによって実際のファイル名に 変えられます。したがって、同じ例で、必要条件の1つが‘%.c’と書かれた場合、 それは‘test.c’と展開されます。

ターゲットパターンがスラッシュを含まないとき(通常はそうではありませんが)、 ファイル名のディレクトリ名はターゲットのプレフィックスとサフィックスと 比較されるまえにファイル名から取り除かれます。ファイル名とターゲットパターンの 比較のあと、スラッシュで終わるディレクトリ名が、パターンルールの必要条件 パターンとファイル名から生成された必要条件のファイル名に加えられます。 ディレクトリは、ルールのアプリケーションのなかではなく、使用される暗黙の ルールの発見の目的のためだけに無視されます。したがって、‘e%t’は ‘src/a’をstemとしてファイル名‘src/eat’にマッチします。 必要条件がファイル名に変えられるとき、stemからのディレクトリは先頭に 加えられ、stemの残りは‘%’で代用されます。必要条件のパターン ‘c%r’を伴うstem‘src/a’はファイル名‘src/car’を与えます。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5.5 何にでもマッチするパターンルール

パターンルールのターゲットが‘%’だけであった場合、それはどんな ファイル名にでもマッチします。このようなルールを、何にでもマッチする ルールと呼びます。これは非常に便利ですが、makeがそれを検討するのに 多くの時間を費やします。なぜなら、ターゲットあるいは必要条件として リストされた個々のファイル名に対してすべて考慮しなければならないからです。

makefileが‘foo.c’に言及する場合、このターゲットに対して、makeは オブジェクトファイル‘foo.c.o’のリンク、あるいは‘foo.c.c’からの 1ステップでのCコンパイルとリンク、あるいは‘foo.c.p’からのPascal コンパイルとリンクなどによってmakeすることを考慮しなければなりません。

しかし、これらの可能性は‘foo.c’がCのソースファイルであって 実行可能ではないことを知っているため滑稽だと感じます。makeが これらの可能性を考慮する場合、最終的にはそれらを拒絶するでしょう。 なぜなら、‘foo.c.o’と‘foo.c.p’のようなファイルが 存在しないからです。しかし、このような可能性が多ければ、makeが それらを考慮した場合には非常に動作が遅くなってしまいます。

スピードを上げるには、makeが何にでもマッチするルールを考慮する 方法にさまざまな制約を置きます。適用できる制約は2つあります。何にでも マッチするルールを適用する際には、どちらか一方のルールを 選択しなければなりません。

1つめの選択は、ダブルコロンを用いて何にでもマッチするルールを ターミナルであるとしてマークすることです。ルールがターミナルであるとき、 その必要条件が実際に存在しない限りそれは適用されません。ほかの暗黙の ルールによって作られた必要条件は十分なものではありません。いいかえれば、 ターミナルルールを越えて連鎖は許可されないのです。

たとえば、RCSやSCCSファイルからソースを展開する組み込み済みの暗黙のルールは ターミナルです。結果的に‘foo.c,v’が存在しない場合、makeは ‘foo.c,v.o’あるいは‘RCS/SCCS/s.foo.c,v’からの中間ファイルとして それをみなそうとしません。RCSとSCCSファイルは一般的に究極の ソースファイルであり、ほかのファイルから作り出されることはありません。 したがって、makeはそれらを再構成する方法を探さないことで 時間を節約できるのです。

もし、何にでもマッチするルールをターミナルであるとマークしない場合には ターミナルでないことになります。ターミナルでない何にでもマッチするルールは 特別なタイプのデータを示すファイル名には適用できないことになります。 何にでもマッチしない暗黙のルールのターゲットがマッチしない場合、 ファイル名は特別なタイプのデータを示すことになります。

たとえば、ファイル名‘foo.c’はパターンルール‘%.c : %.y’(Yaccを 実行するルール)に対するターゲットとマッチします。このルールが実際に 適用可能かどうかにかかわらず(‘foo.y’が存在するときにだけ起こりますが)、 ターゲットがマッチするという事実は、ファイル‘foo.c’に対するいかなる ターミナルでない何にでもマッチするルールを考慮するのを妨げるのに十分です。 したがって、makeは‘foo.c.o’、‘foo.c.c’、‘foo.c.p’などから 実行ファイルとして‘foo.c’を作成しようと考慮することさえしないのです。

このような制約の理由は、ターミナルでない何にでもマッチするルールが、 特別なタイプのデータを含むファイル(たとえば実行ファイル)と既知の サフィックスが特別なタイプのデータを示すファイル名(たとえばCのソース)を 作成するのに用いられるためです。

特定のファイル名を認識するために組み込み済みのダミーのパターンルールが 提供されていて、ターミナルでない何にでもマッチするルールは考慮されません。 このようなダミーのルールは必要条件やコマンドを何も持たず、 ほかの目的に対しては無視されます。たとえば組み込み済みの暗黙のルール、

 
%.p :

は、‘foo.p’のようなPascalのソースファイルが特別なターゲットパターンに マッチするかを確認し、これによって、‘foo.p.o’や‘foo.p.c’を 探すための時間をむだにすることを回避するのです。

%.p’に対するもののようなダミーパターンルールは、サフィックスルールで 使用される正しくリストされたサフィックスに対して作られています (see section 古いスタイルのサフィックスルール.)。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.5.6 暗黙のルールのキャンセル

組み込み済みの暗黙のルール(あるいは独自に定義したルール)を同じターゲットと 必要条件で新しいパターンルールを定義することでオーバーライドすることが 可能です。ただし、この場合コマンドは異なるものが必要です。新しいルールが 定義されると組み込み済みのものは置き換えられます。暗黙のルールの シーケンスにおける新しいルールの位置は、新しいルールを書いた場所によります。

組み込み済みの暗黙のルールを、同じターゲットと必要条件で新しいパターンルールを 定義することでキャンセルすることが可能です。ただし、この場合コマンドは 異なるものが必要です。たとえば、以下の例ではアセンブラの実行を行なうルールを キャンセルできます。

 
%.o : %.s

[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.6 最後の手段のルールの定義

必要条件なしにターミナルな何にでもマッチするパターンを記述することで 最後の手段ともいえる暗黙のルールを定義することができます (see section 何にでもマッチするパターンルール.)。 これはほかのパターンルールと非常に似ていますが、いかなるターゲットにも マッチするという唯一の点で異なります。したがって、そのようなルールの コマンドは暗黙のルールが何も適用されず、自身のコマンドを持たないすべて のターゲットと必要条件に対して用いられます。

たとえば、makefileのテストの際、ソースファイルが実データを持つ場合、 存在するだけなので気にしてはなりません。そして、以下のようにします。

 
%::
        touch $@

は、すべてのソースファイル(必要条件として)が自動的に作成される必要が あるようにします。

かわりに、ルールがまったくない場合のターゲットに対して用いられるコマンドを、 ターゲットがコマンドを指定しなくとも、定義することができます。この場合、 ターゲット.DEFAULTに対してルールを書くことが必要です。そのような ルールのコマンドは、いかなる明示的なルールにも現われないすべての必要条件と 暗黙のルールが適用されないものに対して用いられます。もちろん、 記述しない限り.DEFAULTルールはありません。

コマンドや必要条件なしに.DEFAULTを使用する場合、

 
.DEFAULT:

.DEFAULTに以前に保存されたコマンドはクリアされます。すると、 make.DEFAULTがまったく定義されていないかのように動作します。

ターゲットが何にでもマッチするパターンルールあるいは.DEFAULTから コマンドを取得するのを望まない場合で、しかしターゲットに対して何もコマンドの 実行を望まない場合は空のコマンドを与えることができます (see section 空のコマンドの使用.)。

別のmakefileの一部をオーバーライドするために、最後の手段のルールを使用する ことができます。 See section ほかのMakefileの部分的なオーバーライド.。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.7 古いスタイルのサフィックスルール

サフィックスルールは、makeに対して暗黙のルールを定義するための 古いスタイルの方法です。サフィックスルールは、パターンルールがより一般的で わかりやすいので時代遅れです。GNUのmakeでは古いmakefileとの互換性を とるためにサポートされます。ルールには2種類あり、それらは ダブルサフィックスシングルサフィックスです。

ダブルサフィックスルールは、ターゲットとソースのサフィックスのペアによる ものです。ターゲットのサフィックスで終わるどんなファイル名ともマッチします。 関係する暗黙の必要条件はファイル名でターゲットのサフィックスをソースの それに置き換えられて作られます。2つのサフィックスによるルールの場合は、 ターゲットとソースが‘.o’と‘.c’で、‘%.o : %.c’と同じです。

一方、シングルサフィックスルールは1つのサフィックスで定義されます。それは ソースのサフィックスです。それはどんなファイルともマッチし、関連した暗黙の 必要条件の名前はソースのサフィックスが付け加えられます。 シングルサフィックスルールで、‘.c’はパターンルールの‘% : %.c’と 同じです。

サフィックスルールの定義は、既知のサフィックスのリストとそれぞれのルールの ターゲットとの比較で認識されます。makeが既知のサフィックスをルールに みつけた場合、そのルールはシングルサフィックスルールとみなされます。 makeが既知の2つの連続したサフィックスをルールにみつけた場合、 そのルールはダブルサフィックスルールとみなされます。

たとえば、‘.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’ファイルを作成する方法を示していて、 ‘foo.h’にも依存したパターンルールを使ってすべての‘.o’ファイルを 作成します。

コマンドなしのサフィックスルールは無意味です。コマンドのないパターンルールと 同じくそれらのルールは以前のルールを取り除きません (see section 暗黙のルールのキャンセル.)。それらは、 サフィックスあるいは連結されたサフィックスをターゲットとしてデータベースに 入力します。

既知のサフィックスはたんに特別なターゲット.SUFFIXESの必要条件の名前で、 .SUFFIXESに対するルールを記述することによって独自のサフィックスを 追加することが可能です。そうすることによって、必要条件も追加することに なります。

 
.SUFFIXES: .hack .win

上記は、サフィックスのリストの最後に‘.hack’と‘.win’を追加します。

たんに追加するかわりにデフォルトの既知のサフィックスを取り除きたい場合は、 必要条件なしに.SUFFIXESにルールを記述します。これによって、 特別な分配によって、すべての既存の.SUFFIXESの必要条件を取り除きます。 また、希望するサフィックスを追加するために別のルールを記述することもできます。

 
.SUFFIXES:            # デフォルトサフィックスを削除
.SUFFIXES: .c .o .h   # サフィックスリストを定義

-r’あるいは‘--no-builtin-rules’フラグはサフィックスの デフォルトのリストを空にします。

変数SUFFIXESは、makeがどのmakefileでも読み込むまえに サフィックスのデフォルトのリストに定義されます。特別なターゲットの .SUFFIXESに対するルールでサフィックスのリストを変更できますが、 この変数を変更するわけではありません。


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

10.8 暗黙のルールのサーチアルゴリズム

makeが、ターゲットtに対する暗黙のルールをサーチするのに 用いる手続きがあります。この手続きは、コマンドなしの個々の ダブルコロンルール、コマンドを持たないここの通常のルールのターゲット、 どのルールのターゲットでもない個々の必要条件に従われます。また、ルールの 連鎖において、暗黙のルールからの必要条件に関して再帰的に従われます。

サフィックスルールはこのアルゴリズムでは言及されません。なぜならば、 サフィックスルールは、いったんmakefileが読み込まれると、パターンルールに 変換されてしまうからです。

archive(member)’の書式を持つアーカイブメンバーの ターゲットに対して、以下のアルゴリズムは2回実行されます。1回目は ターゲット名tをすべて使用し、1回目でルールを発見できない場合に、 2回目は‘(member)’をターゲット名tとして使用します。

  1. tdと呼ばれるディレクトリとnと呼ばれる残りに分離します。 たとえば、tが‘src/foo.o’のとき、dは‘src/’でnは ‘foo.o’です。
  2. そのターゲットうちの1つがtあるいはnにマッチするパターンルール のすべてのリストを作成します。ターゲットパターンがスラッシュを含む場合、 tにマッチし、ほかはnにマッチします。
  3. リストのどのルールも何にでもマッチするルールではない場合、そのリストから すべてのターミナルでない何にでもマッチするルールを削除します。
  4. コマンドのないすべてのルールをリストから削除します。
  5. リストの個々のパターンルールに対して、
    1. stemを発見します。tあるいはnの空でない一部が ターゲットパターンの‘%’でマッチしたものです。
    2. %’に対するsの代用により必要条件を計算します。 ターゲットパターンがスラッシュを含まないとき、個々の必要条件の名前の 先頭にdを追加します。
    3. すべての必要条件が存在するか、あるいはすべきかをテストします。(ファイル名が makefileのなかでターゲットあるいは明示的な必要条件として言及されている場合、 それは存在すべきであるといえます。)

      すべての必要条件が存在するか、あるいはすべきであるとき、もしくは何も必要条件が ない場合にこのルールが適用されます。

  6. もし、どんなルールも発見されない場合、リストの個々のパターンに対して、
    1. ルールがターミナルである場合、それを無視し次のルールに進みます。
    2. そのまえに必要条件の名前を計算します。
    3. すべての必要条件が存在するかあるいはすべきかをテストします。
    4. 必要条件が存在しない場合、暗黙のルールによる作成が可能かどうか、 このアルゴリズムを再帰的に適用します。
    5. 必要条件が存在する場合あるいは存在すべき場合、または暗黙のルールによって 作成可能な場合、このルールを適用します。
  7. いかなる暗黙のルールも適用されない場合、.DEFAULTに対するルールも 適用されない場合。そのような場合には、.DEFAULTの持つ同じコマンドを tに与えます。さもなければ、tに対しては何もコマンドがありません。

いったん、適用されるルールがみつかると、tあるいはnにマッチしたもの 以外のルールの個々のターゲットパターンに対して、パターンのなかの‘%’は sで置き換えられ、結果的なファイル名はターゲットファイルtを 再構成するコマンドが実行されるまで保存されます。それらのコマンドの実行後、 保存された個々のファイル名はデータベースに格納され、アップデートされて ファイルtとしてステータスもアップデートされたとしてマークされます。

tに対してパターンルールのコマンドが実行される場合、自動変数は ターゲットと必要条件が一致しているようにセットされます。 See section 自動変数.。


[ << ] [ >> ]           [冒頭] [目次] [見出し] [ ? ]

この文書は新堂 安孝によって2009年9月22日texi2html 1.82を用いて生成されました。