imakeコードリーディングメモ・プリプロセッサ部編
imakeコードリーディングメモ「プリプロセッサ部」編です。
# これまでの道のり。下ほど新。
- xmkmfとimakeによるMakefile生成 - 虎塚
- メモ: lndirコマンド - 虎塚
- 疑問メモ: ビルドするGCCのバージョン - 虎塚
- 「Building and Installing the X Window System R6.3」よんだ - 虎塚
imakeは、ビルド時にMakefileのプラットフォーム依存を解決するためのツールです。そのため、ツールのコードも、各プラットフォームに対応するための記述が多くを占めます。実際、imake.cは1300行弱のファイルですが、先頭から300行程度がそのためのプリプロセッサです。
というわけで、プリプロセッサ部分で行われていることを確認しました。
以下は、自分用のメモです。
定数、マクロなど
Cの規格を表す定数
- X_NOT_STDC_ENV
これが定義されていると、ANSI Cヘッダファイルがないことを意味する。(via xc/include/Xosdefs.h)
X_NOT_POSIXが定義されていると、POSIXヘッダファイルがないことを意味する。(via xc/include/Xosdefs.h)。POSIX環境を得るには、_POSIX_SOURCEを定義する必要がある、らしい。
プラットフォームを表す定数
- WIN32
- ISC
- Interactive Unix、の意。ISC ユーザ向けの情報 http://xjman.dsl.gr.jp/xf86_3/isc.html
- SCO325
- SCO OpenServer http://ja.wikipedia.org/wiki/SCO_OpenServer
- SYSV
- __minix_vmd
- SYS_NMLN
- utsname.hで定義されているutsname構造体の文字列要素のサイズ
プラットフォームの差異を吸収するといっても、限界があるわけで、上記に当てはまらない環境の場合は、「その他Linuxシステム」のような扱いになると思われる。
・・・のだけれども、プラットフォーム固有の設定ファイルは、上記の分類よりも数多く用意されている。
ということは、環境に適応する設定ファイルをよろしく選ぶ処理が、どこかにあるハズ(でも、どこにあるのか分からない。探し中)。
マクロ
- SIGCHLD
- SIGCLD
SIGCHLDは、プロセスが停止/終了したときに親プロセスに送られるシグナル。SIGCLDは、SIGCHLDの昔の名前。
imake.cの中では、SIGCLDが定義されていた場合、SIGCHLDとして呼び出せるように、マクロで置換している。
- WIFSIGNALED
- 「Wait if SIGNALED(?)」。ハンドルされないシグナルを受け取って子プロセスが終了したときに、非ゼロの値を返す
- WIFEXITED
- 「Wait IF EXITED」。子プロセスがexitや_exitで終了した時に、非ゼロの値を返す
- WEXITSTATUS
- 「Wait EXIT STATUS」。子プロセスの終了ステータスを得る。
- WTERMSIG
- 「Wait TERMinated SIGNAL」。子プロセスが終了したシグナルの値を返す。
上の4つのマクロはsys/wait.hで定義されているので、これらを宣言するよりも前の行で、sys/wait.hをincludeする必要がある。実際、そうなっている。
ヘッダファイルのinclude
システムファイル
複数のシステムファイルが、プラットフォームを判断するための条件に応じて、includeされます。
若干テキトーな部分もありますが、表に整理すると次のようになります。
- 「any」列が「Y(es)」のシステムファイルは、問答無用でincludeされる
- プラットフォームを表す定数の列が「Y(es)」は定義済み、「N(o)」は未定義を指す
any | X_NOT_STDC_ENV | X_NOT_POSIX | WIN32 | ISC | SCO325 | SYSV | |
---|---|---|---|---|---|---|---|
stdio.h | Y | ||||||
ctype.h | Y | ||||||
signal.h | Y | ||||||
sys/stat.h | Y | ||||||
string.h | N | ||||||
sys/types.h | N | ||||||
fcntl.h | N | ||||||
sys/file.h | Y | N | |||||
unistd.h | N(or) | Y(or) | |||||
sys/procset.h | N | Y | |||||
sys/siginfo.h | N | Y | |||||
sys/wait.h | N | ||||||
sys/wait.h | Y | N | N | ||||
process.h | Y | Y | N | ||||
stdlib.h | N | ||||||
errno.h | Y | ||||||
sys/utsname.h | N |
いくつか、もう少し詳しくみます。
- sys/types.h
- sys/stat.hが必要とするので、stat.hより前の行でincludeされる
- fcntl.h
- ファイルオープン時のモードを表す定数の定義
これらは、X_NOT_POSIXが定義されていないとき、includeされる。_POSIX_SOURCEが定義されていなければ、いったん_POSIX_SOURCEをdefineして、includeした後にundefしている。
- sys/file.h
- ファイル入出力用の関数定義
- unistd.h
そういえば、以前、unistd.hを使うコードをWindowsでコンパイルしようとしていました(→ http://d.hatena.ne.jp/torazuka/20101212/c)。Unix用のファイルだから、はまったのでした。
- process.h
SYSVでなく、WIN32のとき、includeされる。
- signal.h
- sys/wait.h
これらも(sys/types.h、fcntl.h同様に)、_POSIX_SOURCEが定義されていなければ、いったん_POSIX_SOURCEをdefineして、includeした後にundefしている。
ユーザファイル
ユーザファイルは3個あり、これもプラットフォームに応じてincludeされます。
any | WIN32 | |
---|---|---|
Xosdefs.h | Y | |
imakemdep.h | Y | |
Xw32defs.h | Y |
ちなみに、Xw32defs.hは、xc/include/Xw32defs.h にあります。
次は、やっとmain関数に入れそうなカンジ。
参考
ふつりなを読んで、知らないマクロはlibc.infoで引けばよいとやっと知りました(これまでは、manに存在しなければ、インターネッツで調べていた)。ふつりなは偉大な本です。
- Not a Symbol アンスタンダーダイズド http://vgr.blog8.fc2.com/blog-entry-69.html
- WIN32について
- C言語入門 その3 プロセスとシグナル http://www.yoshinobrain.com/c3.html
- 名前の区切りが参考になった
- 全ては時の中に… : 【C++】Linuxでコマンドの実行結果を取得する http://blog.livedoor.jp/akf0/archives/51662262.html
- サンプルコードがある(C++だけど)