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 (訳注: これはcat, woof, dogにもじって作られた仮のソースコードであり、実際に存在しているわけではありません)
343
344 .. To define a build configuration, we have to do three things. 
345
346 ビルド設定を定義するために、私たちは以下の3つの作業を行う必要があります。
347
348 ..   1. Define a .SCANNER rule for discovering dependency information for the source files.
349      2. Define a generic rule for compiling a .cat file to a .woof file.
350      3. Define a rule (as a function) for linking .woof files to produce a .dog executable. 
351
352 1. 依存関係の情報をソースファイルから探索するための ``.SCANNER`` ルールを定義する。
353 2. ``.cat`` ファイルを ``.woof`` ファイルにコンパイルするための普遍的なビルドルールを定義する。
354 3. 実行可能な ``.dog`` ファイルを生成するために、 ``.woof`` ファイルをリンクするためのルールを一つの関数として定義する。
355
356 .. Initially, these definitions will be placed in the project root OMakefile.
357
358 初めに、これらの定義はプロジェクトルートの ``OMakefile`` に置くことになります。
359
360 .. index::
361    single: 遅延評価変数
362    single: mapprefix()
363 .. _label3.4.1:
364
365 3.4.1  通常の編集ルールの定義
366 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
367 .. 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.
368
369 さて、パート2に移って、通常の編集ルールを定義していきましょう。今回私たちはビルドルールについて、ソースコードに直接ルールを定義することにします。まずはインクルードパスを扱うために、インクルードパスを指定した変数 ``CAT_INCLUDES`` を定義します。これはディレクトリが格納されている配列です。そしてオプションを定義するために、私たちは『遅延評価変数(lazy variable)(":ref:`label7.5`"を参照)』を使用します。この場合は他にも標準的なフラグが存在していますので、 ``CAT_FLAGS`` 変数も定義することにしましょう。 ::
370
371    # 私たちは今回CATC変数ををオーバーライドしたいので、catcコマンドを定義します
372    CATC = catc
373
374    # 通常のフラグは空にします
375    CAT_FLAGS =
376    
377    # インクルードパスの辞書(通常は空です)
378    INCLUDES[] =
379
380    # インクルードパスによるインクルードオプションを計算します
381    PREFIXED_INCLUDES[] = $`(mapprefix -I, $(INCLUDES))
382
383    # 通常の方法で.woofファイルをビルドします
384    %.woof: %.cat
385        $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) -c $<
386
387 .. 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.
388
389 最後の部分では、インクルードパスと前に定義されている ``CAT_FLAGS`` 変数を含んだ、 ``catc`` コンパイラを呼び出すというビルドルールを定義しています。 ``$<`` 変数はソースファイル名に置き換わります。
390
391 .. index::
392    single: addsuffix()
393 .. _label3.4.2:
394
395 3.4.2  リンクするためのルールを定義
396 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
397 .. 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.
398
399 .woofファイルをリンクするために、どのようにビルド作業を行うのかについて記述した、別のルールを記述します。ここでソースに直接ルールを定義するかわりに、リンク作業を記述した関数を定義することにします。この関数は二つの引数をとり、最初の引数は実行ファイル名(拡張子なし)で、二つ目の引数はリンクするためのファイル名(これもまた拡張子はなし)を指定します。以下はコードの断片です。 ::
400
401     # 副次的なリンクオプション
402     CAT_LINK_FLAGS =
403
404     # どのように.dogプログラムをビルドするのかを定義した関数
405     CatProgram(program, files) =
406         # 拡張子を追加
407         file_names = $(addsuffix .woof, $(files))
408         prog_name = $(addsuffix .dog, $(files))
409
410         # ビルドルール
411         $(prog_name): $(file_names)
412             $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) $(CAT_LINK_FLAGS) -o $@ $+
413
414         # プログラム名を返す
415         value $(prog_name)
416
417 .. 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.
418
419 ``CAT_LINK_FLAGS`` 変数はちょうど私たちがリンク作業において、追加フラグを渡したいような場合に定義される変数です。さて、新しく関数が定義されましたので、私たちがプログラムをビルドするためのルールを定義したいと思った場合はいつでも、単純にこの関数を呼ぶだけで完了します。前回のような暗黙のルールを記述する場合ですと、どのように各々のソースファイルがコンパイルされるのかについていちいち指定する必要がありましたが、 ``CatProgram`` 関数はどのように実行ファイルをビルドするのか指定するだけで完了します。 ::
420
421     # rover.dogプログラムをソースファイルneko.catとchat.catからビルドします。
422     # rover.dogは普通にコンパイルされます。
423     .DEFAULT: $(CatProgram rover, neko chat)
424
425 .. index::
426    single: .SCANNER
427    single: 暗黙的な依存関係
428    single: 正規表現
429    single: find-in-path()
430    single: awk()
431 .. _label3.4.3:
432
433 3.4.3  依存関係の解析
434 ^^^^^^^^^^^^^^^^^^^^^^^^^
435 .. 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.
436
437 これでほとんどの作業が終わりましたが、まだ依存関係の解析を自動的に行わせる部分が残っています。これはOMakeの利点の一つであり、さらにロバストで書きやすいビルド設定を作る手助けとなっています。厳密に言うと、この箇所は必要というわけではありませんが、あなたは切実にこの機能を欲しがっているでしょう。
438
439 .. 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.
440
441 このメカニズムは通常のルールのように、 ``.SCANNER`` ルールを定義することで得られます。しかし ``.SCANNER`` ルールはどのように依存関係を解析するのかについて指定するのであって、ターゲット自身を指定しているわけではありません。私たちは以下のような形で ``.SCANNER`` ルールを定義したいものとします。 ::
442
443     .SCANNER: %.woof: %.cat
444         <commands>
445
446 .. 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.
447
448 このルールは ``<commands>`` を実行することで ``.cat`` ファイルを収集し、その収集されたファイルを展開することができるいくつかの依存関係を新たに追加することのできる ``.woof`` ファイルを指定しています???。 ``<commands>`` の実行結果は、通常の端末で出力できる、OMake形式の依存関係の配列である必要があります。
449
450 .. 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.
451
452 心配している通り、各々の ``.cat`` ファイルは ``open`` 構文を用いて、 ``.woof`` ファイルに依存していることを指定していたとします。例えば、もし ``neko.cat`` ファイルが行 ``open chat`` コマンドを含んでいたとするならば、 ``neko.woof`` ファイルは ``chat.woof`` ファイルに依存しています。この場合、 ``<commands>`` は以下の行を出力しなければなりません。 ::
453
454     neko.woof: chat.woof
455
456 .. 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.
457
458 この類推は、 ``.o`` ファイルが ``.c`` ファイルをコンパイルすることで生成されるC言語について考えるとより明瞭になります。もしファイル ``foo.c`` が ``#include "fum.h"`` のような行を含んでいたとすると、 ``foo.c`` は ``fum.c`` が変更されたときはいつでも再コンパイルを行う必要があります。これはつまり、ファイル ``foo.o`` がファイル ``fum.h`` に依存していることを表しています。OMakeの用語では、このことを『暗黙的な依存関係(implicit dependency)』と呼んでおり、 ``.SCANNER <commands>`` は以下のような行を出力する必要があるでしょう。 ::
459
460     foo.o: fum.h
461
462 .. 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.
463
464 それでは動物の世界へと戻ってみましょう。 ``neko.woof`` の依存関係を解析するために、私たちは一行一行 ``neko.cat`` ファイルをスキャンして、 ``open <name>`` のような形の構文を含んだ行を探す必要があります。私たちはこのようなプログラムを書かなければなりませんが、OMakeはこのような作業を簡略化することができます。この例ですと、ソースファイルをスキャンする ``awk`` 関数がビルドインで用意されているので、これを使ってみましょう。一つ難しいことがあるとするならば、それは依存関係が ``INCLUDE`` パスに依存していることです。そのためにOMakeでは探索するための ``find-in-path`` 関数を用意しています。それでは以下のように書いてみます。 ::
465
466     .SCANNER: %.woof: %.cat
467         section
468             # ファイルをスキャン
469             deps[] =
470             awk($<)
471             case $'^open'
472                 deps[] += $2
473                 export
474
475             # 重複を削除し、インクルードパスのファイルを探索する
476             deps = $(find-in-path $(INCLUDES), $(set $(deps)))
477
478             # 依存関係を出力
479             println($"$@: $(deps)")
480
481 .. 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.
482
483 それでは上のソースコードを見てみましょう。初めに、全体の文はシェルコマンドのシーケンスとして扱われずに内部で計算されるよう、 ``section`` 文の中で定義されています。
484
485 .. 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.
486
487 今回私たちはすべての依存関係を集めるために、 ``deps`` 変数を用いました。 ``awk`` 関数はソースファイル ``($<)`` を一行一行スキャンしていきます。正規表現 ``^open`` (これはこの行が単語 ``open`` で始まることを表しています)が見つかった場合、 ``deps`` 変数に二番目の単語を追加します。具体的には、もし入力された行が ``open chat`` であった場合、 ``deps`` 配列に ``chat`` 文字列を追加することになります。ソースファイル中のその他すべての行は無視されます。
488
489 .. 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.
490
491 次に、 ``$(set $(deps))`` 文によって ``deps`` 配列の重複された文字列は削除されます(このとき、アルファベット順に配列をソートします)。 ``find-in-path`` 関数はインクルードパス中の各々のファイルの絶対パスを探索します。
492
493 .. The final step is print the result as the string $"$@: $(deps)" The quotations are added to flatten the deps array to a simple string.
494
495 最後に、文字列 ``$"$@: $(deps)"`` を結果として出力します。クオーテーションには ``deps`` 配列を単純な文字列に変換した状態で追加されます。
496
497 .. _label3.4.4:
498
499 3.4.4  まとめ
500 ^^^^^^^^^^^^^^^^^^^
501 .. To complete the example, let's pull it all together into a single project, much like our previous example.
502
503 例がすべて終わったので、この成果を一つのプロジェクトにまとめてみましょう。前回の例は以下のような構成とします。 ::
504
505     my_project/
506     |--> OMakeroot
507     |--> OMakefile
508     `--> src/
509          |---> OMakefile
510          |---> lib/
511          |     |---> OMakefile
512          |     |---> neko.cat
513          |     `---> chat.cat
514          `---> main/
515                |---> OMakefile
516                `---> main.cat
517
518 .. The listing for the entire project is as follows. Here, we also include a function CatLibrary to link several .woof files into a library.
519
520 この全体のプロジェクトのリストは以下のようになります。私たちはまたライブラリにいくつかの ``.woof`` ファイルをリンクさせるために、 ``CatLibrary`` 関数を定義していることに注意してください。 ::
521
522     my_project/OMakeroot:
523         # コマンドライン上の変数を処理
524         DefineCommandVars()
525         
526         # このディレクトリのOMakefileをインクルード
527         .SUBDIRS: .
528
529     my_project/OMakefile:
530        ########################################################################
531        # .catファイルをコンパイルするための標準設定
532        #
533
534        # 私たちは今回CATC変数ををオーバーライドしたいので、catcコマンドを定義します
535        CATC = catc
536
537        # 通常のフラグは空にします
538        CAT_FLAGS =
539        
540        # インクルードパスの辞書(通常は空です)
541        INCLUDES[] =
542
543        #  インクルードパスによるインクルードオプションを計算します
544        PREFIXED_INCLUDES[] = $`(mapprefix -I, $(INCLUDES))
545
546        # .catファイルの依存関係を解析するスキャナ
547        .SCANNER: %.woof: %.cat
548             section
549                 # ファイルをスキャン
550                 deps[] =
551                 awk($<)
552                 case $'^open'
553                     deps[] += $2
554                     export
555
556                 # 重複を削除し、インクルードパスのファイルを探索する
557                 deps = $(find-in-path $(INCLUDES), $(set $(deps)))
558
559                 # 依存関係を出力
560                 println($"$@: $(deps)")
561
562        # 通常の方法で.catファイルをコンパイルする
563        %.woof: %.cat
564            $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) -c $<
565
566        # 副次的なリンクオプション
567        CAT_LINK_FLAGS =
568
569        # いくつかの.woofファイルを用いてライブラリをビルド
570        CatLibrary(lib, files) =
571            # 拡張子を追加
572            file_names = $(addsuffix .woof, $(files))
573            lib_name = $(addsuffix .woof, $(lib))
574
575            # ビルドルール
576            $(lib_name): $(file_names)
577                $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) $(CAT_LINK_FLAGS) -a $@ $+
578
579            # プログラム名を返す
580            value $(lib_name)
581
582        # どのように.dogプログラムをビルドするのかを定義した関数
583        CatProgram(program, files) =
584            # 拡張子を追加
585            file_names = $(addsuffix .woof, $(files))
586            prog_name = $(addsuffix .dog, $(program))
587
588            # ビルドルール
589            $(prog_name): $(file_names)
590                $(CATC) $(PREFIXED_INCLUDES) $(CAT_FLAGS) $(CAT_LINK_FLAGS) -o $@ $+
591
592            # プログラム名を返す
593            value $(prog_name)
594
595        ########################################################################
596        # これで正しくプログラムが動きます
597        #
598
599        # srcサブディレクトリをインクルード
600        .SUBDIRS: src
601
602     my_project/src/OMakefile:
603        .SUBDIRS: lib main
604
605     my_project/src/lib/OMakefile:
606        CatLibrary(cats, neko chat)
607
608     my_project/src/main/OMakefile:
609        # ../libディレクトリからのインクルードを許可
610        INCLUDES[] += ../lib
611
612        # プログラムをビルド
613        .DEFAULT: $(CatProgram main, main ../cats)
614
615 .. 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.
616
617 注意点としては、 ``OMakeroot`` では依存関係の解析や、ソースファイルをコンパイルするための通常のルール、ライブラリやプログラムをビルドするいくつかの関数を含んだ、標準的な設定を定義しています。
618
619 .. 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.
620
621 これらのルールや関数はサブディレクトリに継承されていますので、 ``.SCANNER`` とビルドルールは自動的に各々のサブディレクトリに使われます。よってあなたはこれらを繰り返し記述する必要はありません。
622
623 .. index::
624    single: OMAKEPATH
625 .. _label3.4.5:
626
627 3.4.5  終わりに
628 ^^^^^^^^^^^^^^^^^^
629 .. At this point we are done, but there are a few things we can consider.
630
631 これで一通りの作業は終わりましたが、まだ考慮すべき点はいくつか残っています。
632
633 .. 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.
634
635 まず、 ``cat`` プログラムをビルドするためのルールはプロジェクトの ``OMakefile`` に定義しました。もしあなたがどこか別の ``cat`` プロジェクトを持っていた場合、 ``OMakeroot`` をコピーを(そしてもし必要ならば修正も)するかもしれません。その代わりに、あなたは設定ファイルを ``Cat.om`` のように名称を変更して、ライブラリの共有ディレクトリに移すべきです。これで、コードをコピーする代わりに、OMakeコマンド ``open Cat`` を用いてインクルードできるようになります。そのためには、あなたは共有ディレクトリを ``OMAKEPATH`` 環境変数に追加することで、omakeがどこを探せば良いのか分かるようにすべきです。
636
637 .. 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.
638
639 もしあなたがいい仕事をしたのなら、標準の設定となるようにあなたの設定ファイルを送ることを考えてみてください(``omake@metaprl.org`` 宛にリクエストを送ることで)。他の人の作業を省力化することになります。
640
641 .. index::
642    single: .SUBDIRS
643    single: absname()
644 .. _label3.5:
645
646 3.5  階層構造、.SUBDIRSの内容を並列化させる
647 -------------------------------------------
648 .. 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.
649
650 いくつかのプロジェクトは同一の設定を有した、数多くのディレクトリで構成されているものです。例えば、あなたは現在サブディレクトリが多数あり、その各々がウェブページの画像の集合であるというプロジェクトを持っているものとしましょう。ある特定の画像を除いて、各々のファイルの設定は同一です。
651
652 .. 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.
653
654 この設定をより強固に構築するため、以下のような場合を考えます。まず、このプロジェクトは4つのサブディレクトリ ``page1, page2, page3, page4`` を含んでいるものとします。また、各々のサブディレクトリは二つのファイル ``image1.jpg, image2.jpg`` を含んでおり、それらはプログラム ``genhtml`` によって生成されるウェブページの一部であるとします。
655
656 .. Instead of of defining a OMakefile in each directory, we can define it as a body to the .SUBDIRS command.
657
658 各々のディレクトリ中に ``OMakefile`` を定義する代わりに、OMakeでは ``.SUBDIRS`` コマンドの内容として定義することができます。 ::
659
660     .SUBDIRS: page1 page2 page3 page4
661         index.html: image1.jpg image2jpg
662             genhtml $+ > $@
663
664 .. 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)).
665
666 ``.SUBDIRS`` の内容は、まるで ``OMakefile`` が内部にあるかのように正確にふるまい、通常の命令を任意の数だけ実行することができます。 ``.SUBDIRS`` の内容は各々のサブディレクトリの内部で評価されます。実際に何が行われているのかについては、現在のディレクトリ名を出力する命令 ``($(CWD))`` を追加することでより分かりやすくなるでしょう。 ::
667
668     .SUBDIRS: page1 page2 page3 page4
669         println($(absname $(CWD)))
670         index.html: image1.jpg image2jpg
671             genhtml $+ > $@
672   # 出力
673     /home/jyh/.../page1
674     /home/jyh/.../page2
675     /home/jyh/.../page3
676     /home/jyh/.../page4
677
678 .. index::
679    single: glob()
680    single: ls()
681 .. _label3.5.1:
682
683 3.5.1  バイナリデータのパターン(blob patterns)を扱う
684 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
685 .. 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.
686
687 もちろん、上述した指定は非常に強固なものとなっています。実際に、各々のサブディレクトリが異なった画像の集合であり、そのすべてがウェブページに含まれているような場合でも、記述方法は似ています。この問題に対するより簡単な解法の一つは、 ``glob`` や ``ls`` のようなディレクトリのリストを出力する関数を用いることです。 ``glob`` 関数はシェルのパターンを引数に持ち、現在のディレクトリ上でマッチしているファイル名の配列を返す関数です。 ::
688
689     .SUBDIRS: page1 page2 page3 page4
690         IMAGES = $(glob *.jpg)
691         index.html: $(IMAGES)
692             genhtml $+ > $@
693
694 .. index::
695    single: include
696 .. _label3.5.2:
697
698 3.5.2  簡略化されたサブディレクトリの設定
699 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
700 .. 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.
701
702 別の方法は、各々のサブディレクトリ固有の情報を定義した設定ファイルを、それぞれのディレクトリに追加することです。例えば、私たちは現在、各々のサブディレクトリ中に、ディレクトリ内部にある画像のリストを定義した ``BuildInfo.om`` ファイルを設置しているものとします。 ``.SUBDIRS`` の行は似ていますが、 ``BuildInfo`` ファイルをインクルードしている点が異なっています。 ::
703
704     .SUBDIRS: page1 page2 page3 page4
705         include BuildInfo   # IMAGES変数を定義
706
707         index.html: $(IMAGES)
708             genhtml $+ > $@
709
710 .. Where we might have the following configurations.
711
712 それぞれのBuildInfo.omの内容は以下のようになっています。 ::
713
714    page1/BuildInfo.om:
715        IMAGES[] = image.jpg
716    page2/BuildInfo.om:
717        IMAGES[] = ../common/header.jpg winlogo.jpg
718    page3/BuildInfo.om:
719        IMAGES[] = ../common/header.jpg unixlogo.jpg daemon.jpg
720    page4/BuildInfo.om:
721        IMAGES[] = fee.jpg fi.jpg foo.jpg fum.jpg
722
723 .. index::
724    single: subdirs()
725    single: find()
726    single: dirof()
727 .. _label3.5.3:
728
729 3.5.3  サブディレクトリのリストを計算
730 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
731 .. 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).
732
733 現在、サブディレクトリのリスト ``page1, ... , page4`` は直接指定しています。他のディレクトリが追加される度に ``OMakefile`` を編集するよりも、( ``glob`` を用いて)計算させたほうがはるかに合理的です。 ::
734
735     .SUBDIRS: $(glob page*)
736         index.html: $(glob *.jpg)
737             genhtml $+ > $@
738
739 .. 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.
740
741 ディレクトリ構造が階層的である場合を考えてみましょう。その場合 ``glob`` 関数を用いる代わりに、階層的に各々のディレクトリを返す ``subdirs`` 関数を使います。例えば、以下はOMakeプロジェクトのルート上で ``subdirs`` 関数を評価した結果です。最初の引数として渡したPオプションでは、OMakeのディレクトリ自身を含んでいない、『適切な』リストを返すことを指定しています。 ::
742
743     osh> subdirs(P, .)
744     - : <array
745             /home/jyh/.../omake/mk : Dir
746             /home/jyh/.../omake/RPM : Dir
747             ...
748             /home/jyh/.../omake/osx_resources : Dir>
749
750 .. Using subdirs, our example is now as follows.
751
752 ``subdirs`` を使用することで、上の例は以下のように表現できます。 ::
753
754     .SUBDIRS: $(subdirs P, .)
755         index.html: $(glob *.jpg)
756             genhtml $+ > $@
757
758 .. In this case, every subdirectory will be included in the project.
759
760 この場合ですと、プロジェクト中の *すべての* サブディレクトリが含まれることとなります。
761
762 .. 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.
763
764 もし私たちが ``BuildInfo.om`` オプションを使用する場合、すべてのサブディレクトリをインクルードする代わりに、 ``BuildInfo.om`` ファイルが含んであるディレクトリのみインクルードしたいと思うでしょう。これを実現するために、私たちはディレクトリを階層的に全走査し、特定の表現にマッチしたファイルを返す ``find`` 関数を使用します。この場合ですと、 ``BuildInfo.om`` という名前のファイルを探したいことになります。以下は ``find`` 関数を呼び出したサンプルです。 ::
765
766     osh> FILES = $(find . -name BuildInfo.om)
767     - : <array
768             /home/jyh/.../omake/doc/html/BuildInfo.om : File
769             /home/jyh/.../omake/src/BuildInfo.om : File
770             /home/jyh/.../omake/tests/simple/BuildInfo.om : File>
771     osh> DIRS = $(dirof $(FILES))
772     - : <array
773             /home/jyh/.../omake/doc/html : Dir
774             /home/jyh/.../omake/src : Dir
775             /home/jyh/.../omake/tests/simple : Dir>
776
777 .. 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.
778
779 この例では、プロジェクト中に3つの ``BuildInfo.om`` ファイルが ``doc/html, src, tests/simple`` ディレクトリに存在しています。また、 ``dirof`` 関数は各々のファイルのディレクトリを返します。
780
781 .. Returning to our original example, we modify it as follows.
782
783 先の例に戻って、私たちは以下のように修正することにしました。 ::
784
785     .SUBDIRS: $(dirof $(find . -name BuildInfo.om))
786         include BuildInfo   # Defines the IMAGES variable
787
788         index.html: $(IMAGES)
789             genhtml $+ > $@
790
791 .. index::
792    single: 一時的なディレクトリ
793    single: CREATE_SUBDIRS
794 .. _label3.5.4:
795
796 3.5.4  一時的なディレクトリ
797 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
798 .. 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.
799
800 時々、プロジェクトでは中間ファイルを置いておくための一時的なディレクトリが必要となる場合があります。これらの一時ディレクトリはプロジェクトがクリーンアップされたときはいつでも消去されます。これは特に、ディレクトリが消去されたら同ディレクトリの ``OMakefile`` も消去されるために、 ``OMakefile`` を一時的なディレクトリに置くべきではないことを意味しています。
801
802 .. Instead, if you need to define a configuration for any of these directories, you will need to define it using a .SUBDIRS body.
803
804 もしあなたがこれらのディレクトリに関する設定を行いたいのなら、あなたは ``OMakefile`` を設置する代わりに、 ``.SUBDIRS`` の内容について記述する必要があります。 ::
805
806     section
807         CREATE_SUBDIRS = true
808
809         .SUBDIRS: tmp
810             # MD5ハッシュを計算
811             %.digest: %.comments
812                echo $(digest $<) > $@
813
814             # ソースファイルからコメントを展開
815             %.comments: ../src/%.src
816                grep '^#' $< > $@
817
818             .DEFAULT: foo.digest
819
820     .PHONY: clean
821
822     clean:
823         rm -rf tmp
824
825 .. 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.
826
827 今回の例では、私たちは ``tmp`` ディレクトリが存在しない場合に新しくディレクトリを生成するため、 ``CREATE_SUBDIRS`` 変数を ``true`` に設定しました。 ``.SUBDIRS`` の内容は少々工夫してありますが、だいたいあなたが期待している通りに動作するはずです。 ``clean phony`` ターゲットでは、プロジェクトがクリーンアップされた場合は ``tmp`` ディレクトリが消去されるように指示しています。