make ユーティリティーは、プログラムのコンパイルとリンク作業の効率を上げます。通常、大きなアプリケーションはいくつかのソースファイルと INCLUDE ファイルから構成され、さらに、いくつかのライブラリとリンクする必要があります。1 つまたは複数のソースファイルを変更すると、プログラムのその部分をコンパイルし、リンクし直さなければいけません。アプリケーションを構成するファイル間の相互依存性を指定し、各部分をコンパイルし、リンクし直すのに必要なコマンドを指定することによって、このプロセスを自動化できます。指令ファイル中にあるこれらの指定を使用して、 make は、コンパイルし直す必要のあるファイルだけをコンパイルし、ユーザーが実行可能ファイルの構築に必要な、オプションとライブラリを使用してリンクします。以降の節では、簡単な例を使用して make の使用法を説明します。要約については、make(1S) のマニュアルページを参照してください。
「メイクファイル」と呼ばれるファイルは、ソースファイルとオブジェクトファイルがお互いにどのように依存するかを構造化された方法で make に伝えるものです。さらに、これらのファイルをコンパイルし、リンクするのに必要なコマンドを定義します。
たとえば、4 つのソースファイルから成るプログラムとメイクファイル (ファイル名 makefile) があるとします。
demo% ls makefile commonblock computepts.f pattern.f startupcore.f demo% |
この例では、pattern.f と computepts.f が commonblock をインクルードするものと仮定します。そして、各 .f ファイルをコンパイルして、3 つの再配置可能なファイルおよび一連のライブラリを pattern というプログラムにリンクします。
この場合の makefile は次のようになります。
demo% cat makefile pattern: pattern.o computepts.o startupcore.o f95 pattern.o computepts.o startupcore.o -lcore95 \ -lcore -lsunwindow -lpixrect -o pattern pattern.o: pattern.f commonblock f95 -c -u pattern.f computepts.o: computepts.f commonblock f95 -c -u computepts.f startupcore.o: startupcore.f f95 -c -u startupcore.f demo% |
makefile の最初の行では、pattern の作成が pattern.o、computepts.o、および startupcore.o に依存することを表しています。次の行以降は、再配置可能な .o ファイルとライブラリから pattern を作成するコマンドです。
makefile の各行は、ターゲットオブジェクトの依存性を表す規則と、そのオブジェクトを作成するのに必要なコマンドです。規則の構造は次のようになります。
ターゲット: 依存性リストTAB 構築コマンド
依存性- 個々の項目は、ターゲットファイルの名前とそのターゲットが依存するすべてのファイル名を列挙した行で始まります。
コマンド- 個々の項目には、引き続く行が 1 行以上あり、この項目がターゲットとするファイルを構築する Bourne シェルコマンドを指定します。これらのコマンド行は、タブでインデントさせておきます。
make コマンドは、引数なしで、単純に次のように指定して実行できます。
demo% make |
make ユーティリティーは、現在のディレクトリから makefile または Makefile という名前のファイルを検索し、その中から指示を取り出します。
make ユーティリティーの一般的な動作は次のとおりです。
処理する必要のあるターゲットファイル、それらが依存するファイル、ターゲットファイルを構築するためのコマンドを メイクファイルから読み取る。
各ファイルが最後に変更された日付と時刻の情報を取り出す。
ターゲットファイルの変更の日付と時刻が、依存するファイルよりも古ければ、メイクファイル にあるそのターゲットに関するコマンドを使用してターゲットファイルを再度構築する。
make ユーティリティーのマクロ機能を使用すると、簡単なパラメータなしの文字列置換を行うことができます。たとえば、pattern という名のターゲットプログラムを考えてみると、それを構成する再配置可能なファイルのリストを 1 つのマクロ文字列として表現できるので、変更しやすくなります。
マクロ文字列を定義するときは、次のような形式を使用します。
名前 = 文字列
マクロ文字列を使用するときは、次のように指定します。
$(名前)
これは、make によって、マクロ文字列の実際の値に置換されます。
次の例は、すべてのオブジェクトファイルを指定するマクロ定義をメイクファイルの最初に追加します。
OBJ = pattern.o computepts.o startupcore.o |
これによって、メイクファイルの中で、このマクロを依存性リストに使用したり、ターゲット pattern の f95 リンクコマンド上で使用したりできます。
pattern: $(OBJ) f95 $(OBJ) -lcore95 -lcore -lsunwindow \ -lpixrect -o pattern |
マクロ文字列の名前が 1 文字の場合、括弧は省略できます。
make マクロの初期値は、make のコマンド行オプションで置換できます。たとえば、次のようにします。
FFLAGS=–u OBJ = pattern.o computepts.o startupcore.o pattern: $(OBJ) f95 $(FFLAGS) $(OBJ) -lcore95 -lcore -lsunwindow \ -lpixrect -o pattern pattern.o: pattern.f commonblock f95 $(FFLAGS) -c pattern.f computepts.o: f95 $(FFLAGS) -c computepts.f |
この状態で、引数なしの make コマンドを実行すると、前述の FFLAGS の値が使用されます。しかし、次のようなコマンド行を使用すると、この値を置換できます。
demo% make "FFLAGS=–u -O" |
make コマンド行上の FFLAGS マクロの定義は、メイクファイルの初期値を無効にし、-O フラグと -u フラグを f95 に渡します。また、"FFLAGS=" をコマンド行上で使用すると、マクロに NULL 文字列を指定したことになり、マクロの影響を無効にできます。
メイクファイルを簡単に書けるようにするため、make はターゲットファイルの接尾辞に従って、独自のデフォルト規則を使用します。
デフォルトの規則は /usr/share/lib/make/make.rules というファイルに定義されています。デフォルトの接尾辞規則を認識すると、make は、FFLAGS マクロで指定されたすべてのフラグと、-c フラグ、コンパイルすべきソースファイルの名前を引数として渡します。また、make.rules では、 FC によって割り当てられた名前を、使用すべき Fortran コンパイラの名前として使用します。
次の例では、この規則を 2 回利用しています。
FC = f95 OBJ = pattern.o computepts.o startupcore.o FFLAGS=–u pattern: $(OBJ) f95 $(OBJ) -lcore95 -lcore -lsunwindow \ -lpixrect -o pattern pattern.o: pattern.f commonblock f95 $(FFLAGS) -c pattern.f computepts.o: computepts.f commonblock startupcore.o: startupcore.f |
make はデフォルトの規則を使用して、computepts.f と startupcore.f をコンパイルします。
.f90 ファイルには、f95 コンパイラを起動するデフォルトの接尾辞規則があります。
しかし、FC マクロを f95 として定義しないかぎり.f ファイルと .F ファイルのデフォルトの接尾辞規則は、f95 ではなく f77 を呼び出します。
また、.f95 ファイルおよび .F95 ファイルには、現在は接尾辞規則が存在しません。.mod Fortran 95 モジュールファイルはモジュールコンパイラを起動します。これに対処するには、make が呼び出されるディレクトリに make.rules ファイルをコピーします。このコピーを変更して、.f95 と .F95 の接尾辞規則を追加し、.mod の接尾辞規則を削除します。詳細は、make(1S) のマニュアルページを参照してください。
コマンドの依存性や隠れた依存性のチェックには、特別なターゲット .KEEP_STATE を使用します。
.KEEP_STATE: ターゲットが有効な場合、make はステータスファイルと照合して、ターゲットを構築するためのコマンドをチェックします。最後に make を実行してからコマンドに変更があった場合、make はターゲットを構築し直します。
.KEEP_STATE: ターゲットが有効な場合、make は cpp(1) およびそのほかのコンパイルプロセッサからレポートを読み取って、#include ファイルなどの「隠れた」ファイルを探します。これらのファイルに関してターゲットが古い場合、make はターゲットを構築し直します。