[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
makefileと呼ばれるデータベースを読み取ることによって、
どのように再コンパイルするかの情報をmake
に伝えます。
3.1 Makefileに含まれるもの | What makefiles contain. | |
3.2 Makefileの名前のつけ方 | How to name your makefile. | |
3.3 ほかのMakefileをインクルードする | How one makefile can use another makefile. | |
3.4 MAKEFILES の変数 | The environment can specify extra makefiles. | |
3.5 Makefileの作られ方 | How makefiles get remade. | |
3.6 ほかのMakefileの部分的なオーバーライド | How to override part of one makefile with another makefile. | |
3.7 make はどのようにMakefileを解釈するか | How makefiles are parsed. |
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
Makefileは5つの項目を含んでいます。それは、explicit rules、 implicit rules、variable definitions、directivesと commentsです。また、ルール、変数とディレクティブについては章の後半で 説明しています。
objects
に対する変数を定義
しています
(see section 変数によるMakefilesの簡素化.)。
make
に
何か特別に実行させる命令です。これらは以下を含みます。
define
ディレクティブの
なかでは例外となりますし、命令行においても例外となります。コメントだけの
行(先頭がスペースで始まる)は空白と同じで無視されます。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
デフォルトではmake
はmaefileを探しますが、その際には、‘GNUmakefile’、
‘makefile’、‘Makefile’の順序で探します。
通常は、makefileを‘makefile’あるいは‘Makefile’としたほうがよく、
こうしておけば、‘README’などの重要なファイルのあるディレクトリの
リストの先頭に出てきます。名前のチェックでは、ほとんどの場合
‘GNUmakefile’は推奨しません。この名前は、とくにGNUのmake
を
使用する場合に用いますが、ほかのバージョンのmake
では
認識されないでしょう。ほかのmake
プログラムは、‘makefile’あるいは
‘Makefile’は認識しますが、‘GNUmakefile’は認識しません。
もしmake
がこれらのファイルを探し出せなかった場合には、
makefileを用いません。したがって、コマンドの引数でゴールを指定する必要があり、
make
は組み込まれている暗黙のルールにのみ従ってremakeしようとします。
See section 暗黙のルールの使用.。
標準的なmakefile以外の名前を用いたい場合には、‘-f’あるいは
‘--file’オプションをつけてmakefileの名前を指定できます。引数
‘-f name’あるいは‘--file=name’によって
make
にnameをmakefileだと認識させられます。また、‘-f’
あるいは‘--file’オプションによって、複数のmakefileの指定を行なうことも
できます。指定されたすべてのmakefileは順序に従って効果的に連結されます。
また、‘-f’あるいは‘--file’オプションを使用した場合には、
デフォルトの名前である‘GNUmakefile’や‘makefile’や‘Makefile’は
自動的にチェックは行なわれません。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
include
ディレクティブは、make
に対してmakefileの読み込みを
中断し、1つあるいは複数のほかのmakefileを読み込んでから継続するように
指示します。makefileのなかのディレクティブは以下のようなものです。
include filenames… |
filenamesは、シェルのファイル名のパターンを含むことができます。
行の先頭では、スペースは無視されるのでかまいませんが、タブは許されません。
タブで始まる行はコマンド行と認識されてしまいます。また、include
と
ファイル名のあいだには空白が必要で、2つ以上の空白やディレクティブの
終わりの空白は無視されます。行の終わりに‘#’で始まるコメントも
可能です。さらに、ファイル名がなんらかの変数や関数の参照を含んでいる場合には
それが展開されます。See section 変数の使用法.。
たとえば、3つの‘.mk’すなわち、‘a.mk’、‘b.mk’、‘c.mk’を
含んでいる場合には、bish bash
とともに展開され、以下のようになります。
include foo *.mk $(bar) |
は、以下と同様です。
include foo a.mk b.mk c.mk bish bash |
make
がinclude
ディレクティブを処理する際は、makefileの
読み込みを中断し、かわりにリストされたファイルの読み込みを実行します。その後、
make
はディレクティブの現われた箇所に戻り読み込み処理を続けます。
さまざまなディレクトリにある個々のmakefileによって処理されるいくつかの
プログラムが変数定義の標準的なセットを必要とする場合にinclude
ディレクティブを使用します(see section 変数の設定.、あるいは
パターンルールについては
see section パターンルールの定義と再定義.)。
また、ソースファイルから必要条件を自動的に生成する場合にもinclude
ディレクティブを用います。その場合、必要条件はメインのmakefileに
含まれるようにファイルとして生成されます。この方法は、従来のほかの
バージョンのmake
のようにメインのmakefileの最後に追加していく
方法よりもすっきりしています。
See section 必要条件の自動生成.。
もし、指定したファイルの名前がスラッシュで始まるものでない場合や カレントディレクトリにない場合には、いくつかのディレクトリがサーチされます。 その際に、まず‘-I’あるいは‘--include-dir’で指定されたディレクトリが サーチされ(see section オプションのサマリー.)、 次に(存在する場合には)以下のディレクトリがサーチされます。 ‘prefix/include’(普通は‘/usr/local/include’ ですが、MS-DOSとMS-Windowsの場合は、DJGPPツリー階層のルートディレクトリ であるようにGNUのMakeはコンパイルを行ないます)、 ‘/usr/gnu/include’、‘/usr/local/include’、 ‘/usr/include’。
もし、含まれているmakefileがどのディレクトリでもみつからない場合には、
警告メッセージが生成されますが、これはすぐに致命的なエラーということではなく、
include
を含むmakefileの処理は継続します。そして、makefileの
読み込みが終了するとmake
は期限切れや存在しないファイルを
再構成しようとします。See section Makefileの作られ方.。
ただし、makefile自体を変更しようとする方法をみつけた場合には再構成は
失敗します。そして致命的なエラーとして、makefileの存在を診断しようとします。
存在しないため、変更しようのないmakefileをエラーメッセージなしに単純に
無視する場合には、以下のようにinclude
ディレクティブのかわりに
-include
を使用してください。
-include filenames… |
filenameがまったく存在せず、エラーがないという場合を除けば、
この動作はinclude
によく似ています。これはほかのmake
インプリメンテーションとの互換性のためで、
sinclude
は-include
の別名となっています。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
MAKEFILES
の変数環境変数MAKEFILES
が定義されている場合には、make
はその変数を、
先行して読み込むmakefileの名前のリスト(空白で区切られた)と
みなします。この動作はinclude
ディレクティブとたいへん似ていて、
さまざまなディレクトリをサーチします
(see section ほかのMakefileをインクルードする.)。さらに、デフォルトの
ゴールはこれらのmakefileから得られることはなく、MAKEFILES
に
リストされたファイルが、たとえみつからない場合でもエラーとなることは
ありません。
MAKEFILES
の主な用途は、make
の再帰的な呼び出しの際の通信です。
(see section make
の再帰的用法.)通常は、トップレベルの
make
の呼び出しのまえに環境変数を設定することは好ましくありません。
なぜなら、外部からmakefileに対して干渉しないことがよいからです。しかし
ながら、makefileを指定せずにmake
を実行する場合には、
MAKEFILES
のなかのmakefileは組み込まれた暗黙のルールが定義された
サーチパスよりもうまく機能します
(see section 必要条件のためのディレクトリサーチ.)。
ユーザーによっては、ログイン時に自動的にMAKEFILES
を環境に設定して、
このような動作をするように設定したがりますが、これはよくないアイデアと
いえます。なぜなら、異なるユーザーによって実行された場合には
失敗してしまうからです。したがって、明示的にinclude
ディレクティブを
記述するほうがずっとよいのです。
See section ほかのMakefileをインクルードする.。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
makefileはRCSやSCCSファイルから作られる場合があります。このようにほかの
ファイルからmakefileが作られる場合には、make
が最新のバージョンの
makefileを読み込むことが期待されます。
すべてのmakefileを読み込んだあと、make
はそれぞれをゴールのターゲットと
みなし、アップデートしようと試みます。あるmakefileがその(まさにその
makefileまたは別のmakefile)アップデートの方法についてのルールを持つ場合
(see section 暗黙のルールの使用.)、あるいは暗黙のルールを
持つ場合には必要に応じてアップデートされるでしょう。すべてのmakefileが
チェックされたあと、なんらかの変更が行なわれた場合には、make
は
クリーン動作を行ないすべてのmakefileの読み込みをふたたび開始します。
(それぞれのアップデートもふたたび試みられますが、通常はアップデートされている
はずなので、再度変更を加えることはしません。)
1つあるいは複数のmakefileが変更できないことを知っていて、しかも暗黙の
ルールのサーチをmake
にさせないようにしたい場合、おそらくその理由は
効率の問題で、暗黙のルールのルックアップは通常の方法で防止することができます。
たとえば、明示的なルールをターゲットとしてmakefileに記述し、
空のコマンド文字列を書いておけばよいのです
(see section 空のコマンドの使用.)。
必要条件ではなく、命令でファイルを変更するために2つのコロンのルールを
makefileで指定する場合には、ファイルはつねに変更されます
(see section ダブルコロンルール.)。つまり、命令と2つのコロンの
ついた必要条件でないルールはmake
が実行されるたびに実行され、
ふたたびmake
が実行される際に再度読み込みも行なわれます。
これは無限ループを引き起こします。make
はつねにmakefileを変更しようと
試み、ほかに何もしないことになります。したがって、これを避けるために、
命令と2つのコロンのついた必要条件でないルールのターゲットとして指定された
makefileについてはmake
は変更しようとしません。
‘-f’や‘--file’オプションでmakefileを何も指定しない場合は、
make
はデフォルトの名前のmakefileを試します
(see section Makefileの名前のつけ方.)。
‘-f’や‘--file’オプションで明示的に要求されたmakefileと異なり、
make
はファイルの存在をあてにしません。しかしながら、デフォルトの
makefileが存在せず、かつmake
の実行によって生成される場合には、
makefileが使用されるようにルールの実行が行なわれたほうがよいことになります。
したがって、もしデフォルトのmakefileが存在しない場合には、make
は
サーチされる順序でそれを生成しようとしますが
(see section Makefileの名前のつけ方.)、サーチする
名前を使い果たしてしまいます。注意しなければならないのは、make
が
makefileをサーチあるいは生成できなかったとしてもこれはエラーとはなりません。
なぜなら、makefileがつねに必要というわけではないからです。
‘-t’あるいは‘--touch’オプション (see section コマンド実行の代替.)を 使用する際には、どのターゲットにtouchするかを決定するために期限切れの makefileを使用したいとは考えないはずです。したがって、‘-t’オプションは makefileのアップデートには何の効果も与えません。同様に、‘-q’ (あるいは‘--question’)や‘-n’ (あるいは‘--just-print’) オプションは、makefileのアップデートを妨げません。 なぜなら期限切れのmakefileはほかのターゲットに対して誤った出力を 行なってしまうからです。したがって、‘make -f mfile -n foo’は‘mfile’を アップデートし、それを読み込みます。そして実行することなしに、命令を出力して ‘foo’と必要条件をアップデートします。‘foo’に出力された命令は、 ‘mfile’のアップデートされた内容において指定されたものです。
しかしながら、ときにはmakefileのアップデートを止めたいと考えることも あるかもしれません。その場合、makefileのなかで行なうようにmakefile自体を ゴールに指定することで、実現できます。明示的なゴールとしてmakefileが 指定されている場合には、‘-t’などのオプションが適用されます。
したがって、‘make -f mfile -n mfile foo’はmakefile ‘mfile’を読み込み 実際に実行することはせずに、アップデートに必要な命令を出力します。そして、 ‘foo’のアップデートに必要な命令も出力します。‘foo’に対する命令は ‘mfile’の実際の内容によって指定されたものとなります。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
まれに、もう1つほとんど同じmakefileを持つことが有益な場合があります。
その場合、‘include’ディレクティブによってもう一方をインクルードするように
します。そして、より多くのターゲットあるいは変数定義を付け加えます。しかし、
同じターゲットに対して2つのmakefileが異なる命令を与える場合にはmake
は
この方法は用いることができません。この場合には別の方法があります。
他方をインクルードしようとするmakefileにおいては、そのmakefileに含まれる
内容から導けないどんなターゲットでも再構成できる何にでもマッチする
パターンルールを使用することができ、make
は他方のmakefileを
読み取ることになります。パターンルールについては、
See section パターンルールの定義と再定義.。
たとえば、ターゲット‘foo’をmakeするための‘Makefile’があるとして、 もう1つ別の‘GNUmakefile’を作ることができ、その中身は、 以下のようにします。
foo: frobnicate > foo %: force @$(MAKE) -f Makefile $@ force: ; |
‘make foo’とした場合、make
は‘GNUmakefile’をみつけだし、
それを読み‘foo’をmakeしようとします。そしてコマンド
‘frobnicate > foo’を実行しようとします。また、‘make bar’とした
場合には、make
は‘GNUmakefile’のなかで‘bar’をmakeする方法を
みつけられません。つまりここでは、‘make -f Makefile bar’という
パターンルールを使おうとしたからです。もし‘Makefile’が‘bar’を
アップデートするルールを提供するならば、make
はそれを適用します。
‘GNUmakefile’がどのようにmakeするかを指示しないあらゆるターゲットに
対しても同様です。
この動作は、‘%’だけのパターンを持つパターンルールによります。‘%’は
あらゆるターゲットにマッチします。たとえターゲットファイルがすでに
存在していても命令の実行を保証するために、ルールは‘force’という
必要条件を指定します。make
が暗黙のルールをサーチしないように空の
命令を‘force’ターゲットに与えます。そうしないと同一の何にでもマッチする
ルールを‘force’に適用してしまい、必要条件のループを生成してしまいます。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
make
はどのようにMakefileを解釈するかGNUのmake
は2つの異なったフェーズで仕事を行ないます。最初のフェーズでは、
すべてのmakefileを読み、makefileのインクルードを行ないすべての変数と値を内部の
値として持ち、暗黙および明示的なルールおよびすべてのターゲットと
その必要条件の依存状態のグラフを構築します。次のフェーズでは、
どのターゲットが再構築される必要があり、ルールの適用が必要なのかを
決定するためにmake
は内部構造を使用します。
この2段階のアプローチを理解しておくのが重要なのは、変数と関数の展開による
直接的な影響があるからです。このことはしばしばmakefileを記述する際の混乱の
もとになります。ここでは、makefileのなかの異なる構成に対する展開における2つの
段階の要約を示します。最初のフェーズで展開が行なわれる場合を
immediateといい、この場合はmake
は構文解析されたmakefileとして
構成のセクションの部分にすべての変数と関数を展開します。また、展開がただちに
行なわれない場合をdeferredといい、即時の文脈のなかでその構成が出現しない
限り実行されることはなく、そうでない場合は2番目のフェーズで実行されることに
なります。
読者はこの構成(物)に関してはまだ詳しくはないかもしれませんが、あとの章を 読み詳しくなるに従ってこの章を参照するとよいでしょう。
変数の定義は以下のように構文解析されます。
immediate = deferred immediate ?= deferred immediate := immediate immediate += deferred or immediate define immediate deferred endef |
‘+=’は付加オペレーターで、以前に変数が単純変数としてセット (‘:=’)されていてdeferredでない場合には、オペレーターの右側は immediateであるとみなされます。
条件付きのすべてのインスタンスはただちに全体として構文解析され、これには
ifdef
やifeq
やifndef
とifneq
形式が含まれます。
ルールは形式を問わず、つねに同じ方法で展開されます。
immediate : immediate ; deferred deferred |
つまり、ターゲットと必要条件であるセクションはただちに展開されて、ターゲットを 構成するための命令はつねにdeferredとなります。この一般的なルールは明示的な ルール、パターンルール、サフィックスルール、静的なパターンルールと単純な 必要条件の定義に対してあてはまります。
[ << ] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
この文書は新堂 安孝によって2009年9月22日にtexi2html 1.82を用いて生成されました。