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