imakeコードリーディングメモ・プリプロセッサ部編

imakeコードリーディングメモ「プリプロセッサ部」編です。

# これまでの道のり。下ほど新。

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を定義する必要がある、らしい。

プラットフォームを表す定数

プラットフォームの差異を吸収するといっても、限界があるわけで、上記に当てはまらない環境の場合は、「その他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されます。

若干テキトーな部分もありますが、表に整理すると次のようになります。

  1. 「any」列が「Y(es)」のシステムファイルは、問答無用でincludeされる
  2. プラットフォームを表す定数の列が「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用のファイルだから、はまったのでした。

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に存在しなければ、インターネッツで調べていた)。ふつりなは偉大な本です。