この章では、Fortran プログラミングプロジェクトに使用すると大変便利な 2 つの強力なプログラム開発ツール、make と SCCS を簡単に説明します。
現在では、make および SCCS の使用方法について、優れた本が何冊も市販されています。その中に、Andrew Oram および Steve Talbott 著の『Managing Projects with make』と Don Bolinger および Tan Bronson 著の『Applying RCS and SCCS』があります。これらはともに O'Reilly & Associates から出版されています。
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 はターゲットを構築し直します。
SCCS とは、ソースコード管理システム (Source Code Control System) のことです。SCCS には次のような機能があります。
ソースファイルの変更のレコード (変更履歴) を管理します。
複数のプログラマが、同時にソースファイルを変更することを防ぎます。
バージョンスタンプによってバージョン番号を記録します。
SCCS の基本操作は次の 3 つです。
ファイルを SCCS 管理下に置きます。
編集のためにファイルをチェックアウトします。
ファイルをチェックインします。
この節では、SCCS を使用してこれらの操作を行う方法を説明し、前のプログラムを使用した簡単な例を示します。ここでは基本的な SCCS についてだけ説明し、3 つの SCCS コマンド、create、edit、および delget だけを紹介します。
ファイルを SCCS の管理下に置くには、次の処理を行う必要があります。
SCCS ディレクトリを作成します。
SCCS ID キーワードをファイルに挿入します (任意)。
SCCS ファイルを作成します。
まず最初に、プログラム開発を行なっているディレクトリに SCCS サブディレクトリを作成しなければいけません。次のコマンドを使用します。
demo% mkdir SCCS |
なお、SCCS は必ず大文字にします。
ファイルごとにいくつかの SCCS ID キーワードを挿入する開発者もいますが、これは必須ではありません。あとで、SCCS の get または delget コマンドによってファイルがチェックインされるたびに、キーワードはバージョン番号によって識別されます。キーワードの文字列は次の 3 か所によく置かれます。
コメント行
PARAMETER 文
初期化データ
キーワードを使用する利点は、ソースリストの中にも、コンパイルされたオブジェクトプログラムの中にも、バージョン情報が現れることです。文字列 @(#) を前に付けておけば、what コマンドを使用して、オブジェクトファイル中のキーワードを出力できます。
パラメータとデータの定義文だけを含むヘッダーファイルをインクルードした場合は、初期化データの生成は行われず、ファイルに対するキーワードは、通常コメントの中か PARAMETER 文に付けられます。ASCII データファイルやメイクファイルのようなファイルの場合には、SCCS 情報はコメントに現れます。
SCCS キーワードは % キーワード % の形式で現れ、SCCS の get コマンドによって本来の値に展開されます。頻繁に使用されるキーワードは、次のとおりです。
%Z% は、what コマンドで認識される識別子文字列 @(#) に展開されます。%M% は、ソースファイルの名前に展開されます。%I% は、この SCCS が管理するファイルのバージョン番号に展開されます。%E% は、現在の日付に展開されます。
たとえば、make のコメント中で次のようなキーワードを使用すると、メイクファイルを指定することができます。
# %Z%%M% %I% %E% |
ソースファイルの startupcore.f、computepts.f、および pattern.f は、次の形式の初期化データによって指定できます。
CHARACTER*50 SCCSID DATA SCCSID/"%Z%%M% %I% %E%\n"/ |
このファイルを SCCS で処理し、コンパイルし、SCCS の what コマンドでオブジェクトファイルを処理すると、次のように表示されます。
demo% f95 -c pattern.f ... demo% what pattern pattern: pattern.f 1.2 96/06/10 |
また、get でファイルに探査するたびに自動的に更新される、CTIME という名前の PARAMETER も作成できます。
CHARACTER*(*) CTIME PARAMETER ( CTIME="%E%") |
INCLUDE ファイルは、SCCS スタンプが入っている Fortran のコメントで注釈できます。
C %Z%%M% %I% %E% |
Fortran 95 ソースコードファイルから取得した 1 文字の型成分名を使用すると、SCCS キーワード認識と競合する可能性があります。たとえば、Fortran 95 構造体成分参照 X%Y%Z は、SCCS から渡された場合、SCCS の get を実行したあとに XZ となります。ここで、Fortran 95 プログラムで SCCS を使用するとき、構造体成分を定義するのに 1 文字の英字を使用しないように注意します。たとえば、Fortran 95 プログラムの構造体参照が X%YY%Z の場合、%YY% は SCCS によりキーワード参照として解釈されません。そのほかの方法としては、SCCS で get -k オプションを指定すると、SCCS キーワード ID を拡張しなくてもファイルが取得されます。
これで、SCCS の create コマンドによって、これらのファイルを SCCS の管理下に置くことができます。
demo% sccs create makefile commonblock startupcore.f \ computepts.f pattern.f demo% |
ソースコードを SCCS 管理下に置いたあとは、ユーザーは SCCS を 2 つの主な作業に使用します。 編集を可能にするためにファイルをチェックアウトすることと、編集の完了したファイルをチェックインすることです。
ファイルのチェックアウトには、sccs edit コマンドを使用します。たとえば、次のようにします。
demo% sccs edit computepts.f |
この例では、SCCS は computepts.f の書き込み可能なコピーを現在のディレクトリに作成し、ユーザーのログイン名を記録します。あるユーザーがファイルをチェックアウトしている間、ほかのユーザーはそのファイルをチェックアウトできません。 しかし、ほかのユーザーは、誰がそのファイルをチェックアウトしているかを知ることはできます。
編集が完了したら、sccs delget コマンドを使用して、修正したファイルをチェックインします。たとえば、次のとおりです。
demo% sccs delget computepts.f |
このコマンドを実行すると、SCCS システムは次の作業を行います。
ログイン名を比較して、ユーザーがそのファイルをチェックアウトしたユーザーかどうかを確認する。
変更に関するコメントを入力するようにユーザーに求める。
この編集セッションで何が変更されたかを記録する。
現在のディレクトリから computepts.f の書き込み可能なコピーを削除する。
書き込み可能なコピーを、SCCS キーワードが展開された読み取り専用のコピーで置き換える。
sccs delget コマンドは、より簡単な SCCS の 2 つのコマンド、delta と get を組み合わせたものです。delta コマンドが前述の項目のうちの最初の 3 つを実行し、get コマンドが最後の 2 つの作業を実行します。