Sun WorkShop TeamWare ユーザーズガイド |
第 10 章
dmake
ユーティリティの使用この章では、分散メーク (
dmake
) ユーティリティで構築プロセスを複数のホストに分散し、複数のワークステーションやマルチプロセッサ上で並列的にプログラムを構築する方法について説明します。
dmake
の基礎分散メーク (
dmake
) を使用して、多数のプログラムから構成される大規模なプロジェクトを構築する処理を、複数のワークステーション上、またはマルチプロセッサシステムの複数の CPU 上に分散できます。dmake
ユーティリティは、メークファイルを解析して次のことを行います。
dmake
ユーティリティは、make
ユーティリティのスーパーセットです。
dmake
を理解するためには、次の事柄についての知識が必要です。構成ファイル
dmake
ユーティリティは、どの構築サーバーにジョブを分散するか、また各サーバーにどれだけのジョブを分散するかを決定する際に、2 つのファイルを参照します。実行時構成ファイル
dmake
ユーティリティは、dmake
ホスト上の実行時構成ファイルから、ジョブの分散先に関する情報を得ます。通常、このファイルはdmake
ホストのホームディレクトリに.dmakerc
という名前で格納されています。このファイルには、構築サーバーおよび各構築サーバーに分散できるジョブ数が記述されています。詳細は、「dmake ホスト」を参照してください。構築サーバーの構成ファイル
それぞれの分散構築に使用する構築サーバーには、必ず
/etc/opt/SPROdmake/dmake.conf
ファイルが存在している必要があります。このファイルは、dmake
ユーザーが全体として各構築サーバーに割り当てることができるdmake
ジョブの最大数を指定します。また、すべてのdmake
ジョブの実行に適用されるnice
優先度も指定できます。詳細は、「構築サーバー」を参照してください。
dmake
ホスト
dmake
ホストとは、dmake
コマンドが最初に起動されるマシンです。dmake
ユーティリティは、実行時構成ファイルの内容に基づいて、ジョブをどこに分散するかを決定します。一般に、このファイルは、dmake
ホストのホームディレクトリ内に、.dmakerc
という名前で置かれている必要があります。dmake
ユーティリティは、以下の順序で実行時構成ファイルを探します。
- コマンド行で
-c
オプションを使用して指定されたパス名DMAKE_RCFILE
という名のメークファイルマクロを使用して指定されたパス名DMAKE_RCFILE
環境変数を使用して指定されたパス名$(HOME)/.dmakerc
実行時構成ファイルが見つからない場合、
dmake
ユーティリティはdmake
ホストに 2 つのジョブを割り当てます。実行時構成ファイルによって、各構築サーバーのリストと各構築サーバーに分散するジョブの数を指定できます。次に、
.dmakerc
ファイルの例を示します。
コード例 10-1
# My machine. This entry causes dmake to distribute to it.falcon { jobs = 1 }hawkeagle { jobs = 3 }# Manager's machine. She's usually at meetingshero { jobs = 4 }avocetdmakerc
ファイル
falcon
、hawk
、eagle
、heron
、avocet
は、構築サーバーのリストです。- 構築サーバーごとに、分散するジョブ数を指定できます。デフォルトのジョブ数は 2 です。
- "#" の文字で始まる行は、コメントとして解釈されます。
注 - 上記のコード例の構築サーバーのリストには、dmake
ホストでもあるfalcon
が含まれています。dmake
ホストも構築サーバーとして指定できます。実行時構成ファイルにdmake
ホストを指定しなかった場合、dmake
ホストにはdmake
ジョブは分散されません。
実行時構成ファイルには、構築サーバーのグループを設定することもできます。この方法によって、状況に応じて構築サーバーのグループを簡単に切り替えることができます。たとえば、異なるオペレーティングシステムでの構築処理ごとにユーザーが構築サーバーグループを定義したり、特殊なソフトウェアがインストールされている構築サーバーのグループを定義したりできます。
次に、構築サーバーのグループが定義されている実行時構成ファイルの例を示します。
- グループであることが
group
命令によって定義され、そのメンバーのリストが中括弧 ({}) で囲まれています。- グループのメンバーになる構築サーバーは、
host
指令によって指定されます。- グループをほかのグループのメンバーにすることもできます。
- 構築サーバーのグループが指定されている実行時構成ファイルに、個別に構築サーバーを指定することもできます。この場合、
dmake
は、個別に指定された構築サーバーを名前が指定されていないグループのメンバーとして扱います。
dmake
ユーティリティは、次の優先順位に従ってジョブを分散します。
- コマンド行で
-g
オプションの引数として指定されたグループDMAKE_GROUP
という名のメークファイルマクロを使用して指定されたグループDMAKE_GROUP
環境変数を使用して指定されたグループ- 実行時構成ファイルで最初に指定されたグループ
dmake
ユーティリティは、構築サーバーごとに異なる実行パスを指定できます。デフォルトでは、dmake
は、dmake
ホストと同じ論理パスを使用して、構築サーバー上のdmake
サポートバイナリファイルを検索します。次のように、.dmakerc
ファイルで構築サーバー用の別のパスをホスト属性として指定できます。
group lab1 {host falcon { jobs = 10 , path = "/set/dist/sparc-S2/bin" }host hawk { path = "/opt/SUNWspro/bin" }}
.dmakerc
ファイルでは、グループ名およびホスト名を二重引用符で囲むことができます。文字列の一部として二重引用符を使用することで、グループおよびホストに付ける名前の制約が緩和されます。数字も英字と同様に使用できるようになります。数字で始まる名前は、次のように、二重引用符で囲む必要があります。
group "123_lab" {host "456_hawk" { path = "/opt/SUNWspro/bin" }}構築サーバー
構築サーバーのファイルシステム内に
/etc/opt/SPROdmake/dmake.conf
というファイルがあります。このファイルは、この構築サーバーでユーザーが全体として並行して実行できるdmake
ジョブの最大数を指定するために使用します。また、すべてのdmake
ジョブの実行に適用されるnice
優先度も指定できます。次に/etc/opt/SPROdmake/dmake.conf
ファイルの例を示します。このファイルでは、1 つの構築サーバーで実行可能な (すべてのdmake
ユーザーからの)dmake
ジョブの最大数を、 8 に設定しています。
max_jobs: 8nice_prio: 5
注 - 構築サーバーに/etc/opt/SPROdmake/dmake.conf
ファイルが存在しない場合、そのサーバーで、dmake
ジョブを実行することはできません。
dmake
ユーティリティについて分散メークを実行するには、標準の
make
ユーティリティの代わりに、dmake
を使用します。dmake
を使用する前に、Solaris のmake
ユーティリティを理解しておく必要があります。make
ユーティリティについての詳細は、Solaris の『プログラミングユーティリティ』を参照してください。make
ユーティリティを使用している場合、ほとんど変更なしでdmake
を使用できます。
dmake
ユーティリティがメークファイルに与える影響この節では、
dmake
で解決可能な種類の問題を例に挙げて説明します。手続きが複雑になるにしたがって、それらを実装するメークファイルの内容も複雑になります。適切なメークファイルをもたらす方法を知る必要があります。この節では、一般的なコード開発の例を挙げ、dmake
を使用して作業を簡略化する方法を説明します。メークファイルテンプレートの使用
プロジェクトを開始する時点でメークファイルテンプレートを使用することがわかっている場合は、メークファイルテンプレートをカスタマイズして独自のメークファイルを作成すると、次の利点があります。
メークファイルの編集にかかる時間を節約し、プログラムやプロジェクトの開発により多くの時間を費やすことができます。
ターゲットの並列構築
一般的に、大規模なソフトウェア開発プロジェクトは、並列して構築できる独立した多数のモジュールで構成されています。
dmake
ユーティリティは、ネットワークにまたがった複数のマシン上でのターゲットの並列処理を行うことができます。こうした並列処理により、大規模な開発プロジェクトを構築するのに必要な時間が大幅に省けます。
dmake
は、構築するターゲットが与えられると、そのターゲットに関連する依存関係を調べ、古くなっている依存関係を構築します。この依存関係の構築では、依存関係の依存関係の構築を伴うこともあります。ジョブを分散する際、dmake
は開始可能なすべてのターゲットを開始します。それらのターゲットが終了すると、dmake
はその他のターゲットを起動します。デフォルトでは、入れ子構造になったdmake
の呼び出しは同時には実行されません。ただし、この設定は変更可能です (詳細は、「並列処理に対する制限」を参照)。
dmake
では複数のターゲットが並列に構築されるため、各構築プロセスの出力は同時に生成されます。各コマンドからの出力が混ざらないよう、dmake
では各構築の出力を個別に収集します。またdmake
は、コマンドを実行する前に、そのコマンドの内容を表示します。実行したコマンドによって出力、警告、またはエラーが生成されると、dmake
ユーティリティは該当するコマンドの出力全体を表示します。後から開始したコマンドが先行するコマンドよりも先に終了することもあるので、出力の順序が予想と異なる場合があります。メークファイルに関する制限事項
複数のターゲットを同時に構築する場合は、メークファイルに多少の制限が伴います。たとえば、暗黙の依存関係の順序に依存しているメークファイルは、並列構築を行なったとき正しく機能しないことがあります。また、同じファイルを修正する複数のターゲットは、そのファイルが 2 つの異なるターゲットによって同時に変更されると失敗することがあります。この節では、こうした問題の例を取り上げます。
依存関係リスト
ターゲットを並列構築するときは、依存関係リストが正確であることが重要なポイントになります。たとえば、 2 つの実行可能ファイルが同じオブジェクトファイルを共有しているときに、一方のファイルでしか依存関係が指定されていないと、並列構築がエラーになる可能性があります。次のメークファイルの例を考えてみます。
all: prog1 prog2prog1: prog1.o aux.o$(LINK.c) prog1.o aux.o -o prog1prog2: prog2.o$(LINK.c) prog2.o aux.o -o prog2逐次構築では、ターゲット
aux.o
はprog1
に依存するファイルとして構築され、prog2
の構築時に更新されます。これに対し、並列構築では、prog2
のリンクが、aux.o
の構築前に開始されることがあり、その場合は、不正になります。make
の.KEEP_STATE
機能で検出できる依存関係も一部ありますが、上記のような関係はその対象にはなりません。依存関係リストにおける明示的な順序指定
次に、暗黙の順序にもとづく依存関係がある場合は、問題がさらに複雑になるという例を示します。たとえば、あるシステムのヘッダーをすべて作成してから構築を開始する場合は、すべての要素がこの構築に依存していなければなりません。このため、メークファイルがさらに複雑になり、新しいターゲットをメークファイルに追加した場合などにエラーが起きる可能性が高くなります。この場合は、メークファイルの中で特殊な
.WAIT
ターゲットを指定して、暗黙の依存関係があることを明示できます。dmake
は依存関係リストの中に.WAIT
ターゲットを検出すると、これまでの依存関係の処理を終了してから、以降の依存関係の処理を実行します。 1 つの依存関係リストに、複数の.WAIT
ターゲットを入れることもできます。次に、.WAIT
を使用して、まずヘッダーを作成してから、以降の処理を続行する例を示します。
all: hdrs .WAIT libs functions
.WAIT
ターゲットに対する空の規則をメークファイルに追加することによって、make
ユーティリティでも、このメークファイルを使用できます。ファイルの同時修正
ターゲットの構築プロセスでは、同時に同じファイルを修正しないように注意する必要があります。この問題は、さまざまな形で起きる可能性があります。一時ファイルを使用する新しい接尾辞の規則を定義する場合、一時ファイルの名前は、ターゲットごとに異なっていなければなりません。この場合は、
$@
や$*
の動的マクロを利用できます。たとえば、ソースファイルをコンパイルする前に.c
ファイルに修正を加える場合、.c.o
の規則は次のように定義できます。
.c.o:awk -f modify.awk $*.c > $*.mod.c$(COMPILE.c) $*.mod.c -o $*.o$(RM) $*.mod.cライブラリの同時更新
並列処理でもう 1 つの問題になる可能性があるのは、ライブラリを作成するときのデフォルトの規則です。すなわち、ライブラリという固定ファイルが変更される場合があるということです。本来適用されるべきでない
.c.a
規則によって、dmake
がそれぞれのオブジェクトファイルを構築し、このオブジェクトファイルをアーカイブする可能性があります。dmake
が 2 つのオブジェクトファイルを同時にアーカイブすると、並列的に更新が行われてアーカイブファイルが壊れることがあります。
.c.a:$(COMPILE.c) -o $% $<$(AR) $(ARFLAGS) $@ $%$(RM) $%この場合は、各オブジェクトファイルを構築し、その構築が完了した後、すべてのオブジェクトファイルをアーカイブするようにします。正しい接尾辞の規則と対応するライブラリの規則は次のとおりです。
.c.a:$(COMPILE.c) -o $% $<$(COMPILE.c) -o $% $<lib.a: lib.a($(OBJECTS))$(AR) $(ARFLAGS) $(OBJECTS)$(RM) $(OBJECTS)複数のターゲット
ファイルの同時更新の問題は、複数のターゲットに対して同じ規則を定義した場合にも起きます。たとえば、プログラムと
lex(1)
で使用されるヘッダーの両方を構築するyacc(1)
というプログラムがあります。 1 つの規則にもとづいて複数のターゲットファイルを構築する場合は、+
表記を使用して各ファイルを 1 つのグループとして指定する必要があります。特に、並列構築の場合に、このことが重要になります。
y.tab.c y.tab.h: parser.y$(YACC.y) parser.yこの規則は、次のように 2 つの規則が指定された場合と同等になります。
y.tab.c: parser.y$(YACC.y) parser.yy.tab.h: parser.y$(YACC.y) parser.y逐次処理の
make
は、最初の規則に基づいてy.tab.c
を作成してから、y.tab.h
が最新であり、構築の必要がないと判断します。これに対し、並列構築では、yacc
がy.tab.c
の構築を完了する前にy.tab.h
を調べるため、y.tab.h
の構築が必要であると判断し、最初のyacc
と並行して別のyacc
を起動します。両方のyacc
が同じファイル (y.tab.c
とy.tab.h
) に書き込みを行うため、これらのファイルが壊れ、不正になる可能性があります。正しい規則では、次の例に示すように、+
構文を使用して、両方のターゲットを同じ規則に従って同時に作成するように指示します。
y.tab.c + y.tab.h: parser.y$(YACC.y) parser.y並列処理に対する制限
1 つのメークファイルの中でファイルの衝突が避けられない場合があります。その 1 つの例が、C プログラムから文字列を抽出して、共有文字列を生成する
xstr(1)
コマンドです。xstr
コマンドでは、変更された C プログラムはx.c
という固定したファイルに書き込まれ、抽出した文字列はstrings
という固定ファイルに追加されます。xstr
は C ファイルごとに実行する必要があるため、次の新しい.c.o
規則がよく定義されます。
.c.o:$(CC) $(CPPFLAGS) -E $*.c | xstr -c -$(CC) $(CFLAGS) $(TARGET_ARCH) -c x.cmv x.o $*.oこの場合、各ターゲットを作成するごとに、
x.c
とstrings
という同じファイルに書き込みを行うので、dmake
ユーティリティは上の規則にもとづいてターゲットを同時に構築することはできません。また使用するファイルを変更することもできません。この場合は、.NO_PARALLEL:
という特殊なターゲットを使用して、dmake
に各ターゲットを同時に構築しないように指示できます。たとえば、.c.o
規則を使用して構築するオブジェクトをOBJECTS
マクロで定義している場合は、次のようにして、各ターゲットを逐次構築するようdmake
に指示します。
.NO_PARALLEL: $(OBJECTS)大部分のオブジェクトを逐次構築する必要がある場合は、依存関係リストを持たない
.NO_PARALLEL:
ターゲットをメークファイルに含めることによって、全オブジェクトをデフォルトで強制的に逐次処理するようにすると安全で簡単です。並列構築できるターゲットは、次のように.PARALLEL:
ターゲットに依存するファイルとして記述できます。
.NO_PARALLEL:.PARALLEL: $(LIB_OBJECT)分散メークの入れ子呼び出し
dmake
は、ほかのdmake
コマンドを呼び出すターゲットを検出した場合、そのターゲットを並列構築しないで、逐次構築します。これによって、2 つの異なるdmake
が同じディレクトリ中の同じターゲットを構築しようとするという問題を回避できます。この問題は、同じライブラリにアクセスする必要のある 2 つの異なるプログラムが並列構築された場合に起こります。各dmake
呼び出しでライブラリが最新であることを確認できる唯一の方法として、dmake
を再帰的に呼び出してライブラリを構築できます。コマンド行で$(MAKE)
マクロを指定した場合のみ、dmake
ユーティリティは入れ子呼び出しを認識できます。入れ子にしたコマンドが衝突を起こさないと分かっている場合は、
.PARALLEL:
を使用して、強制的に並列構築が行われるように設定できます。メークファイルの中に、並行して実行される入れ子のコマンドが多数含まれている場合、負荷均衡アルゴリズムが、強制的にローカルマシンに構築処理を過剰に割り当ててしまうことがあります。これによって、負荷が大きくなったり、スワップ領域が不足するなどの問題を引き起こすことがあります。こうした問題が発生した場合は、入れ子にしたコマンドを逐次実行するようにしてください。
dmake
ユーティリティの使用方法
dmake
ホストでdmake
コマンドを実行すると、構築サーバーにジョブが分散されます。また、dmake
ホストにジョブを分散することもできます。この場合、dmake
ホストも構築サーバーとみなされます。dmake
ユーティリティは、(メークファイルをもとにして) 並行構築が可能であると判断したターゲットに基づいて、ジョブを分散します。次の条件を満たしているマシンを、構築サーバーとして使用できます。
dmake
ホスト (dmake
を実行するために使用しているマシン) からは、パスワードを入力しなくても、rsh
を使用して、リモートから構築サーバー上でコマンドを実行できる必要があります。rsh
コマンドに関する詳細は、rsh
(1) のマニュアルページを参照してください。rsh
コマンドの使用例を次に示します。
demo%rsh
build_serverwhich dmake
/opt/SUNWspro/bin/dmakedmake
がインストールされているbin
ディレクトリに、構築サーバーからアクセスできる必要があります。すべての構築サーバーが共通のdmake
インストールディレクトリを共有するようにしてください。共有ファイルシステムの作成についての詳細は、share
(1M) およびmount
(1M) のマニュアルページ、またはオペレーティングシステムの AnswerBook を参照してください。- デフォルトでは、
dmake
は、dmake
ホストと構築サーバーのdmake
実行可能ファイルのパスが同じであることを前提に処理を行います。この設定を変更する場合は、実行時構成ファイルで、ホストの属性としてパス名を指定します。たとえば、次のようにパスを指定します。
group sparc-cluster {host wren { jobs = 10 , path = "/export/SUNWspro/bin"}host stimpy { path = "/opt/SUNWspro/bin" }- 構築を行うソース階層は、次の条件を満たす必要があります。
dmake
ホストから、使用する構築サーバーと各構築サーバーに割り当てるdmake
ジョブの数を制御できます。特定の構築サーバーで実行可能なdmake
ジョブの数は、その構築サーバー上でも制限できます。
-m
オプションとparallel
引数を指定した場合、またはDMAKE_MODE
変数またはマクロの値としてparallel
を設定している場合、dmake
は、実行時構成ファイルをスキャンしません。このため、ジョブの数は、-j
オプション、DMAKE_MAX_JOBS
変数またはマクロを使用して指定する必要があります。このどの方法でもジョブ数を指定しなかった場合は、デフォルトのジョブ数の 2 が使用されます。
dmake
を分散モードで使用している時に、-j
オプション、DMAKE_MAX_JOBS
変数またはマクロを使用してジョブの最大数を変更した場合、指定した値が実行時構成ファイルで設定されている値の代わりにしようされます。指定した値は、すべての構築サーバーへ分散可能なジョブ数の合計値として使用されます。「構築」ウィンドウから
dmake
を使用する場合は、オンラインヘルプで構築サーバーとジョブ数の指定方法についての説明を参照してください。コマンド行からdmake
を使用する場合は、dmake
(1) のマニュアルページ (dmake.1
) を参照してください。
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |