OSDN Git Service

翻訳し忘れていた箇所の翻訳.番号ミスの修正.
[omake-japanese/omake_trans.git] / build-examples.rst
1 .. 3-build-examples
2
3 .. index::
4    single: OMakefile
5    single: OMakeroot
6    single: OSTYPE
7 .. _label3:
8
9 3. OMakeビルドサンプル
10 ==================================
11 .. Let's explain the OMake build model a bit more. One issue that dominates this discussion is that OMake is based on global project analysis. That means you define a configuration for the entire project, and you run one instance of omake.
12
13 この章ではOMakeのビルド体系をさらにもう少し解説します。この議論を決定するただ一つの結論としては、OMakeは全体のプロジェクト解析を元にしているということです。これはあなたがプロジェクト全体の設定を決めて、そしてOMakeのインスタンスを実行することを意味しています。
14
15 .. For single-directory projects this doesn't mean much. For multi-directory projects it means a lot. With GNU make, you would usually invoke the make program recursively for each directory in the project. For example, suppose you had a project with some project root directory, containing a directory of sources src, which in turn contains subdirectories lib and main. So your project looks like this nice piece of ASCII art.
16
17 一つのディレクトリで構成されたプロジェクトではあまり意味がないかもしれませんが、多数のディレクトリからなるプロジェクトでは大きな意味を持ちます。 ``GNU make`` では、あなたは通常、プロジェクトの各々のディレクトリにおいて ``make`` プログラムを再帰的に呼び出すでしょう。例えば、あなたが現在サブディレクトリ ``lib`` と ``main`` が入っているソースディレクトリ ``src`` を含んでいるプロジェクトをいくつか持っているものとしましょう。具体的には、あなたのプロジェクト構成は以下のアスキーアートのようになります。 ::
18
19     my_project/
20     |--> Makefile
21     `--> src/
22          |---> Makefile
23          |---> lib/
24          |     |---> Makefile
25          |     `---> source files...
26          `---> main/
27                |---> Makefile
28                `---> source files...
29
30 .. Typically, with GNU make, you would start an instance of make in my_project/; this would in term start an instance of make in the src/ directory; and this would start new instances in lib/ and main/. Basically, you count up the number of Makefiles in the project, and that is the number of instances of make processes that will be created.
31
32 一般的に ``GNU make`` では、初めに ``my_project/`` の ``make`` インスタンスを呼び出します。この ``make`` インスタンスは ``src/`` ディレクトリ内の ``make`` インスタンスを呼び出し、そして ``lib/`` と ``main/`` の新しいインスタンスを呼び出します。つまり、 ``GNU make`` では単純に、プロジェクト内の ``Makefile`` の数だけ ``make`` インスタンスが生成されることになります。
33
34 .. The number of processes is no big deal with today's machines (sometimes contrary the the author's opinion, we no longer live in the 1970s). The problem with the scheme was that each make process had a separate configuration, and it took a lot of work to make sure that everything was consistent. Furthermore, suppose the programmer runs make in the main/ directory, but the lib/ is out-of-date. In this case, make would happily crank away, perhaps trying to rebuild files in lib/, perhaps just giving up.
35
36 大量のプロセスを処理することは今日のコンピュータにとってさほど大きな問題ではありません(ときどき著者の意見に反対する人もいるようですが、私たちはもはや1970年代に住んでいるわけではないのです)。この構造に関する問題としては、各々の ``make`` プロセスが分けられた設定を用いており、そしてそのすべてが調和のとれたものにするには、非常に多くの負担になってしまうという点です。さらには、プログラマが ``main/`` ディレクトリで ``make`` プログラムを実行し、 ``lib/`` がもう使われていない物である場合を考えてみましょう。この場合、 ``make`` は幸せそうにあちこちに曲がりくねった挙句、恐らく ``lib/`` をリビルドしようと奮起して、恐らく諦めることになるでしょう。
37
38 .. With OMake this changes entirely. Well, not entirely. The source structure is quite similar, we merely add some Os to the ASCII art.
39
40 OMakeではこの構造を抜本的に変更します。とは言っても実際の変更点はそれほどありません。ソース構造は非常に似通っています。私たちは単純にいくつかの"O"を以下のアスキーアートのように加えただけです。 ::
41
42     my_project/
43     |--> OMakeroot   (or Root.om)
44     |--> OMakefile
45     `--> src/
46          |---> OMakefile
47          |---> lib/
48          |     |---> OMakefile
49          |     `---> source files...
50          `---> main/
51                |---> OMakefile
52                `---> source files...
53
54 .. The role of each <dir>/OMakefile plays the same role as each <dir>/Makefile: it describes how to build the source files in <dir>. The OMakefile retains much of syntax and structure of the Makefile, but in most cases it is much simpler.
55
56 各々の ``<dir>/OMakefile`` の役割は各々の ``<dir>/Makefile`` の役割と同様で、どのように ``<dir>`` のソースファイルをビルドするのかを設定します。 ``OMakefile`` は ``Makefile`` の構造や文法を保持しておりますが、ほとんどの場合 ``make`` よりも簡単に記述することができます。
57
58 .. One minor difference is the presence of the OMakeroot in the project root. The main purpose of this file is to indicate where the project root is in the first place (in case omake is invoked from a subdirectory). The OMakeroot serves as the bootstrap file; omake starts by reading this file first. Otherwise, the syntax and evaluation of OMakeroot is no different from any other OMakefile.
59
60 一つ小さな違いがあるとすれば、プロジェクトのルートディレクトリに ``OMakeroot`` が存在している点です。このファイルの主要な目的は、第一にプロジェクトのルートディレクトリがどこにあるかを示すことです(omakeがサブディレクトリから呼び出されたときのためです)。 ``OMakeroot`` はブートストラップとして働きます。omakeはこのファイルを最初に読み込むことで実行されます。それ以外では、 ``OMakeroot`` の文法と機能は他の ``OMakefile`` と全く同様です。
61
62 .. The big difference is that OMake performs a global analysis. Here is what happens when omake starts.
63
64 *大きな* 違いは、OMakeは *グローバルな* 解析を行うという点です。以下はどのようにomakeが動作するのかを示します。
65
66 ..   1. omake locates that OMakeroot file, and reads it.
67      2. Each OMakefile points to its subdirectory OMakefiles using the .SUBDIRS target. For example, my_project/OMakefile has a rule,
68
69             .SUBDIRS: src
70
71         and the my_project/src/OMakefile has a rule,
72
73             .SUBDIRS: lib main
74
75         omake uses these rules to read and evaluate every OMakefile in the project. Reading and evaluation is fast. This part of the process is cheap.
76      3. Now that the entire configuration is read, omake determines which files are out-of-date (using a global analysis), and starts the build process. This may take a while, depending on what exactly needs to be done. 
77
78 1. omakeはOMakerootファイルがあるディレクトリに移動し、読んでいきます。
79 2. 各々の ``OMakefile`` は ``.SUBDIRS`` ターゲットを使用して ``OMakefile`` があるサブディレクトリを指し示します。例えば、 ``my_project/OMakefile`` は以下のルールを持っていたとします。 ::
80
81      .SUBDIRS: src
82
83   omakeはこれらのルールを読んで、プロジェクト内のすべてのOMakefileを評価します。読み込みや評価は高速に行われるので、このプロセスは大変ではありません。
84
85 3. 全体の設定が読まれたら、omakeはどのファイルが使われていないのかを決定し(グローバルな解析を使用します)、ビルド作業を開始します。これはどのファイルのビルドが実際に必要なのかに依存した、ビルド時間がかかります。
86
87 .. There are several advantages to this model. First, since analysis is global, it is much easier to ensure that the build configuration is consistent–after all, there is only one configuration. Another benefit is that the build configuration is inherited, and can be re-used, down the hierarchy. Typically, the root OMakefile defines some standard boilerplate and configuration, and this is inherited by subdirectories that tweak and modify it (but do not need to restate it entirely). The disadvantage of course is space, since this is global analysis after all. In practice rarely seems to be a concern; omake takes up much less space than your web browser even on large projects.
88
89 このモデルではいくつかの利点があります。初めに、解析をグローバルにしたことで、結局たった一つの設定ファイルを用いることとなり、ビルドに関する設定の一致が保証されるという点です。別の利点はビルドに関する設定が継承され、再利用可能となり、さらに階層構造となる点です。概して、ルートの ``OMakefile`` はいくつかの標準的な決まり文句と設定を定義しており、これはサブディレクトリによって継承され、調整したり、変更することができます(全体を書き換える必要はありません)。この方法の欠点は容量が増大することで、これは結局グローバルな解析を行っているためです。が、実際にはめったに考慮する必要があるようには見えません。OMakeは大きなプロジェクトにおいてさえ、あなたが使っているウェブブラウザよりもはるかに小さい容量しか使いません。
90
91 .. Some notes to the GNU/BSD make user. 
92
93 GNU/BSDのmakeユーザは以下の点を頭に留めておいてください。
94
95 ..    * OMakefiles are a lot like Makefiles. The syntax is similar, and there many of the builtin functions are similar. However, the two build systems are not the same. Some evil features (in the authors' opinions) have been dropped in OMake, and some new features have been added.
96       * OMake works the same way on all platforms, including Win32. The standard configuration does the right thing, but if you care about porting your code to multiple platforms, and you use some tricky features, you may need to condition parts of your build config on the $(OSTYPE) variable.
97       * A minor issue is that OMake dependency analysis is based on MD5 file digests. That is, dependencies are based on file contents, not file modification times. Say goodbye to false rebuilds based on spurious timestamp changes and mismatches between local time and fileserver time. 
98
99 * OMakeは ``Makefile`` と同じくらい多くのファイルを作ります。文法は似ており、makeと同様に多くのビルドイン関数が用意されています。しかしながら、この2つのビルドシステムは同じではありません。OMakeではいくつかの酷い機能(これは著者の意見です)が外されており、それに代わって新しい機能が追加されています。
100 * OMakeはWin32を含んだ、複数のプラットフォーム上で同様に動きます。あなたは複数のプラットフォーム上で動かすためにコードを変更したり、いくつかのトリッキーなテクを使ったり、 ``$(OSTYPE)`` 変数を使ってビルド設定を調節する必要はありません。
101 * OMakeの依存関係の解析はMD5によるファイルの要約を元にしています。これはつまり、依存関係の解析はファイルの『修正日時』ではなくファイルの『内容』を元にしていることを表しています。さあ、ローカル日時とファイルサーバの日時から生じるミスマッチや、間違ったタイムスタンプの変更によるビルドミスにおさらばしましょう。
102
103 .. index::
104    single: OMakeroot
105    single: OMakefile
106 .. _label3.1:
107
108 3.1  OMakeroot vs. OMakefile
109 ----------------------------------
110 .. Before we begin with examples, let's ask the first question, “What is the difference between the project root OMakeroot and OMakefile?” A short answer is, there is no difference, but you must have an OMakeroot file (or Root.om file).
111
112 さて、例を見せる前に、一つ質問をしてみましょう。それは「プロジェクトルートの ``OMakeroot`` と ``OMakefile`` の違いは何か?」というものです。その質問に関する端的な答えは「違いはないが、あなたは必ず ``OMakeroot`` ファイル(あるいは ``Root.om`` ファイル)を作らなければならない」です。
113
114 .. However, the normal style is that OMakeroot is boilerplate and is more-or-less the same for all projects. The OMakefile is where you put all your project-specific stuff.
115
116 しかしながら、通常の範囲で用いるならば ``OMakeroot`` は変更する必要のない決まり文句が並んでいるファイルであり、すべてのプロジェクトの ``OMakeroot`` は多かれ少なかれ同じような内容となるでしょう。
117
118 .. To get started, you don't have to do this yourself. In most cases you just perform the following step in your project root directory.
119
120 OMakeを始めるために、あなたがこのような決まり文句を入力する必要はありません。ほとんどの場合において、あなたは以下の手順をプロジェクトのルートディレクトリで実行するだけです。
121
122 .. Run omake --install in your project root. 
123
124 * omake --installをプロジェクトのルートで実行する。
125
126 .. This will create the initial OMakeroot and OMakefile files that you can edit to get started.
127
128 これで最初の ``OMakeroot`` と ``OMakefile`` が生成され、編集できるようになりました。
129
130 .. index::
131    single: DefineCommandVars()
132 .. _label3.2:
133
134 3.2  Cプロジェクトのサンプル
135 ------------------------------
136 .. To begin, let's start with a simple example. Let's say that we have a full directory tree, containing the following files.
137
138 OMakeを始めるためには、まず簡単なサンプルを見せるのが手っ取り早いでしょう。いま私たちは以下のファイルを含んだディレクトリツリーを持っているものとします。 ::
139
140     my_project/
141     |--> OMakeroot
142     |--> OMakefile
143     `--> src/
144          |---> OMakefile
145          |---> lib/
146          |     |---> OMakefile
147          |     |---> ouch.c
148          |     |---> ouch.h
149          |     `---> bandaid.c
150          `---> main/
151                |---> OMakefile
152                |---> horsefly.c
153                |---> horsefly.h
154                `---> main.c
155
156 .. Here is an example listing.
157
158 以下は ``OMakeroot`` , ``OMakefile`` リストのサンプルです。 ::
159
160     my_project/OMakeroot:
161         # Cアプリケーションの標準的な設定をインクルード
162         open build/C
163         
164         # コマンドライン上の変数を処理
165         DefineCommandVars()
166         
167         # このディレクトリのOMakefileをインクルード
168         .SUBDIRS: .
169
170     my_project/OMakefile:
171         # 標準的なコンパイルオプションを設定
172         CFLAGS += -g
173
174         # srcディレクトリをインクルード
175         .SUBDIRS: src
176
177     my_project/src/OMakefile:
178         # あなたの好きなようにオプションを付け加えます
179         CFLAGS += -O2
180
181         # サブディレクトリをインクルード
182         .SUBDIRS: lib main
183
184     my_project/src/lib/OMakefile:
185         # 静的ライブラリとしてライブラリをビルドします。
186         # これはUnix/OSX上ではlibbug.aとして、
187         # Win32上ではlibbug.libとしてビルドされます。
188         # 引数にはソースファイルの拡張子を入れていないことに注意してください。
189         StaticCLibrary(libbug, ouch bandaid)
190
191     my_project/src/main/OMakefile:
192         # いくつかのファイルは../libディレクトリ上の
193         # .hファイルをインクルードしています。
194         INCLUDES += ../lib
195
196         # どのライブラリに対してリンクしたいのかを指定
197         LIBS[] +=
198             ../lib/libbug
199
200         # プログラムをビルドします。
201         # Win32上ではhorsefly.exe、
202         # Unix上ではhorseflyとしてビルドされます。
203         # 最初の引数はアプリケーション名を指定します。
204         # 二番目の引数はソースファイルの配列を指定します(拡張子は抜いてください)。
205         # これらの配列はビルドするプログラムの一部となります。
206         CProgram(horsefly, horsefly main)
207
208         # デフォルトでこのプログラムをビルドします
209         # (他の引数を指定しないでomakeが実行される場合です)。
210         # EXE変数はWin32上では.exeとして定義されていますが、
211         # 他のプラットフォーム上では空の変数です。
212         .DEFAULT: horsefly$(EXE)
213
214 .. Most of the configuration here is defined in the file build/C.om (which is part of the OMake distribution). This file takes care of a lot of work, including: 
215
216 ほとんどの設定は ``build/C.om`` (これはOMakeの機能の一部です)ファイルに定義されています。このファイルはほとんどの作業の面倒を見てくれます。具体的には、
217
218 ..    * Defining the StaticCLibrary and CProgram functions, which describe the canonical way to build C libraries and programs.
219       * Defining a mechanism for scanning each of the source programs to discover dependencies. That is, it defines .SCANNER rules for C source files. 
220
221 * Cライブラリやプログラムを正当な方法でビルドするための、 ``StaticCLibrary`` と ``CProgram`` 関数を定義しています。
222 * 依存関係を特定するために各々のソースコードを調べていくメカニズムを定義しています。これはつまり、Cソースファイルのための ``.SCANNER`` ルールを定義していることを意味しています。変数はサブディレクトリにも継承されていき、例えば、 ``src/main/OMakefile`` の ``CFLAGS`` 変数の値は ``"-g -O2"`` となります。
223
224 .. index::
225    single: OCaml
226    single: OCamlLibrary()
227    single: OCamlProgram()
228 .. _label3.3:
229
230 3.3  OCamlプロジェクトのサンプル
231 ------------------------------------
232 .. Let's repeat the example, assuming we are using OCaml instead of C. This time, the directory tree looks like this.
233
234 前回のCの代わりにOCamlを使った状態で、簡単なサンプルを作ってみましょう。今回では、ディレクトリツリーは以下のようになります。 ::
235
236     my_project/
237     |--> OMakeroot
238     |--> OMakefile
239     `--> src/
240          |---> OMakefile
241          |---> lib/
242          |     |---> OMakefile
243          |     |---> ouch.ml
244          |     |---> ouch.mli
245          |     `---> bandaid.ml
246          `---> main/
247                |---> OMakefile
248                |---> horsefly.ml
249                |---> horsefly.mli
250                `---> main.ml
251
252 .. The listing is only a bit different.
253
254 ``OMakeroot`` , ``OMakefile`` のリストは前回と少し異なります。 ::
255
256     my_project/OMakeroot:
257         # OCamlアプリケーションの標準的な設定をインクルード
258         open build/OCaml
259         
260         # コマンドライン上の変数を処理
261         DefineCommandVars()
262         
263         # このディレクトリのOMakefileをインクルード
264         .SUBDIRS: .
265
266     my_project/OMakefile:
267         # 標準的なコンパイルオプションを設定
268         OCAMLFLAGS += -Wa
269
270         # バイトコードのコンパイラを使いたいですか?
271         # それともネイティブコードのコンパイラを使いたいですか?
272         # 今回は両方とも使ってみましょう。
273         NATIVE_ENABLED = true
274         BYTE_ENABLED = true
275
276         # srcディレクトリをインクルード
277         .SUBDIRS: src
278
279     my_project/src/OMakefile:
280         # サブディレクトリをインクルード
281         .SUBDIRS: lib main
282
283     my_project/src/lib/OMakefile:
284         # ネイティブコードにおいて、積極的にインライン化を行う
285         OCAMLOPTFLAGS += -inline 10
286
287         # 静的ライブラリとしてライブラリをビルドします。
288         # これはUnix/OSX上ではlibbug.aとして、
289         # Win32上ではlibbug.libとしてビルドされます。
290         # 引数にはソースファイルの拡張子を入れていないことに注意してください。
291         OCamlLibrary(libbug, ouch bandaid)
292
293     my_project/src/main/OMakefile:
294         # いくつかのファイルは../libディレクトリ上の
295         # インターフェースに依存しています。
296         OCAMLINCLUDES += ../lib
297
298         # どのライブラリに対してリンクしたいのかを指定
299         OCAML_LIBS[] +=
300             ../lib/libbug
301
302         # プログラムをビルドします。
303         # Win32上ではhorsefly.exe、
304         # Unix上ではhorseflyとしてビルドされます。
305         # 最初の引数はアプリケーション名を指定します。
306         # 二番目の引数はソースファイルの配列を指定します(拡張子は抜いてください)。
307         # これらの配列はビルドするプログラムの一部となります。
308         OCamlProgram(horsefly, horsefly main)
309
310         # デフォルトでこのプログラムをビルドします
311         # (他の引数を指定しないでomakeが実行される場合です)。
312         # EXE変数はWin32上では.exeとして定義されていますが、
313         # 他のプラットフォーム上では空の変数です。
314         .DEFAULT: horsefly$(EXE)
315
316 .. In this case, most of the configuration here is defined in the file build/OCaml.om. In this particular configuration, files in my_project/src/lib are compiled aggressively with the option -inline 10, but files in my_project/src/lib are compiled normally.
317
318 この場合、ほとんどの設定は ``build/OCaml.om`` ファイルで定義されています。今回は特に、 ``my_project/src/lib`` ファイルを ``-inline 10`` オプションを用いて積極的にコンパイルするが、 ``my_project/src/lib`` は普通にコンパイルする設定となっています。
319
320 .. _label3.4:
321
322 3.4  新しい言語を扱う
323 ------------------------
324 .. The previous two examples seem to be easy enough, but they rely on the OMake standard library (the files build/C and build/OCaml) to do all the work. What happens if we want to write a build configuration for a language that is not already supported in the OMake standard library?
325
326 前回の二つのサンプルは十分簡単なように見えますが、これはOMakeの標準ライブラリ( ``build/C`` と ``/build/OCaml`` ファイル)がすべての仕事を行ってしまったためです。もし私たちがOMakeの標準ライブラリでサポートされていないような言語のビルド設定を書こうとしたら、一体どのようにすれば良いのでしょうか?
327
328 .. For this example, let's suppose we are adopting a new language. The language uses the standard compile/link model, but is not in the OMake standard library. Specifically, let's say we have the following setup.
329
330 例えば、私たちはOMakeに新しい言語を適用させているものとしましょう。この言語は標準的なコンパイル/リンクモデルを用いていますが、OMakeの標準ライブラリには存在していません。今回は問題をはっきりさせるため、以下のように動作する手順について考えてみましょう。
331
332 ..    * Source files are defined in files with a .cat suffix (for Categorical Abstract Terminology).
333       * .cat files are compiled with the catc compiler to produce .woof files (Wicked Object-Oriented Format).
334       * .woof files are linked by the catc compiler with the -c option to produce a .dog executable (Digital Object Group). The catc also defines a -a option to combine several .woof files into a library.
335       * Each .cat can refer to other source files. If a source file a.cat contains a line open b, then a.cat depends on the file b.woof, and a.cat must be recompiled if b.woof changes. The catc function takes a -I option to define a search path for dependencies. 
336
337 * ``.cat`` 拡張子(Categorical Abstract Terminology)では複数あるファイルの中のソースファイルを定義します。
338 * ``catc`` コンパイラを用いて ``.cat`` ファイルは ``.woof`` (Wicked Object-Oriented Format)ファイルにコンパイルされます。
339 * ``.woof`` ファイルは実行可能な ``.dog`` (Digital Object Group)ファイルを生成するために、 ``-c`` オプションを用いた ``catc`` コンパイラによってリンクされます。 ``catc`` はまた ``-a`` オプションで、いくつかの ``.woof`` ファイルをライブラリに結合させることができます。
340 * 各々の ``.cat`` ファイルは他のソースファイルに関連付けることができます。もしソースファイル ``a.cat`` が行 ``open b`` を含んでいたのなら、 ``a.cat`` は ``b.woof`` ファイルに依存しており、 ``a.cat`` は ``b.woof`` が変更されたときに再コンパイルしなければなりません。 ``catc`` 関数は ``-I`` オプションで依存関係を示した行を探索することができます。
341
342 .. note::
343    訳注: これはcat, woof, dogにもじって作られた仮のソースコードであり、実際に存在しているわけではありません
344
345 .. To define a build configuration, we have to do three things. 
346
347 ビルド設定を定義するために、私たちは以下の3つの作業を行う必要があります。
348
349 ..   1. Define a .SCANNER rule for discovering dependency information for the source files.
350      2. Define a generic rule for compiling a .cat file to a .woof file.
351      3. Define a rule (as a function) for linking .woof files to produce a .dog executable. 
352
353 1. 依存関係の情報をソースファイルから探索するための ``.SCANNER`` ルールを定義する。
354 2. ``.cat`` ファイルを ``.woof`` ファイルにコンパイルするための普遍的なビルドルールを定義する。
355 3. 実行可能な ``.dog`` ファイルを生成するために、 ``.woof`` ファイルをリンクするためのルールを一つの関数として定義する。
356
357 .. Initially, these definitions will be placed in the project root OMakefile.
358
359 初めに、これらの定義はプロジェクトルートの ``OMakefile`` に置くことになります。
360
361 .. index::
362    single: 遅延評価変数
363    single: mapprefix()
364 .. _label3.4.1:
365
366 3.4.1  通常の編集ルールの定義
367 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
368 .. Let's start with part 2, defining a generic compilation rule. We'll define the build rule as an implicit rule. To handle the include path, we'll define a variable CAT_INCLUDES that specifies the include path. This will be an array of directories. To define the options, we'll use a lazy variable (Section 7.5). In case there are any other standard flags, we'll define a CAT_FLAGS variable.
369
370 さて、パート2に移って、通常の編集ルールを定義していきましょう。今回私たちはビルドルールについて、ソースコードに直接ルールを定義することにします。まずはインクルードパスを扱うために、インクルードパスを指定した変数 ``CAT_INCLUDES`` を定義します。これはディレクトリが格納されている配列です。そしてオプションを定義するために、私たちは『遅延評価変数(lazy variable)(":ref:`label7.5`"を参照)』を使用します。この場合は他にも標準的なフラグが存在していますので、 ``CAT_FLAGS`` 変数も定義することにしましょう。 ::
371
372    # 私たちは今回CATC変数ををオーバーライドしたいので、catcコマンドを定義します
373    CATC = catc
374
375    # 通常のフラグは空にします
376    CAT_FLAGS =
377    
378    # インクルードパスの辞書(通常は空です)
379    INCLUDES[] =
380
381    # インクルードパスによるインクルードオプションを計算します
382    PREFIXED_INCLUDES[] = $`(mapprefix -I, $(INCLUDES))
383
384    # 通常の方法で.woofファイルをビルドします
385    %.woof: %.cat
386        $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) -c $<
387
388 .. The final part is the build rule itself, where we call the catc compiler with the include path, and the CAT_FLAGS that have been defined. The $< variable represents the source file.
389
390 最後の部分では、インクルードパスと前に定義されている ``CAT_FLAGS`` 変数を含んだ、 ``catc`` コンパイラを呼び出すというビルドルールを定義しています。 ``$<`` 変数はソースファイル名に置き換わります。
391
392 .. index::
393    single: addsuffix()
394 .. _label3.4.2:
395
396 3.4.2  リンクするためのルールを定義
397 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
398 .. For linking, we'll define another rule describing how to perform linking. Instead of defining an implicit rule, we'll define a function that describes the linking step. The function will take two arguments; the first is the name of the executable (without suffix), and the second is the files to link (also without suffixes). Here is the code fragment.
399
400 .woofファイルをリンクするために、どのようにビルド作業を行うのかについて記述した、別のルールを記述します。ここでソースに直接ルールを定義するかわりに、リンク作業を記述した関数を定義することにします。この関数は二つの引数をとり、最初の引数は実行ファイル名(拡張子なし)で、二つ目の引数はリンクするためのファイル名(これもまた拡張子はなし)を指定します。以下はコードの断片です。 ::
401
402     # 副次的なリンクオプション
403     CAT_LINK_FLAGS =
404
405     # どのように.dogプログラムをビルドするのかを定義した関数
406     CatProgram(program, files) =
407         # 拡張子を追加
408         file_names = $(addsuffix .woof, $(files))
409         prog_name = $(addsuffix .dog, $(files))
410
411         # ビルドルール
412         $(prog_name): $(file_names)
413             $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) $(CAT_LINK_FLAGS) -o $@ $+
414
415         # プログラム名を返す
416         value $(prog_name)
417
418 .. The CAT_LINK_FLAGS variable is defined just in case we want to pass additional flags specific to the link step. Now that this function is defined, whenever we want to define a rule for building a program, we simply call the rule. The previous implicit rule specifies how to compile each source file, and the CatProgram function specifies how to build the executable.
419
420 ``CAT_LINK_FLAGS`` 変数はちょうど私たちがリンク作業において、追加フラグを渡したいような場合に定義される変数です。さて、新しく関数が定義されましたので、私たちがプログラムをビルドするためのルールを定義したいと思った場合はいつでも、単純にこの関数を呼ぶだけで完了します。前回のような暗黙のルールを記述する場合ですと、どのように各々のソースファイルがコンパイルされるのかについていちいち指定する必要がありましたが、 ``CatProgram`` 関数はどのように実行ファイルをビルドするのか指定するだけで完了します。 ::
421
422     # rover.dogプログラムをソースファイルneko.catとchat.catからビルドします。
423     # rover.dogは普通にコンパイルされます。
424     .DEFAULT: $(CatProgram rover, neko chat)
425
426 .. index::
427    single: .SCANNER
428    single: 暗黙的な依存関係
429    single: 正規表現
430    single: find-in-path()
431    single: awk()
432 .. _label3.4.3:
433
434 3.4.3  依存関係の解析
435 ^^^^^^^^^^^^^^^^^^^^^^^^^
436 .. That's it, almost. The part we left out was automated dependency scanning. This is one of the nicer features of OMake, and one that makes build specifications easier to write and more robust. Strictly speaking, it isn't required, but you definitely want to do it.
437
438 これでほとんどの作業が終わりましたが、まだ依存関係の解析を自動的に行わせる部分が残っています。これはOMakeの利点の一つであり、さらにロバストで書きやすいビルド設定を作る手助けとなっています。厳密に言うと、この箇所は必要というわけではありませんが、あなたは切実にこの機能を欲しがっていると思います。
439
440 .. The mechanism is to define a .SCANNER rule, which is like a normal rule, but it specifies how to compute dependencies, not the target itself. In this case, we want to define a .SCANNER rule of the following form.
441
442 このメカニズムは通常のルールのように、 ``.SCANNER`` ルールを定義することで得られます。しかし ``.SCANNER`` ルールはどのように依存関係を解析するのかについて指定するのであって、ターゲット自身を指定しているわけではありません。私たちは以下のような形で ``.SCANNER`` ルールを定義したいものとします。 ::
443
444     .SCANNER: %.woof: %.cat
445         <commands>
446
447 .. This rule specifies that a .woof file may have additional dependencies that can be extracted from the corresponding .cat file by executing the <commands>. The result of executing the <commands> should be a sequence of dependencies in OMake format, printed to the standard output.
448
449 このルールでは、「 ``.woof`` ファイルは収集した ``.cat`` ファイルから、 ``<commands>`` を実行することで展開できる」という、新しい依存関係を追加することを指定しています。 ``<commands>`` の実行結果は、通常の端末で出力できる、OMake形式の依存関係の配列である必要があります。
450
451 .. As we mentioned, each .cat file specifies dependencies on .woof files with an open directive. For example, if the neko.cat file contains a line open chat, then neko.woof depends on chat.woof. In this case, the <commands> should print the following line.
452
453 すでに述べた通り、各々の ``.cat`` ファイルは ``open`` 構文を用いて、 ``.woof`` ファイルに依存していることを指定していたとします。例えば、もし ``neko.cat`` ファイルが行 ``open chat`` コマンドを含んでいたとするならば、 ``neko.woof`` ファイルは ``chat.woof`` ファイルに依存しています。この場合、 ``<commands>`` は以下の行を出力しなければなりません。 ::
454
455     neko.woof: chat.woof
456
457 .. For an analogy that might make this clearer, consider the C programming language, where a .o file is produced by compiling a .c file. If a file foo.c contains a line like #include "fum.h", then foo.c should be recompiled whenever fum.h changes. That is, the file foo.o depends on the file fum.h. In the OMake parlance, this is called an implicit dependency, and the .SCANNER <commands> would print a line like the following.
458
459 この類推は、 ``.o`` ファイルが ``.c`` ファイルをコンパイルすることで生成されるC言語について考えるとより明瞭になります。もしファイル ``foo.c`` が ``#include "fum.h"`` のような行を含んでいたとすると、 ``foo.c`` は ``fum.c`` が変更されたときはいつでも再コンパイルを行う必要があります。これはつまり、ファイル ``foo.o`` がファイル ``fum.h`` に依存していることを表しています。OMakeの用語では、このことを『暗黙的な依存関係(implicit dependency)』と呼んでおり、 ``.SCANNER <commands>`` は以下のような行を出力する必要があるでしょう。 ::
460
461     foo.o: fum.h
462
463 .. Now, returning to the animal world, to compute the dependencies of neko.woof, we should scan neko.cat, line-by-line, looking for lines of the form open <name>. We could do this by writing a program, but it is easy enough to do it in omake itself. We can use the builtin awk function to scan the source file. One slight complication is that the dependencies depend on the INCLUDE path. We'll use the find-in-path function to find them. Here we go.
464
465 それでは動物の世界へと戻ってみましょう。 ``neko.woof`` の依存関係を解析するために、私たちは一行一行 ``neko.cat`` ファイルをスキャンして、 ``open <name>`` のような形の構文を含んだ行を探す必要があります。私たちはこのようなプログラムを書かなければなりませんが、OMakeはこのような作業を簡略化することができます。この例ですと、ソースファイルをスキャンする ``awk`` 関数がビルドインで用意されているので、これを使ってみましょう。一つ難しいことがあるとするならば、それは依存関係が ``INCLUDE`` パスに依存していることです。そのためにOMakeでは探索するための ``find-in-path`` 関数を用意しています。それでは以下のように書いてみます。 ::
466
467     .SCANNER: %.woof: %.cat
468         section
469             # ファイルをスキャン
470             deps[] =
471             awk($<)
472             case $'^open'
473                 deps[] += $2
474                 export
475
476             # 重複を削除し、インクルードパスのファイルを探索する
477             deps = $(find-in-path $(INCLUDES), $(set $(deps)))
478
479             # 依存関係を出力
480             println($"$@: $(deps)")
481
482 .. Let's look at the parts. First, the entire body is defined in a section because we are computing it internally, not as a sequence of shell commands.
483
484 それでは上のソースコードを見てみましょう。初めに、全体の文はシェルコマンドのシーケンスとして扱われずに内部で計算されるよう、 ``section`` 文の中で定義されています。
485
486 .. We use the deps variable to collect all the dependencies. The awk function scans the source file ($<) line-by-line. For lines that match the regular expression ^open (meaning that the line begins with the word open), we add the second word on the line to the deps variable. For example, if the input line is open chat, then we would add the chat string to the deps array. All other lines in the source file are ignored.
487
488 今回私たちはすべての依存関係を集めるために、 ``deps`` 変数を用いました。 ``awk`` 関数はソースファイル ``($<)`` を一行一行スキャンしていきます。正規表現 ``^open`` (これはこの行が単語 ``open`` で始まることを表しています)が見つかった場合、 ``deps`` 変数に二番目の単語を追加します。具体的には、入力された行が ``open chat`` であった場合、 ``deps`` 配列に ``chat`` 文字列を追加することになります。ソースファイル中のその他すべての行は無視されます。
489
490 .. Next, the $(set $(deps)) expression removes any duplicate values in the deps array (sorting the array alphabetically in the process). The find-in-path function then finds the actual location of each file in the include path.
491
492 次に、 ``$(set $(deps))`` 文によって ``deps`` 配列の重複された文字列は削除されます(このとき、アルファベット順に配列をソートします)。 ``find-in-path`` 関数はインクルードパス中の各々のファイルの絶対パスを探索します。
493
494 .. The final step is print the result as the string $"$@: $(deps)" The quotations are added to flatten the deps array to a simple string.
495
496 最後に、文字列 ``$"$@: $(deps)"`` を結果として出力します。クオーテーションには ``deps`` 配列を単純な文字列に変換した状態で追加されます。
497
498 .. _label3.4.4:
499
500 3.4.4  まとめ
501 ^^^^^^^^^^^^^^^^^^^
502 .. To complete the example, let's pull it all together into a single project, much like our previous example.
503
504 例がすべて終わったので、この成果を一つのプロジェクトにまとめてみましょう。前回の例は以下のような構成とします。 ::
505
506     my_project/
507     |--> OMakeroot
508     |--> OMakefile
509     `--> src/
510          |---> OMakefile
511          |---> lib/
512          |     |---> OMakefile
513          |     |---> neko.cat
514          |     `---> chat.cat
515          `---> main/
516                |---> OMakefile
517                `---> main.cat
518
519 .. The listing for the entire project is as follows. Here, we also include a function CatLibrary to link several .woof files into a library.
520
521 この全体のプロジェクトのリストは以下のようになります。私たちはまたライブラリにいくつかの ``.woof`` ファイルをリンクさせるために、 ``CatLibrary`` 関数を定義していることに注意してください。 ::
522
523     my_project/OMakeroot:
524         # コマンドライン上の変数を処理
525         DefineCommandVars()
526         
527         # このディレクトリのOMakefileをインクルード
528         .SUBDIRS: .
529
530     my_project/OMakefile:
531        ########################################################################
532        # .catファイルをコンパイルするための標準設定
533        #
534
535        # 私たちは今回CATC変数ををオーバーライドしたいので、catcコマンドを定義します
536        CATC = catc
537
538        # 通常のフラグは空にします
539        CAT_FLAGS =
540        
541        # インクルードパスの辞書(通常は空です)
542        INCLUDES[] =
543
544        #  インクルードパスによるインクルードオプションを計算します
545        PREFIXED_INCLUDES[] = $`(mapprefix -I, $(INCLUDES))
546
547        # .catファイルの依存関係を解析するスキャナ
548        .SCANNER: %.woof: %.cat
549             section
550                 # ファイルをスキャン
551                 deps[] =
552                 awk($<)
553                 case $'^open'
554                     deps[] += $2
555                     export
556
557                 # 重複を削除し、インクルードパスのファイルを探索する
558                 deps = $(find-in-path $(INCLUDES), $(set $(deps)))
559
560                 # 依存関係を出力
561                 println($"$@: $(deps)")
562
563        # 通常の方法で.catファイルをコンパイルする
564        %.woof: %.cat
565            $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) -c $<
566
567        # 副次的なリンクオプション
568        CAT_LINK_FLAGS =
569
570        # いくつかの.woofファイルを用いてライブラリをビルド
571        CatLibrary(lib, files) =
572            # 拡張子を追加
573            file_names = $(addsuffix .woof, $(files))
574            lib_name = $(addsuffix .woof, $(lib))
575
576            # ビルドルール
577            $(lib_name): $(file_names)
578                $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) $(CAT_LINK_FLAGS) -a $@ $+
579
580            # プログラム名を返す
581            value $(lib_name)
582
583        # どのように.dogプログラムをビルドするのかを定義した関数
584        CatProgram(program, files) =
585            # 拡張子を追加
586            file_names = $(addsuffix .woof, $(files))
587            prog_name = $(addsuffix .dog, $(program))
588
589            # ビルドルール
590            $(prog_name): $(file_names)
591                $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) $(CAT_LINK_FLAGS) -o $@ $+
592
593            # プログラム名を返す
594            value $(prog_name)
595
596        ########################################################################
597        # これで正しくプログラムが動きます
598        #
599
600        # srcサブディレクトリをインクルード
601        .SUBDIRS: src
602
603     my_project/src/OMakefile:
604        .SUBDIRS: lib main
605
606     my_project/src/lib/OMakefile:
607        CatLibrary(cats, neko chat)
608
609     my_project/src/main/OMakefile:
610        # ../libディレクトリからのインクルードを許可
611        INCLUDES[] += ../lib
612
613        # プログラムをビルド
614        .DEFAULT: $(CatProgram main, main ../cats)
615
616 .. Some notes. The configuration in the project OMakeroot defines the standard configuration, including the dependency scanner, the default rule for compiling source files, and functions for building libraries and programs.
617
618 注意点としては、 ``OMakeroot`` では依存関係の解析や、ソースファイルをコンパイルするための通常のルール、ライブラリやプログラムをビルドするいくつかの関数を含んだ、標準的な設定を定義しています。
619
620 .. These rules and functions are inherited by subdirectories, so the .SCANNER and build rules are used automatically in each subdirectory, so you don't need to repeat them.
621
622 これらのルールや関数はサブディレクトリに継承されていますので、 ``.SCANNER`` とビルドルールは自動的に各々のサブディレクトリに使われます。よってあなたはこれらを繰り返し記述する必要はありません。
623
624 .. index::
625    single: OMAKEPATH
626 .. _label3.4.5:
627
628 3.4.5  終わりに
629 ^^^^^^^^^^^^^^^^^^
630 .. At this point we are done, but there are a few things we can consider.
631
632 これで一通りの作業は終わりましたが、まだ考慮すべき点はいくつか残っています。
633
634 .. First, the rules for building cat programs is defined in the project OMakefile. If you had another cat project somewhere, you would need to copy the OMakeroot (and modify it as needed). Instead of that, you should consider moving the configuration to a shared library directory, in a file like Cat.om. That way, instead of copying the code, you could include the shared copy with an OMake command open Cat. The share directory should be added to your OMAKEPATH environment variable to ensure that omake knows how to find it.
635
636 まず、 ``cat`` プログラムをビルドするためのルールはプロジェクトの ``OMakefile`` に定義しました。もしあなたがどこか別の ``cat`` プロジェクトを持っていたとすると、 ``OMakeroot`` をコピー(そしてもし必要ならば修正も)するかもしれません。その代わりに、あなたは設定ファイルを ``Cat.om`` のように名称を変更して、ライブラリの共有ディレクトリに移すべきです。これで、コードをコピーする代わりに、OMakeコマンド ``open Cat`` を用いてインクルードできるようになります。そのためには、あなたは共有ディレクトリを ``OMAKEPATH`` 環境変数に追加することで、omakeがどこを探せば良いのか分かるようにすべきです。
637
638 .. Better yet, if you are happy with your work, consider submitting it as a standard configuration (by sending a request to omake@metaprl.org) so that others can make use of it too.
639
640 もしあなたが満足する仕事をしたのなら、標準の設定となるようにあなたの設定ファイルを送ることを考えてみてください(``omake@metaprl.org`` 宛にリクエストを送ることで)。他の人の作業を省力化することになります。
641
642 .. index::
643    single: .SUBDIRS
644    single: absname()
645 .. _label3.5:
646
647 3.5  階層構造、.SUBDIRSの内容を並列化させる
648 -------------------------------------------
649 .. Some projects have many subdirectories that all have the same configuration. For instance, suppose you have a project with many subdirectories, each containing a set of images that are to be composed into a web page. Apart from the specific images, the configuration of each file is the same.
650
651 いくつかのプロジェクトは同一の設定を有した、数多くのディレクトリで構成されているものです。例えば、あなたは現在サブディレクトリが多数あり、その各々がウェブページの画像の集合であるというプロジェクトを持っているものとしましょう。ある特定の画像を除いて、各々のファイルの設定は同一です。
652
653 .. To make this more concrete, suppose the project has four subdirectories page1, page2, page3, and page4. Each contains two files image1.jpg and image2.jpg that are part of a web page generated by a program genhtml.
654
655 この設定をより強固に構築するため、以下のような場合を考えます。まず、このプロジェクトは4つのサブディレクトリ ``page1, page2, page3, page4`` を含んでいるものとします。また、各々のサブディレクトリは二つのファイル ``image1.jpg, image2.jpg`` を含んでおり、それらはプログラム ``genhtml`` によって生成されるウェブページの一部であるとします。
656
657 .. Instead of of defining a OMakefile in each directory, we can define it as a body to the .SUBDIRS command.
658
659 各々のディレクトリ中に ``OMakefile`` を定義する代わりに、OMakeでは ``.SUBDIRS`` コマンドの内容として定義することができます。 ::
660
661     .SUBDIRS: page1 page2 page3 page4
662         index.html: image1.jpg image2jpg
663             genhtml $+ > $@
664
665 .. The body of the .SUBDIRS is interpreted exactly as if it were the OMakefile, and it can contain any of the normal statements. The body is evaluated in the subdirectory for each of the subdirectories. We can see this if we add a statement that prints the current directory ($(CWD)).
666
667 ``.SUBDIRS`` の内容は、まるで ``OMakefile`` が内部にあるかのように正確にふるまい、通常の命令を任意の数だけ実行することができます。 ``.SUBDIRS`` の内容は各々のサブディレクトリの内部で評価されます。実際に何が行われているのかについては、現在のディレクトリ名を出力する命令 ``($(CWD))`` を追加することでより分かりやすくなるでしょう。 ::
668
669     .SUBDIRS: page1 page2 page3 page4
670         println($(absname $(CWD)))
671         index.html: image1.jpg image2jpg
672             genhtml $+ > $@
673   # 出力
674     /home/jyh/.../page1
675     /home/jyh/.../page2
676     /home/jyh/.../page3
677     /home/jyh/.../page4
678
679 .. index::
680    single: glob()
681    single: ls()
682 .. _label3.5.1:
683
684 3.5.1  globパターンを扱う
685 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
686 .. Of course, this specification is quite rigid. In practice, it is likely that each subdirectory will have a different set of images, and all should be included in the web page. One of the easier solutions is to use one of the directory-listing functions, like glob or ls. The glob function takes a shell pattern, and returns an array of file with matching filenames in the current directory.
687
688 もちろん、上述した指定は非常に強固なものとなっています。実際に、各々のサブディレクトリが異なった画像の集合であり、そのすべてがウェブページに含まれているような場合でも、記述方法は似ています。この問題に対するより簡単な解法の一つは、 ``glob`` や ``ls`` のようなディレクトリのリストを出力する関数を用いることです。 ``glob`` 関数はシェルのパターンを引数に持ち、現在のディレクトリ上でマッチしているファイル名の配列を返す関数です。 ::
689
690     .SUBDIRS: page1 page2 page3 page4
691         IMAGES = $(glob *.jpg)
692         index.html: $(IMAGES)
693             genhtml $+ > $@
694
695 .. index::
696    single: include
697 .. _label3.5.2:
698
699 3.5.2  簡略化されたサブディレクトリの設定
700 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
701 .. Another option is to add a configuration file in each of the subdirectories that defines directory-specific information. For this example, we might define a file BuildInfo.om in each of the subdirectories that defines a list of images in that directory. The .SUBDIRS line is similar, but we include the BuildInfo file.
702
703 別の方法は、各々のサブディレクトリ固有の情報を定義した設定ファイルを、それぞれのディレクトリに追加することです。例えば、私たちは現在、各々のサブディレクトリ中に、ディレクトリ内部にある画像のリストを定義した ``BuildInfo.om`` ファイルを設置しているものとします。 ``.SUBDIRS`` の行は似ていますが、 ``BuildInfo`` ファイルをインクルードしている点が異なっています。 ::
704
705     .SUBDIRS: page1 page2 page3 page4
706         include BuildInfo   # IMAGES変数を定義
707
708         index.html: $(IMAGES)
709             genhtml $+ > $@
710
711 .. Where we might have the following configurations.
712
713 それぞれのBuildInfo.omの内容は以下のようになっています。 ::
714
715    page1/BuildInfo.om:
716        IMAGES[] = image.jpg
717    page2/BuildInfo.om:
718        IMAGES[] = ../common/header.jpg winlogo.jpg
719    page3/BuildInfo.om:
720        IMAGES[] = ../common/header.jpg unixlogo.jpg daemon.jpg
721    page4/BuildInfo.om:
722        IMAGES[] = fee.jpg fi.jpg foo.jpg fum.jpg
723
724 .. index::
725    single: subdirs()
726    single: find()
727    single: dirof()
728 .. _label3.5.3:
729
730 3.5.3  サブディレクトリのリストを計算
731 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
732 .. The other hardcoded specification is the list of subdirectories page1, ..., page4. Rather than editing the project OMakefile each time a directory is added, we could compute it (again with glob).
733
734 現在、サブディレクトリのリスト ``page1, ... , page4`` は直接指定しています。他のディレクトリが追加される度に ``OMakefile`` を編集するよりも、( ``glob`` を用いて)計算させたほうがはるかに合理的です。 ::
735
736     .SUBDIRS: $(glob page*)
737         index.html: $(glob *.jpg)
738             genhtml $+ > $@
739
740 .. Alternately, the directory structure may be hierarchical. Instead of using glob, we could use the subdirs function, returns each of the directories in a hierarchy. For example, this is the result of evaluating the subdirs function in the omake project root. The P option, passed as the first argument, specifies that the listing is “proper,” it should not include the omake directory itself.
741
742 ディレクトリ構造が階層的である場合を考えてみましょう。その場合 ``glob`` 関数を用いる代わりに、階層的に各々のディレクトリを返す ``subdirs`` 関数を使います。例えば、以下はOMakeプロジェクトのルート上で ``subdirs`` 関数を評価した結果です。最初の引数として渡したPオプションでは、OMakeのディレクトリ自身を含んでいない、『適切な』リストを返すことを指定しています。 ::
743
744     osh> subdirs(P, .)
745     - : <array
746             /home/jyh/.../omake/mk : Dir
747             /home/jyh/.../omake/RPM : Dir
748             ...
749             /home/jyh/.../omake/osx_resources : Dir>
750
751 .. Using subdirs, our example is now as follows.
752
753 ``subdirs`` を使用することで、上の例は以下のように表現できます。 ::
754
755     .SUBDIRS: $(subdirs P, .)
756         index.html: $(glob *.jpg)
757             genhtml $+ > $@
758
759 .. In this case, every subdirectory will be included in the project.
760
761 この場合ですと、プロジェクト中の *すべての* サブディレクトリが含まれることとなります。
762
763 .. If we are using the BuildInfo.om option. Instead of including every subdirectory, we could include only those that contain a BuildInfo.om file. For this purpose, we can use the find function, which traverses the directory hierarchy looking for files that match a test expression. In our case, we want to search for files with the name BuildInfo.om. Here is an example call.
764
765 私たちが ``BuildInfo.om`` オプションを使用する場合、すべてのサブディレクトリをインクルードする代わりに、 ``BuildInfo.om`` ファイルが含んであるディレクトリのみインクルードしたいと思うでしょう。これを実現するために、私たちはディレクトリを階層的に全走査し、特定の表現にマッチしたファイルを返す ``find`` 関数を使用します。この場合ですと、 ``BuildInfo.om`` という名前のファイルを探したいことになります。以下は ``find`` 関数を呼び出したサンプルです。 ::
766
767     osh> FILES = $(find . -name BuildInfo.om)
768     - : <array
769             /home/jyh/.../omake/doc/html/BuildInfo.om : File
770             /home/jyh/.../omake/src/BuildInfo.om : File
771             /home/jyh/.../omake/tests/simple/BuildInfo.om : File>
772     osh> DIRS = $(dirof $(FILES))
773     - : <array
774             /home/jyh/.../omake/doc/html : Dir
775             /home/jyh/.../omake/src : Dir
776             /home/jyh/.../omake/tests/simple : Dir>
777
778 .. In this example, there are three BuildInfo.om files, in the doc/html, src, and tests/simple directories. The dirof function returns the directories for each of the files.
779
780 この例では、プロジェクト中に3つの ``BuildInfo.om`` ファイルが ``doc/html, src, tests/simple`` ディレクトリに存在しています。また、 ``dirof`` 関数は各々のファイルのディレクトリを返します。
781
782 .. Returning to our original example, we modify it as follows.
783
784 先の例に戻って、私たちは以下のように修正することにしました。 ::
785
786     .SUBDIRS: $(dirof $(find . -name BuildInfo.om))
787         include BuildInfo   # IMAGES変数を定義
788
789         index.html: $(IMAGES)
790             genhtml $+ > $@
791
792 .. index::
793    single: 一時的なディレクトリ
794    single: CREATE_SUBDIRS
795 .. _label3.5.4:
796
797 3.5.4  一時的なディレクトリ
798 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
799 .. Sometimes, your project may include temporary directories–directories where you place intermediate results. these directories are deleted whenever the project is cleanup up. This means, in particular, that you can't place an OMakefile in a temporary directory, because it will be removed when the directory is removed.
800
801 時々、プロジェクトでは中間ファイルを置いておくための一時的なディレクトリが必要となる場合があります。これらの一時ディレクトリはプロジェクトがクリーンアップされたときはいつでも消去されます。これは特に、ディレクトリが消去されたら同ディレクトリの ``OMakefile`` も消去されるために、 ``OMakefile`` を一時的なディレクトリに置くべきではないことを意味しています。
802
803 .. Instead, if you need to define a configuration for any of these directories, you will need to define it using a .SUBDIRS body.
804
805 もしあなたがこれらのディレクトリに関する設定を行いたいのなら、あなたは ``OMakefile`` を設置する代わりに、 ``.SUBDIRS`` の内容について記述する必要があります。 ::
806
807     section
808         CREATE_SUBDIRS = true
809
810         .SUBDIRS: tmp
811             # MD5ハッシュを計算
812             %.digest: %.comments
813                echo $(digest $<) > $@
814
815             # ソースファイルからコメントを展開
816             %.comments: ../src/%.src
817                grep '^#' $< > $@
818
819             .DEFAULT: foo.digest
820
821     .PHONY: clean
822
823     clean:
824         rm -rf tmp
825
826 .. In this example, we define the CREATE_SUBDIRS variable as true, so that the tmp directory will be created if it does not exist. The .SUBDIRS body in this example is a bit contrived, but it illustrates the kind of specification you might expect. The clean phony-target indicates that the tmp directory should be removed when the project is cleaned up.
827
828 今回の例では、私たちは ``tmp`` ディレクトリが存在しない場合に新しくディレクトリを生成するため、 ``CREATE_SUBDIRS`` 変数を ``true`` に設定しました。 ``.SUBDIRS`` の内容は少々工夫してありますが、だいたいあなたが期待している通りに動作するはずです。 ``clean phony`` ターゲットでは、プロジェクトがクリーンアップされた場合は ``tmp`` ディレクトリが消去されるように指示しています。