1 Copyright (C) 2009 Tadashi Koike (T.K)
17 このプロジェクト(GAST)は、C言語で作成されたオープンソース製品の
18 コンパイル時に、なんらかの理由により、プリプロセッサで処理された
19 実際のコンパイルにかけられるソースコードも生成物として一緒に入手
20 したいというニーズがある場合、それを支援するための簡易なツールを
24 このプロジェクトで提供されるプログラムは、現在のところ以下の3つ
27 ● gast : gcc コマンドのラッパースクリプト。
29 本スクリプトに、シンボリックリンクで gcc や cc などの別名をつ
30 けて、本来のコンパイラよりも先にこのスクリプトが実行プログラム
31 として認識され起動される様に PATH 環境変数を設定して、利用し
34 本スクリプトが起動されると、以下の処理を基本的に実施します。
36 1)与えられたコマンド引数を解析し、Cソースファイルのコンパイル
37 であった場合は、与えられたコマンド引数に、-save-temps を
39 Cソースファイルのコンパイルではなかった場合(リンカーとし
40 て呼び出された場合など)は、与えれたコマンド引数そのまま
43 2)Cソースのコンパイルであった場合、プリプロセッサ処理後の
44 ソースファイルが中間ファイルとして生成される(拡張子 .i)。
45 このファイルの退避先ディレクトリが指定されていた場合、
46 そのディレクトリ配下に中間ファイルを移動する。
48 3)中間ファイルとしてアセンブラソースファイルも生成されるので
51 なお、これら機能を働かせるには、gast の動作制御用の環境変数を
52 いくつか定義する必要があります。詳細は、「6. gast 制御用環境変数」
56 コンパイラが make コマンドの配下で実施される場合は、通常の make
57 に代えて、以下に示す gast_make スクリプトの支援を必要とします。
58 これは、通常の make コマンドが、ビルドの効率化のためにコンパイル
59 処理を複数並列で実行する場合があるからです。
61 同一のソースコードが、異なるコンパイル処理においてコンパイル対象
62 としてかちあった場合、中間ファイル名が同一であることから、中間
63 ファイルの破壊が発生します。この場合、ビルド処理は失敗します。
64 オープンソース製品のビルド処理を安全に実施するためには、後述の
68 ● gast_make : make コマンドのラッパースクリプト。
70 本スクリプトに、シンボリックリンクで make や gmake などの別名
71 をつけて、本来の make コマンドよりも先にこのスクリプトが実行
72 プログラムとして認識され起動される様に PATH 環境変数を設定して、
75 本スクリプトが起動されると、以下の処理を基本的に実施します。
77 1)与えられたコマンド引数を解析し、同時に実行できるジョブ数が
78 指定されていた場合(-j<n> または --jobs=<n> オプション)、
80 ジョブ数の指定がなされていなかった場合は、与えられたコマンド
83 2)1)で加工されたコマンド引数を用いて、本来の make (or gmake)
87 ● gast_rpmbuild : rpmbuild コマンドのラッパースクリプト。
89 RedHat Enterprise Linux や CentOS, Fedora などの、パッケージを
90 RPM で管理しているシステムでは、バイナリパッケージ(RPM) を
91 ソースパッケージ(SRPM)から作成します。その際に用いられるコマンド
94 本スクリプトに、シンボリックリンクで rpmbuild と別名をつけて、
95 本来の rpmbuild コマンドよりも先にこのスクリプトが実行プログラム
96 として認識され起動される様に PATH 環境変数を設定して、利用します。
98 本スクリプトが rpmbuild 名で起動されると、以下の処理を行います。
100 1)与えられたコマンド引数を解析し、このスクリプト専用のオプション
101 引数である --save-temps-dir オプションが指定されていた場合、
102 それに続く引数を、gast(の別名としての gcc や cc) によって
103 生成されたプリプロセッサ処理済ソースファイル(=中間ファイル)
104 の退避ディレクトリと認識し、動作環境として設定する。
106 2)さらに中間ファイルの生成に必要な環境変数を定義する。
107 (PATH環境変数の変更により、ラッパースクリプトが先に認識
110 3)--save-temps-dir オプション引数をのぞくコマンドライン引数を
111 伴って、本来の rpmbuild コマンドを実行する。
115 このスクリプト群が動作するためには、環境として以下のプログラムが
120 ・bash (ver 3.0以上が望ましい)
122 また、以下のコマンドが利用可能であることを強く推奨いたします。
126 ※存在しない場合、目的のテキストファイルのフィルタリング処理を
127 bash の機能で代替え実行しますが、処理スピードが格段に遅いため
128 (コンパイル時間が通常の 10倍程度かかる)、perl が利用できる
134 本プロジェクトの成果物は、tar + gzip 形式で配布されます。 この
135 ファイルを適当なディレクトリ配下で解凍・展開すると、gast-0.1.0
136 というディレクトリが作成され、その配下に成果物であるスクリプトが
137 配置されます。 この展開されたことを以って、インストール完了と
138 します(不要となった圧縮ファイルは削除してください)。
140 <オペレーション>:以降の例では、/home/foo 配下にインストールすると
142 プロジェクト成果物は /tmp/gast-0.1.0.tar.gz で
145 $ tar -xvzf /tmp/gast-0.1.0.tar.gz
149 gast-0.1.0/gast_rpmbuild
150 gast-0.1.0/README.ja_JP.UTF-8
153 スクリプトが配置されているディレクトリに移動し、各スクリプトを
154 単独で(オプション引数なしで)実行してください。 各スクリプトは
155 自身の別名となるシンボリックリンクを同一ディレクトリ内に作成しま
158 $ cd /home/foo/gast-0.1.0
160 gast : Create symbolic link 'gcc'
161 gast : Create symbolic link 'cc'
164 gast_make : Create symbolic link 'make'
165 gast_make : Create symbolic link 'gmake'
168 gast_rpmbuild : Create symbolic link 'rpmbuild'
171 ・ここで提供されるスクリプト群は、互いが同一ディレクトリに配置
172 されることを想定した動作をします。 よって、個々のスクリプトを
173 単独で別のディレクトリに移動し実行することは、動作に影響します
176 ・ここで提供されるスクリプト群は、本来の make コマンドやコンパイラ
177 自身が配置されているディレクトリ(例:/usr/bin, /usr/local/bin)
178 に配置されることは想定していませんし、本スクリプト群の性格上、
179 禁止です。 できましたら、展開した状態のままお使いください。
181 ・当然のことですが、プロダクト全体のビルドにかかる時間は長くなり
182 ます。状況にもよりますが、通常の 1.2〜3倍程度を見積もってくだ
187 A)rpmbuil コマンドで SRPM をコンパイルして RPM を作成する場合
190 rpmbuild (=gast_rpmbuild の別名)スクリプトを、直接起動してください。
192 例)Linux カーネルの srpm のビルドの際、中間ファイルを抽出する。
193 $ /home/foo/gast-0.1.0/rpmbuild --save-temps-dir /home/foo/tmp \
194 --recompile /tmp/kernel-2.6.18-92.1.10.el5.src.rpm
196 オプションの指定方法は、通常の rpmbuild コマンドと変わりません。
197 さらに rpmbuild スクリプトは、--save-temps-dir という独自オプション
198 によって、中間ファイルの退避場所を指定できるようになっています。
199 上記の例では、/home/foo/tmp 配下に退避されます。
201 また必要に応じて、GAST_CONTENT_WITHOUT_H, GAST_CONTENT_UNIQUE
203 $ export GAST_CONTENT_WITHOUT_H=
204 $ export GAST_CONTENT_UNIQUE=
206 ------------------------------------------------------------------
208 rpmbuild は通常、ビルド作業を /usr/src/redhat などの、システムが
209 提供する作業ディレクトリで行おうとします。
210 ビルド作業を行うディレクトリを変更する場合は、以下の対処を行う
213 - ログインディレクトリ配下に、.rpmmacros ファイルを作成する。
214 - .rpmmacros ファイルに、以下のマクロ記述を追加する。
215 %_topdir <ビルド作業ディレクトリ名>
217 設定が正しく反映されているか否かは、以下のコマンドで確認できます。
218 $ rpmbuild --showrc | grep _topdir
220 .rpmmacros の記述の仕方は、/usr/lib/macros などの、デフォルトの
222 以上、CentOS 5 における実績でした。
223 ------------------------------------------------------------------
225 B)configure/make/make install タイプのオープンソース・ソフトウェアを
231 2. 本プロジェクト提供のスクリプト配置ディレクトリを、PATH 環境
232 変数の先頭に追加して、ソフトウェアをビルド
234 例)Apache HTTPD 2.2 (httpd-2.2.11.tar.gz) を /tmp 配下に展開して
238 $ tar -xvzf httpd-2.2.11.tar.gz
239 $ cd /tmp/httpd-2.2.11
240 $ ./configure --prefix=/home/foo/local
243 $ # make の前に、gast 用環境変数の設定
244 $ export GAST_ENABLE=
245 $ export GAST_SOURCE_DIR=/tmp
246 $ export GAST_SAVE_DIR=/home/foo/tmp
247 $ export GAST_CONTENT_WITHOUT_H=
248 $ export GAST_CONTENT_UNIQUE=
251 $ PATH=/home/foo/gast-0.1.0:${PATH} make
257 GAST で提供されるスクリプトを、他のビルドツールより
258 優先的に起動するための PATH 環境変数の設定は、export
259 コマンドを用いて固定的に設定してしまうことも可能です。
260 しかし GAST は、作業環境に固定的に組み入れるというよ
261 りは、必要なときに一時的に有効にする、といった用い方
262 の方が、他に影響がなくて好ましいと考えます。 よって、
263 上記のとおり、ビルド作業を行う時だけ GAST の各スクリ
264 プトが有効となるような PATH 変数の指定を行う利用法を
267 実施し終わったら、上記の環境変数は削除してください。
268 $ unset GAST_ENABLE GAST_SOURCE_DIR GAST_SAVE_DIR
269 $ unset GAST_CONTENT_WITHOUT_H GAST_CONTENT_UNIQUE
271 C)Cソースファイルを単独でコンパイルする場合
273 configure/make と実施することは変わりません。
275 また、以下のような実施方法もあります(コマンド列が長くて面倒ですが)。
277 $ GAST_ENABLE= GAST_SOURCE_DIR=/tmp GAST_SAVE_DIR=/home/foo/tmp \
278 > GAST_CONTENT_WITHOUT_H= PATH=/home/foo/gast-0.1.0:$PATH \
285 gast (gcc ラッパースクリプト) が中間ファイルを生成し退避する動作は、
286 いくつかの環境変数の設定に基づいて行われます。 gast を用いる場合は
287 あらかじめこれら環境変数の設定をおこなってください。
290 この環境変数が存在する場合(かつ値が "no" でない場合)、gast は
291 gast から起動される本来のコンパイラに、中間ファイルの生成を指示
292 するオプションを付与してコンパイルを実施します。
293 もしこの環境変数が存在しない場合には、gast は、通常のコンパイラ
294 による起動とまったく同じ振舞いをします(=中間ファイルは作成され
298 この環境変数が存在する場合でかつ、その値がディレクトリ名であった
299 場合(この時点では存在していなくても良い)、生成された中間ファイル
300 は、この指定されたディレクトリに退避されます。
301 指定されたディレクトリが存在しなかった場合には、ディレクトリは
305 この環境変数が存在しなかった場合、中間ファイルはコンパイル実行時
306 のカレントディレクトリに配置されたままとなりますが、名前だけは、
309 例)test.i ---> test.0.i
311 これは、同一のソースコードが条件を変えて複数回コンパイルされた
312 場合に、古い中間ファイルが上書きされて無くなってしまうことを
315 GAST_SOURCE_DIR=<DIR>
316 この環境変数が存在する場合でかつ、その値がディレクトリ名であった
317 場合、コンパイル対象Cソースファイルの完全パス名からこのディレク
318 トリ名が除去された相対パス名が、中間ファイルを退避する際のパス名
320 この環境変数が存在しない場合は、Cソースファイルのルート "/" から
321 の相対パスを取得して、退避ディレクトリ配下に反映されます。
323 GAST_CONTENT_WITHOUT_H
324 この環境変数が存在する場合(かつ値が "no" でない場合)、退避される
326 具体的には、プリプロセッサ処理済ソースファイルの中から、ヘッダー
327 ファイルが展開された箇所は取り除き(*1)、本来のCソースファイル部分の
328 展開結果のみが残るように保存する動作を行います。
330 (*1):ただし、ヘッダーファイルのインクルードの痕跡は残すように
331 しています。どんなヘッダファイルが関与したかは判ります。
334 通常の動作では、同一のCソースファイルがコンパイルオプションを
335 変えて何度もコンパイルがなされる場合、その各々で生成される中間
336 ファイルを、(簡易番号を付けて)その都度退避します。
337 この環境変数が存在する場合(かつ値が "no" でない場合)、異なる
338 コンパイルオプションで何度かコンパイルが行われた場合、生成される
339 中間ファイルの内容が、以前に作成されている中間ファイルの内容と
340 結果として一緒であれば、そのとき生成された中間ファイルは退避されず
341 破棄され、同一の内容が重複して退避されないようになります。
343 ※その代わり、コンパイルオプションの記録は完全には辿れなくなります。
348 1)ソースコード解析の補助として(マクロの展開結果を手軽に知りたい)。
350 マクロで定義される定数が、各OS/アーキテクチャ毎で異なって定義
351 されていて、それら定義が複雑である場合、実際のマクロが展開され
352 た結果がどのようになるのか、ソースコードの解読ではすぐには解か
354 →プリプロセッサ処理後のソースを見てみたい。
355 →GAST 環境配下でビルド処理を実施し、入手してみる。
357 2)ソースコードからエラーメッセージを収集するための解析対象として。
359 エラーメッセージの出力関数(syslog関数や printf関数、Linux
360 カーネルならば printk関数など)で出力されるメッセージを収集
361 したいが、それらがヘッダーファイル内でマクロ定義によりラップ
362 されてしまった場合、ソースコード上にはエラーメッセージ出力関数
363 は表れず、メッセージ収集から洩れる場合がある。
365 →マクロ展開済のソースコードなら、エラーメッセージ出力関数
366 が展開されているので、そこから収集すれば洩れがないだろう。
367 →マクロ展開済み(=プリプロセッサ処理後)のソースを入手したい。
368 →GAST 環境配下で、ビルド処理を実施し、入手してみる。
372 C言語で作成されたオープンソース製品のビルドに際して、用いるコンパイラ
373 のパスが、もしフルパスで指定されていた場合は、gast が介在できる余地
374 がないため、中間ファイルを取得することができません。悪しからず。
378 GAST 環境でもしオープンソース製品のビルドに失敗した場合、まずは、GAST
379 環境ではない状態で再度ビルドを試みてください。 もしそこでビルドが同じ
380 く失敗する場合は、GAST 環境の影響ではない、といえます。 逆に、GAST
381 環境でない状態ではビルドが成功する場合には、GAST 提供のプログラム(主に
382 gast スクリプト)にバグがある場合が示唆されます。ビルドエラー時には、
383 このような事象の切り分けを行ってください。