[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
ルールの命令は、1行ずつ実行されるシェルコマンドの行で成り立っていて、 個々の行はタブで始まらなければなりませんが、あいだにセミコロンのある ターゲットと必要条件の行は例外です。また、空白行とコメントだけの行も あいだに置くことができますが、それらは無視されます。(ただし、タブで 始まり明らかに空白の行は空白ではなく空の命令です。 see section 空のコマンドの使用.。)
ユーザーは多くの異なったシェルプログラムを使用しますが、makefile中の コマンドはほかのシェルを指定しない限り、つねに‘/bin/sh’によって 解釈されます。See section コマンド実行.。
使用されるシェルは、コマンド行においてコメントが書かれているかどうか、 使用されるシンタックスは何かを決定します。シェルが‘/bin/sh’の場合、 ‘#’がコメントの始まりで、行の終わりまでコメントとされます。また、 ‘#’が行の先頭にある必要はなく、‘#’よりまえのテキストはコメントの 一部ではありません。
5.1 コマンドエコー | How to control when commands are echoed. | |
5.2 コマンド実行 | How commands are executed. | |
5.3 パラレル実行 | How commands can be executed in parallel. | |
5.4 コマンドのエラー | What happens after a command execution error. | |
5.5 make の中断あるいはkill | What happens when a command is interrupted. | |
5.6 make の再帰的用法 | Invoking make from makefiles.
| |
5.7 コマンドの組み合わせの定義 | Defining canned sequences of commands. | |
5.8 空のコマンドの使用 | Defining useful, do-nothing commands. |
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
通常、make
はコマンドの実行前に個々のコマンド行を出力します。
コマンドをタイプしたときのように見えることからこれをエコーといいます。
行が‘@’で始まる場合、エコーは抑制され、コマンドがシェルに渡される
まえに‘@’は破棄されます。一般的には、makefileを通して実行状態を
表示するためのecho
コマンドのように何かを出力する効果のある
コマンドに対してこれを用います。
@echo About to make distribution files |
make
に‘-n’あるいは‘--just-print’フラグが
与えられる場合には、コマンドのエコーだけを行ない実行はしません。
See section オプションのサマリー.。
このケースにおいてだけ、‘@’で始まるコマンドでさえも出力されます。
このフラグは有益で、make
が必要とするコマンドがどれであるかを実行を
伴わずにみつけだすことができます。
‘-s’あるいは‘--silent’フラグがmake
に与えられた場合、
すべてのコマンドが‘@’で始まるかのごとくすべてのエコーが抑制されます。
必要条件を持たない特別なターゲットである.SILENT
に対するmakefileの
ルールは同様の効果を持ちます
(see section 特別な組み込み済みのターゲット名.)。‘@’は
より柔軟なため、.SILENT
は本質的に時代遅れといえます。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
ターゲットをアップデートする命令の実行のタイミングであるとき、それぞれの
行に対して新しいサブシェルを作ることによって実行されます。(実際には、
make
は結果に影響を与えないショートカットを捉えます。)
[Please Note:]cd
のような個々のプロセスにローカルな
変数をセットするシェルコマンドはそれに続く行に対して影響を与えないことを
意味していることです。(1)
仮に、cd
を使用して次のコマンドに影響与えるようにする場合、1行に2つの
コマンドをセミコロンで区切って置けばよいのです。そして、make
は
それらを1つのコマンドのようにみなし、連続して実行するようにします。たとえば
以下のようになります。
foo : bar/lose cd bar; gobble lose > ../foo |
もし、1つのシェルコマンドを複数の行に分割したい場合には、最後の行を除いて すべての行の終わりにバックスラッシュを置きます。このような連続した行は、 シェルに渡されるまえにバックスラッシュによる分割が削除されて単一の行として 統合されます。したがって、以下の例は前記のものと同じものとなります。
foo : bar/lose cd bar; \ gobble lose > ../foo |
シェルとして使われるプログラムは変数.SHELL
から得られます。
デフォルトでは、‘/bin/sh’が使われます。
MS-DOSの場合、SHELL
がセットされていない場合には変数COMSPEC
の
値がかわりに用いられます。
Makefileにおいて変数SHELL
をセットした行の処理はMS-DOSの場合には
異なります。もともとのシェルである‘command.com’は機能が滑稽に
制限されていて、make
のユーザーはかわりのシェルをインストールする
傾向があります。したがってMS-DOSにおいては、make
はSHELL
変数の
値を試し、UnixスタイルかDOSスタイルかによってふるまいを変更します。
これによって、たとえSHELL
が‘command.com’であっても妥当な機能を
提供できるのです。
SHELL
がUnixスタイルを示す場合、MS-DOSのmake
はそのシェルを
みつけだそうとします。もし、みつからない場合にはSHELL
をセットした行を
無視します。MS-DOSにおいてはGNUのmake
は以下の場所でシェルを
検索します。
SHELL
の値で指定された正確な場所。たとえば、makefileで
‘SHELL = /bin/sh’と指定されている場合、make
はカレントドライブの
‘/bin’ディレクトリを探します。
PATH
変数のなかのディレクトリを順番に。
それぞれのディレクトリにおいてmake
は特定のファイル(上記の場合は
‘sh’)を探します。みつからない場合は、実行形式のファイル拡張子を持つ
ファイルをそのディレクトリで探します。たとえば、‘.exe’、‘.com’、
‘.bat’、‘.btm’や‘.sh’などです。
これらの試みが成功すると、SHELL
の値はみつかったシェルのフルパスで
セットされます。しかしながら、何もみつからない場合にはSHELL
の値は
変更されず、その行は無視されます。つまり、make
が動作するシステムに
実際にインストールされているシェルがUnixスタイルのシェルの場合だけを
対象にした特徴をmake
がサポートしているということです。
ここで、シェルのサーチについては、MakefileでSHELL
がセットされて
いる場合には制限されることを注意してください。環境変数やコマンドラインで
設定されている場合には、Unixの場合のようにシェルのフルパスにセットされる
ことが必要です。
以上のDOS限定の処理の効果は、多くのUnixのmakefileのように
‘SHELL = /bin/sh’であるMakefileがMS-DOSでPATH
に従う
ディレクトリに‘sh.exe’がインストールされている場合に限られます。
大部分の変数と異なり、SHELL
は環境から設定されることはありません。
これは、環境変数SHELL
が対話的な使用をするシェルを個人の好みで指定
できるからです。しかし、個人の選択によることはmakefileの機能への影響としては
好ましくないのです。See section 環境(変数)からの変数の取得.。
しかし、MS-DOSやMS-Windowsにおいては環境変数のなかのSHELL
の値が
用いられます。これらのシステムのユーザーはこの変数を設定しませんので、
make
によって使用されるように明確に指定する必要があります。また、
MS-DOSにおいてはSHELL
のセッティングがmake
にとって適当ではない
場合にmake
が使用するMAKESHELL
変数を設定することができ、
これはSHELL
をオーバーライドします。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
GNUのmake
はいくつかのコマンドを同時に実行することができます。通常は
make
は一度に1つのコマンドの実行しかせず、直前の処理の終了を
待ってから次の処理に移ります。しかしながら、‘-j’あるいは
‘--jobs’オプションがある場合は、make
は多くのコマンドを
同時に実行します。
ただし、MS-DOSにおいてはマルチプロセッシングをサポートしていないので、 ‘-j’オプションは意味がありません。
‘-j’オプションのあとに整数がつく場合は、同時に実行するコマンドの数を 表わし、これをジョブスロットの数といいます。‘-j’オプションの あとに整数がないときは、ジョブスロットに制限がないことを意味します。 ジョブスロットのデフォルトの値は1で、シリアルな実行を意味します。
同時にいくつかのコマンドを実行した際に不愉快なのは、種々のコマンドが出す メッセージがバラバラに出てくることです。
もう1つ別の問題は、2つのプロセスが同じデバイスから入力を得ることが
できないことです。したがって、ターミナルからの入力を得ようとするコマンドが
一度に1つになるように気をつけなければならず、make
は標準入力を
無効にして1つのコマンドが動作するようにします。つまり、複数の
子プロセスに対する標準入力からの読み込みは通常はエラー
(‘Broken pipe’シグナル)になるということです。
どのコマンドが有効な標準入力ストリーム(ターミナルまたはmake
の入力を
リダイレクトするデバイス)であるかを予測することは困難です。つねに最初の
コマンドの実行がそれを獲得して、その終了後に次々に獲得していきます。
ほかに選択肢があるならば、make
のこの特徴をどのように変更したいと
考えるでしょうか。パラレル実行を用いる場合には、標準入力を用いるいかなる
コマンドも信頼しないでしょう。しかし、この機能を使用しない場合は標準入力は
すべてのコマンドで正常に動作します。
最終的には、再帰的なmake
の呼び出しが問題として出てきます。詳細は、
サブのmake
へのオプションの伝達.
を参照してください。
コマンドの実行が失敗した場合(シグナルでkillされるか、ゼロ以外の
ステータスで終了した場合)、しかもエラーが無視されなかった場合
(see section コマンドのエラー.)、同じターゲットを再構成するための
残されたコマンドは実行されません。コマンドが失敗して‘-k’や
‘--keep-going’オプションが与えられないときには
(see section オプションのサマリー.)、make
は実行を
中止します。子プロセス側の理由によってmakeが中断する場合には、
終了するまえに、それらの終了を待ちます。
システムのロード(負荷)が大きい場合、小さいときに比較して少ないジョブを
実行させようとするはずです。‘-l’オプションをつけることによって、
make
に対してロードアベレージに応じて同時に実行するジョブの数を
制限することができます。‘-l’あるいは‘--max-load’オプションに
続けて小数を例のように加えます。
-l 2.5 |
この場合、ロードアベレージが2.5を超えたときにはmake
は複数のジョブを
開始しません。また、‘-l’に数値をつけない場合は以前の‘-l’で与えた
ロードの制限をなくします。
より正確にいうと、make
がジョブを開始する際にすでに少なくとも1つの
ジョブが動作中だとすると、現在のロードアベレージをチェックし、‘-l’で
与えられた制限よりも小さくない場合にはmake
は、ロードアベレージが
下がるのを待つか、ほかのすべてのジョブが終了するのを待ちます。
デフォルトでは、この制限はありません。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
個々のシェルコマンドに戻ったあと、make
は終了ステータスを見ます。
コマンドの実行が成功している場合は次のコマンド行が新しいシェルで
実行されます。最後のコマンド行が終了するとルールが終了となります。
もしエラーが起きた場合(終了ステータスがゼロでない場合)、make
は現在
のルールを諦め、おそらくすべてのルールについても諦めます。
一定のコマンドの実行時の失敗は問題を表示しないことがあります。たとえば、
ディレクトリの存在を保証するためにmkdir
コマンドを使うかもしれません。
すでにそのディレクトリが存在している場合、make
はエラーを報告しますが
これを無視してほしい場合もあります。
コマンド行におけるエラーの無視をさせる場合には、‘-’を最初のタブのあとの 行の先頭に置きます。‘-’はコマンドが実行のためにシェルに渡される直前に 破棄されます。
たとえば、
clean: -rm -f *.o |
このようにしておけば、削除できない場合でもrm
は継続できます。
‘-i’または‘--ignore-errors’フラグをつけてmake
を実行した
場合、すべてのルールのすべてのコマンドのエラーが無視されます。必要条件がない
場合には、特別なターゲット.IGNORE
に対するmakefileのルールは同様の
効果を持ちます。ただし、その方法は時代遅れで、‘-’のほうがより柔軟性が
あります。
‘-i’または‘--ignore-errors’フラグによってエラーが無視される場合、
make
はステータスコードを出力する以外はエラーを無視し、成功したかの
ごとく扱い、コマンドから抜け、エラーが無視されたことを示します。
make
に対して無視するように指定されなかったエラーが起きた場合には、
現在のターゲットが正しく再構成されないか、直接的あるいは間接的にほかに
依存していることを暗示しています。必要条件が達成されなければ、ターゲットに
対してのそれ以上のコマンドの実行は行なわれません。
通常、make
はこのような状況ではただちに諦め、ゼロでないステータスを
返します。しかしながら、‘-k’または‘--keep-going’フラグが
指定されている場合、make
は諦めてゼロでないステータスを返すまえに、
必要に応じて保留になっているターゲットのほかの必要条件を再構成することを
継続しようとします。たとえば、あるオブジェクトファイルのコンパイルで
エラーとなったあと、make -k
はリンクすることが不可能とわかっていても
ほかのオブジェクトファイルのコンパイルを継続します。
See section オプションのサマリー.。
make
の通常のふるまいは、特定のターゲットをアップデートすることが
目的であると仮定しています。しかし、make
はこれが無理だとわかると
ただちに失敗を表示します。‘-k’オプションによって実際の目的が可能な限り
プログラムでの変更をテストできるようにすることで、次のコンパイルのまえに
いくつかの独立した問題を解決できるように発見することができます。
Emacsのcompile
コマンドがデフォルトで‘-k’フラグを渡すのは
このような理由によります。
通常、コマンドが実行に失敗し、ターゲットファイルが変更された場合、
そのファイルは損なわれて使用されないことになります。あるいは少なくとも
完全にはアップデートされません。ファイルのタイムスタンプが
アップデートすべきタイミングだと告げても、次回のmake
の実行時に
アップデートは行なわれません。この状況はシグナルによってコマンドが
killされた場合によく似ています
(see section make
の中断あるいはkill.)。したがって、
一般的には、ファイルの変更開始後にコマンドが失敗した場合には、
ターゲットファイルを削除するのが正しい方法でしょう。
make
は.DELETE_ON_ERROR
がターゲットになっている場合に
そのように動作します。この動作はmake
に関して好ましい動作なのですが、
歴史的な互換性のため明確に指示する必要があります。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
make
の中断あるいはkillコマンド実行時にmake
が致命的なシグナルを受け取った場合、
コマンドによってアップデートされるはずのターゲットファイルを
削除することになります。これは、ターゲットファイルがmake
の
最初のチェックから最終更新時刻が変化している場合に行なわれます。
ターゲットの削除の目的は、次回make
が動作する際に最初から
再構成することを確認することです。これはなぜかというと、コンパイラが
動作している際にCtrl-cが押されたとします。その際、‘foo.o’が
書き始められていたとします。Ctrl-cはコンパイラをkillし、結果的に
ソースファイル‘foo.c’よりも新しい最終更新時刻を持つ
不完全なファイルができてしまうことになります。しかしmake
も
またCtrl-cシグナルを受けるため、この不完全なファイルを削除します。
make
がこうしなければ、次回のmake
の呼び出し時に‘foo.o’を
アップデートしないことになります。その結果、半端なオブジェクトファイルの
リンクを試みようとしたリンカから奇妙なエラーメッセージが
示されてしまいます。
このようなターゲットファイルの削除を特別なターゲット.PRECIOUS
を
作ることで防ぐこともできます。ターゲットの再構成のまえに、make
は
.PRECIOUS
の必要条件の有無をチェックし、シグナルが発生したときに
ターゲットを削除すべきかどうかを判断します。この方法を用いる場合は、
ターゲットが自動的な流れのなかでアップデートされたり、
内容によらずに修正時刻の記録のために存在したり、トラブルのソートを
防ぐためにつねに存在しなければならないなどの場合です。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
make
の再帰的用法make
の再帰的用法とは、makefile中のコマンドとしてmake
を
用いることです。大きなシステムを作る際のさまざまなサブシステムにmakefileを
分割したい場合にこのテクニックは有益です。たとえば、サブディレクトリ
‘subdir’があってそのなかにmakefileがあり、そのなかでmake
を
実行したい場合には以下のように記述することができます。
subsystem: cd subdir && $(MAKE) |
もしくは、以下と同様です(see section オプションのサマリー.)。
subsystem: $(MAKE) -C subdir |
読者はこの例をコピーしてmake
の再帰的なコマンドを書くことができます。
しかし、それらがどのように働き、サブのmake
がトップレベルの
make
とどのように関連するのかなどを知っておく必要があります。
便利なように、GNUのmake
は変数CURDIR
をカレントの
ワーキングディレクトリのパス名にセットすることができます。-C
が
有効な場合は、オリジナルではなく新しいディレクトリのパス名を含みます。
makefileに設定された場合は、その変数の値は同じ優位性を持ちます
(デフォルトでは環境変数CURDIR
はそれをオーバーライドしません)。
注意しなければならないのは、この変数の設定はmake
の動作には
まったく影響しないということです。
5.6.1 MAKE 変数の働き | The special effects of using ‘$(MAKE)’. | |
5.6.2 サブのmake への変数の伝達 | How to communicate variables to a sub-make .
| |
5.6.3 サブのmake へのオプションの伝達 | How to communicate options to a sub-make .
| |
5.6.4 ‘--print-directory’オプション | How the ‘-w’ or ‘--print-directory’ option
helps debug use of recursive make commands.
|
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
MAKE
変数の働きmake
を再帰的に用いる場合は、以下のようにつねにMAKE
変数を用い、
コマンド‘make’は使用しません。
subsystem: cd subdir && $(MAKE) |
この変数の値はmake
が呼び出されるファイル名です。
このファイル名が‘/bin/make’である場合、実行されるコマンドは
‘cd subdir && /bin/make’です。特別なバージョンのmake
を
トップレベルのmakefileで使用する場合には、その同じバージョンが再帰的に
呼び出されます。
特別な機能として、変数MAKE
をルールのコマンドで使用する場合、
‘-t’(‘--touch’)、‘-n’(‘--just-print’)あるいは
‘-q’(‘--question’)の効果を代替します。また、MAKE
変数を使用する場合、‘+’文字をコマンド行の先頭で試用する場合と
同じ効果をもたらします。
See section コマンド実行の代替.。
上記の例で、コマンドを‘make -t’とみなしてください。(‘-t’ オプションは実際には何もコマンドを実行せずにターゲットが 最新であることにします。コマンド実行の代替. を参照。)‘-t’の通常の定義に従って、例のなかの‘make -t’ コマンドは‘subsystem’という名前のファイルを作るだけでほかには 何もしません。本当に実行したいコマンドは‘cd subdir && make -t’ のはずですが、実際にはコマンドが実行されません。
この特別な仕組みは希望どおりのことをしてくれます。それは、ルールの
コマンド行が変数MAKE
を含んでいる場合はつねに‘-t’、‘-n’、
‘-q’フラグはその行に適用されません。MAKE
を含んでいる
コマンド行は、ほとんどのコマンドが実行されないフラグの存在にかかわらず
正常に実行されます。通常のMAKEFLAGS
の仕組みは、サブのmake
に
フラグを渡します
(see section サブのmake
へのオプションの伝達.)。
したがって、ファイルのtouchやコマンドの出力の要求はサブシステムに伝達されます。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
make
への変数の伝達トップレベルのmake
の変数の値は、明示的な要求によって環境(変数)を
通してサブのmake
に渡されます。また、これらの変数はデフォルトで
サブのmake
のなかで定義されます。しかし、‘-e’スイッチを
使用しない限り、サブのmake
のmakefileによって使用されるmakefileで
指定されるものをオーバーライドしません
(see section オプションのサマリー.)。
渡された、もしくはエクスポートされた変数の値をmake
はコマンドの
実行のために環境にセットします。反対にサブのmake
は変数テーブルを
その環境を初期化に用います。
See section 環境(変数)からの変数の取得.。
明確な要求による以外は、make
は環境の初期状態で定義されるか、
あるいはコマンド行でセットされる場合にだけ変数をエクスポートします。また、
その場合は文字、数字、アンダースコアだけからなる名前となります。
シェルによっては、文字、数字、アンダースコア以外の文字からなる名前には
対処できない場合があります。
SHELL
という特別な変数とMAKEFILES
はつねにエクスポートされます
(エクスポートしないという要求がない限り)。MAKEFILES
はまた必ず
エクスポートされます。
make
はコマンド行で定義された変数の値をMAKEFILES
変数に
置くことによって、サブのmake
に自動的に渡します。
変数は、make
によってデフォルトで作成されたものである場合は通常は
渡されません
(see section 暗黙のルールで使用される変数.)。
サブのmake
はそれらの定義を自身で行ないます。
特定の変数をサブのmake
に渡したい場合は、export
ディレクティブを
以下のように用います。
export variable … |
変数のエクスポートをしたくない場合には、unexport
ディレクティブを
以下のように用います。
unexport variable … |
変数とエクスポートを同時に行なう便利な方法もあります。
export variable = value |
は、以下と同じ結果をもたらします。
variable = value export variable |
また、
export variable := value |
は、以下と同様の結果をもたらします。
variable := value export variable |
同様に
export variable += value |
は、以下とまったく同じです。
variable += value export variable |
See section 変数へのテキストの追加.。
ここで、make
のなかのexport
とunexport
ディレクティブは
シェルsh
において同じように働くことに気づくかもしれません。
デフォルトですべての変数をエクスポートさせる場合はexport
をこのように
使用できます。
export |
これは、make
に対してexport
やunexport
ディレクティブで
明確に言及されない変数をエクスポートさせるように指示します。
unexpot
ディレクティブで与えられたいかなる変数も決して
エクスポートされません。一方、デフォルトでexport
を用いて変数が
エクスポートされる場合は、英数字とアンダースコア以外の文字をを含む名前の
変数はexport
ディレクティブでとくに言及しない限り
エクスポートされることはありません。
export
ディレクティブによって起きるふるまいは、GNUのmake
の
古いバージョンではデフォルトです。makefileがこのふるまいに依存している場合で
古いバージョンのmake
との互換性を保ちたい場合には、特別なターゲット
.EXPORT_ALL_VARIABLES
をexport
ディレクティブのかわりに
記述します。そうすると、古いmake
では無視され、export
ディレクティブはシンタックスエラーを起こします。
また、unexport
を使用することで、make
がデフォルトで変数を
エクスポートしないように設定することもできます。このふるまいは
デフォルトなので、export
が以前に指定されている場合にのみ
必要になります。しかし、export
とunexport
によっていくつかの
コマンドに関しては変数をエクスポートし、ほかのコマンドに対しては
エクスポートしないということはできません。最後に現われたexport
または
unexport
ディレクティブがmake
の動作を決定します。
特殊な機能として、変数MAKELEVEL
は下位のレベルに渡される際に
変更されます。この変数の値は文字列で、レベルの深さを10進数で表わすものです。
値は、‘0’がトップレベルのmake
、‘1’がサブのmake
、
‘2’がサブのサブのmake
というぐあいです。この数値の増加は、
コマンドに対する環境へのmake
のセットが行なわれる場合に発生します。
MAKELEVEL
の主な用途は、条件ディレクティブにおいてそれをテスト
することです(see section Makefileの条件文.)。
この方法によって、makefileのふるまいを再帰的に動作するか、あるいは
直接的に動作するかを記述することができます。
また、すべてのサブのmake
のコマンドが付加的なmakefileを使用するように
変数MAKEFILES
を使用することができます。
MAKEFILE
の値は、空白で区切られたファイル名のリストで、
外部のmakefileで定義されている場合には、この変数は環境変数を通じて
渡されます。そして、事前にそれを読み込むように、サブのmake
に
対して特別なmakefileのリストを与えることになります。
See section MAKEFILES
の変数.。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
make
へのオプションの伝達‘-s’と‘-k’フラグなどは変数MAKEFLAGS
を通じてサブの
make
に自動的に渡されます。この変数はmake
により自動的に
設定され、make
が受け取ったフラグ文字になります。したがって、
‘make -ks’を実行すると、MAKEFLAGS
は‘ks’という値を
得ることになります。
結果的に、すべてのサブのmake
は自身の環境において、MAKEFLAGS
に
対する値を得ることになります。そして、あたかも引数を与えられたかのように
値とプロセスからフラグを得ることになります。
See section オプションのサマリー.。
また、コマンド行で定義された変数はMAKEFLAGS
を通じてサブの
make
に渡されます。‘=’を含むMAKEFLAGS
の値は、あたかも
コマンド行で現われたかのようにmake
が変数定義として扱います。
See section 変数のオーバーライド.。
オプション‘-C’、‘-f’、‘-o’と‘-W’はMAKEFLAGS
に
渡されず、下位のレベルにも渡されません。
‘-j’オプションは特別なケースです(see section パラレル実行.)。
なんらかの数値‘N’を設定して、OSがそれをサポートしている場合
(大部分のUnixがそうですが、それ以外はそうではありません)、親にあたる
make
とすべてのサブのmake
は‘N’個のジョブだけが同時に
動作するのを保証するように伝達します。注意すべきことは、再帰的にマークされた
(see section コマンド実行の代替.)
いかなるジョブもトータルなジョブの数にはカウント
されないことです。(いいかえれば、‘N’個のサブのmake
だけが動作し、
実際のworkのためのスロットも残されていない状態になるということです。)
読者のOSが上記のような伝達をサポートしていない場合、指定した値のかわりに、
MAKEFLAGS
に対して‘-j 1’がつねに渡されます。このことは、
‘-j’オプションがサブのmake
に渡される理由で、パラレルに
実行される要求よりも多くのジョブを得られます。数字なしで‘-j’を
与えた場合、可能な限り多くのジョブがパラレルに動作し、下位に伝達されます。
もし、ほかのフラグを下位に伝達したくない場合には、MAKEFLAGS
の値を
以下のように変更します。
subsystem: cd subdir && $(MAKE) MAKEFLAGS= |
コマンド行の変数定義は実際にはMAKEOVERRIDES
変数において現われます。
またMAKEFLAGS
はこの変数への参照を含みます。通常のように下位への
伝達を望む場合で、コマンド行の変数定義の伝達は望まない場合は、以下のように
記述します。
MAKEOVERRIDES = |
この方法はつねに有益であるとは限りませんが、システムによっては環境変数の
サイズに制限があり小さすぎる場合があり、MAKEFIL
の値を代入する際に
そのサイズを越える場合があります。‘Arg list too long’という
エラーメッセージが表示された場合はこの問題です。
(POSIX.2に対しての厳格な準拠のため、MAKEOVERRIDES
は特定のターゲット
‘.POSIX’がmakefileに現われる場合にはMAKEFLAGS
に影響を
与えませんので気にする必要はありません。)
歴史的な互換性のために、同様な変数MFLAGS
もあります。この変数は
コマンド行の変数定義を含まないことを除けば、MAKEFLAGS
と同じ値を持ち、
空でない限りつねにハイフンで始まります(‘--warn-undefined-variables’の
ように複数文字のバージョンのオプションで始まる場合だけは
ハイフンで始まります)。
subsystem: cd subdir && $(MAKE) $(MFLAGS) |
しかし、現在のMAKEFLAGS
ではこの使用法は冗長です。makefileを古い
make
プログラムと互換性を保つ場合にこの方法を使用してください。
そうしておけば、現在のmake
と同様にうまく動作するでしょう。
‘-k’のようなオプション(see section オプションのサマリー.)
を使用しmake
を実行するごとにセットしようとする場合には、
MAKEFLAGS
変数もまた有益です。使用法は環境設定のなかで
MAKEFLAGS
に値をセットするだけで、makefileに対して効果のあるように
付加的なフラグを指定します。(注意すべきことは、この方法ではMFLAGS
は
使用できないことです。この変数は互換性のためだけにあり、make
は
その値を解釈しません。)
make
がMAKEFLAGS
の値を解釈する際(環境変数またはmakefileから)
には、値の前にあるハイフンから行なわれます。そして、空白によって値を区切り、
それらをコマンド行のオプションのように解釈していきます(ただし、
‘-C’、‘-f’、‘-h’、‘-o’、‘-W’とその
ロングネームバージョンは無視されますし、不正な値に対してエラーを
返しません)。
MAKEFLAGS
を環境設定に入れる場合は、make
の動作に影響を
与えたりmakefileの目標などに影響を与えるオプションが含まれていないことを
確認する必要があります。たとえば、‘-t’、‘-n’や‘-q’オプションが
含まれている場合、よくない結果が待っていて、悩みの種に
なってしまうことでしょう。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
いくつかのレベルのmake
の再帰的呼び出しを行なう場合、‘-w’あるいは
‘--print-directory’オプションはmake
が処理を開始し終了する
それぞれのディレクトリの表示を簡単にすることができます。たとえば、
‘make -w’がディレクトリ‘/u/gnu/make’で実行される場合、
make
は次の書式で表示させることができます。
make: Entering directory `/u/gnu/make'. |
なにかを実行するまえにこのように記述し、終了したあとのために以下の ように1行記述しておきます。
make: Leaving directory `/u/gnu/make'. |
通常は、このオプションを指定する必要がありません。なぜなら、‘-C’を
使用すると自動的に‘-w’がオンになり、サブのmake
でも
そうだからです。しかし、メッセージを出さない‘-s’オプションを
つけた場合、あるいは‘--no-print-directory’を明確に指示した場合には、
make
は‘-w’を自動的にオンにはしません。
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
さまざまなターゲットを作る際にコマンドの同じシーケンスが有用な場合、
define
ディレクティブによって決まったシーケンスとして定義することが
でき、ターゲットのルールからそのシーケンスを参照することがも可能になります。
このシーケンスは実際には変数のため、ほかの変数名と矛盾しないようにしなければ
なりません。
ここにコマンドのシーケンスの定義の例があります。
define run-yacc yacc $(firstword $^) mv y.tab.c $@ endef |
ここで、run-yacc
は定義する変数名で、endef
は定義の終わりを
示します。この2つのあいだの行がコマンドになります。define
ディレクティブは参照する変数を展開せず、シーケンスにおいて
ファンクションコールも行ないません。‘$’文字、括弧、変数名などは
定義する変数の値の一部となります。
define
の完全な説明については、
See section 変数のまったく同一の定義.。
この例の最初のコマンドは、ルールがコマンドシーケンスを使用することに かかわらず、最初の必要条件としてYaccの実行を行ないます。Yaccからの 出力ファイルは‘y.tab.c’となります。2番目のコマンドはその出力を ルールのターゲットファイル名に変更します。
コマンドのシーケンスを使用するためには、ルールのコマンドに変数を代入します。
そして何かほかの変数(see section 変数参照の基礎.)
のように代用します。define
で定義された変数は再帰的に変数に
展開されるため、define
で記述された変数の参照は展開されます。
たとえば、
foo.c : foo.y $(run-yacc) |
‘foo.y’は、run-yacc
の値や‘$@’に対する‘foo.c’に
存在するときは変数‘$^’に対して代用されます。
これは実例ですが、このような特殊なものは実際にはありません。なぜならば、
make
はファイル名に基づくコマンドのこのような役割を暗黙の
ルールとして持っているからです
(see section 暗黙のルールの使用.)。
コマンドの実行に際しては、それぞれのコマンドのシーケンスは、ルールのなかで
独自に現われたかのようにタブが先頭についた形で扱われます。そして、
make
はそれぞれの行で独立したサブシェルを呼び出します。また、
コマンド行に影響を与える特別なプレフィックス文字(‘@’、‘-’と
‘+’)をそれぞれのコマンドシーケンスで用いることができます。
See section ルールのなかでのコマンドの書き方.。
以下は、このようなコマンドシーケンスの例です。
define frobnicate @echo "frobnicating target $@" frob-step-1 $< -o $@-step-1 frob-step-2 $@-step-1 -o $@ endef |
make
は最初の行すなわちecho
コマンドをエコーしませんが、
次の2つのコマンド行はエコーします。
一方、シーケンスへの参照に用いられるコマンドのプレフィックス文字は シーケンスのすべての行に適用されるため、ルールは、以下のようになります。
frob.out: frob.in @$(frobnicate) |
このように一切エコーしません。(‘@’の詳しい説明については、 See section コマンドエコー.。)
[ < ] | [ > ] | [ << ] | [上] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
何もしないコマンドを定義することが有用な場合があります。この場合、 以下のように単純に空白からなるコマンドを与えるだけでいいのです。
target: ; |
‘target’に対して空白のコマンドを与えます。または、タブ文字から始まる 空のコマンド文字列を使用することもできますが、見かけ上、何もない状態に なりますので混乱することがあります。
何もしないコマンドを定義する理由は何でしょうか。その唯一の理由は、
ターゲットが暗黙のコマンド(暗黙のルールから、あるいは.DEFAULT
の
特別なターゲットから)を得てしまうことを防ぐ意味です。.DEFAULT
の
特別なターゲットについては暗黙のルールの使用.、
最後の手段のルールの定義.を参照してください。
現実のファイルではないターゲットに対して空のコマンド文字列を定義しようと 考えても、実際には必要条件の再構成が可能なようにできるだけです。しかしながら、 この方法はベストとはいえません。なぜなら、ターゲットファイルが実際に 存在する場合には必要条件が適切に再構成できなくなるからです。 よりよい方法については、See section 偽のターゲット.。
[ << ] | [ >> ] | [冒頭] | [目次] | [見出し] | [ ? ] |
この文書は新堂 安孝によって2009年9月22日にtexi2html 1.82を用いて生成されました。