以下のマクロは,Cコンパイラを探し使用する方法を提供します.避けたほうが 良い構成物もいくつかありますが,それらは容易に回避可能なので,調査に使用 しているなら無くしてしまうこともないでしょう.
#ifdef __STDC__
/\
* A comment with backslash-newlines in it. %{ %} *\
\
/
char str[] = "\\
" A string with backslash-newlines in it %{ %} \\
"";
char apostrophe = '\\
\
'\
';
#endif
以下のようになります.
error-->cpp: "foo.c", line 13: error 4048: Non-terminating comment at end of file.
error-->cpp: "foo.c", line 13: error 4033: Missing #endif at end of file.
単一のバックスラッシュを用いた行を削除することで,問題を解決できます.
$ cc a.c b.c
a.c:
b.c:
失敗を検出するために,コンパイラの出力を観察する場合,これは問題になるは
ずです.`cc -c a.c -o a.o; cc -c b.c -o b.o; cc a.o b.o -o c'で呼び
出すことで問題を解決します.
#lineのサポートに依存しないで下さい#line指示語を
拒絶します.さらにposixでは,これは有効になっていません.これは,
Autoconfが#line指示語の生成を停止した理由です.
使用するCコンパイラを決定します.
CCが環境変数で設定されていない場 合,gccとccを調査し,その後で他のCコンパイラを調査します. 出力変数CCを,見つかったコンパイラの名前に設定します.しかし,このマクロはオプションで最初の引数を用いて呼び出すことも可能で, それが指定されている場合,それをスペースで区切られている検索するCコンパ イラのリストにする必要があります.これは,別のCコンパイラの検索リストを 指定する機会をユーザに与えます.例えば,デフォルトの順序が好きではない場 合,以下のような
AC_PROG_CCを呼び出すことが可能です.AC_PROG_CC(cl egcs gcc cc)CコンパイラがデフォルトでANSI Cモードでない場合,そうするため のオプションを出力変数
CCに追加します.このマクロは,様々なシステ ムでANSI Cを選択するように,様々なオプションを試します.関数の プロトタイプを正しく処理する場合,コンパイラがANSI Cモードだと 考えます.このマクロを呼び出した後,CコンパイラがANSI Cを受け入れるよう に設定されているかどうかを調査することが可能です.そうでない場合,シェル 変数
ac_cv_prog_cc_stdcは`no'に設定されます.ソースコードを ANSI Cで書いている場合,Automake附属のプログラムansi2knrを使用して,非ANSIfiedされたコピーを作成するこ とが可能です.AC_C_PROTOTYPES以下も参照してください.GNU Cコンパイラを使用する場合,シェル変数の
GCCを `yes'に設定します.出力変数CFLAGSがいまだ設定されていない場 合,GNU Cコンパイラに対しては-g -O2に設定し(GCCが `-g'を受け入れないシステムは`-O2'),それ以外のコンパイラに対し ては-gに設定します.
Cコンパイラが`-c'と`-o'オプションを同時に受け入れない場合,
NO_MINUS_C_MINUS_Oを定義します.このマクロは,AC_PROG_CCで見つかったコンパイラと,パスの最初のccがそれと異なっている場合 はその両方を,実際にテストします.一つでも失敗した場合,テストは失敗しま す.このマクロは,GNU Makeがデフォルトのコンパイルルールを選択 するように作成されました.
出力変数
CPPを,Cプリプロセッサを実行するコマンドに設定ます. `$CC -E'が動作しない場合,/lib/cppを使用します.拡張子が .cのファイルでCPPを実行することは移植性のためだけです.プロセッサによっては,足りないインクルードファイルをエラーステータスで示 さないものもあります.そのようなプロセッサに対する内部変数は,プリプロセッ サからの標準エラーを調査するための他のマクロを設定し,警告が報告された場 合はテストに失敗したと判断します.それにもかかわらず,ほとんどのプリプロ セッサに対して,
AC_PROG_CPP_WERRORも指定しない限り,警告でインク ルードファイルのテストは失敗します.
これは
AC_PROG_CPPのように動作しますが,プリプロセッサからの警告を, プリプロセッサが成功したことを示すステータスで終了した場合でも,エラーが あったとして処理します.これは,推奨されない注意のような,強制的な警告を 生成するヘッダを避けるときに役に立ちます.
以下のマクロは,Cコンパイラやマシンアーキテクチャの特徴を調査します.こ
こでリストアップされない特徴を調査するために,AC_COMPILE_IFELSE
(see Running the Compiler)やAC_RUN_IFELSE (see Run Time)
を使用してください.
(MotorolaとSPARCのCPUのように)wordが最上位バイトに最初に保存される場合, action-if-trueを実行します.(IntelとVAXのCPUのように)wordが最下位 バイトに最初に保存される場合,action-if-falseを実行します.
システムヘッダファイルからエンディアンを決定不可能な場合,このマクロはテ ストケースを実行します.クロスコンパイル時に,テストケースは実行されませ んが,いくつかのマジック変数を検索します.後者の状況でホストシステムのバ イト特性の決定に失敗した場合,action-if-unknownが実行されます.
action-if-trueのデフォルトは`WORDS_BIGENDIAN'を定義することで す.action-if-falseのデフォルトは何もしないことです.そして最後に, action-if-unknownのデフォルトは,コンフィグレーションを中断し,イ ンストールしている人に,このテストをバイパスさせるために変数を前もって定 義するよう伝えます.
CコンパイラがANSI Cの修飾子
constを完全にサポートしない 場合,constを空で定義します.__STDC__を定義しないCコンパ イラには,constをサポートするものもあります.__STDC__を定 義するCコンパイラには,constを完全にサポートしないものもあります. 全てのCコンパイラがconstをサポートするかのように,プログラムはそ れを使用することができます.サポートしないもののためにMakefileや コンフィグレーションヘッダファイルは,それを空で定義します.Cコンパイラが無いために,インストールしている人がCコードをコンパイルする ためにC++コンパイラを使用することもあります.CとC++は
constを異な る方法で処理するので,これはconstの問題が生じます.例えば,以下の ようにします.const int foo;Cでは有効ですがC++ではそうではありません.残念ながら,これらの違いを
constを空で定義することで誤魔化すことは不可能です.autoconfがこの状況を検出した場合,一般的に実際問題としてより良 い結果になるので,それは
constのままにしておきます.しかし,C コー ドコンパイルするためにC++コンパイラを使用することは推奨されていませんし, サポートもしていません.そして,この状況で問題が生じたインストール者は, CコードをコンパイルするためにGCCのようなCコンパイラを入手すべきです.
Cコンパイラが
restrictキーワードを認識する場合は何もしません. (__restrict,__restrict__,または_Restrict)という, かわったつづりだけを認識する場合,restrictをそれに定義します.そ れ以外では,restrictを空で定義します.このため,プログラムではrestrictをすべてのCコンパイラがサポートしているかのように,単純に 使用してかまいません.そうしない人は,Makefileやコンフィグレーショ ンヘッダで頑張って定義して下さい.C++での
restrictキーワードサポートは要求されていませんが,いくつか のC++コンパイラはそのキーワードを受け入れます.このマクロは,そこでも動 作します.
Cコンパイラがキーワード
volatileを理解しない場合,volatileを空で定義します.プログラムではvolatileをサポートしているコンパ イラのように単純に使用することが可能です.サポートしないものに対しては, Makefileやコンフィグレーションヘッダで,それを空として定義されま す.プログラムの正当性が
volatileの意味に依存している場合,単純に空で 定義するとある意味ではコードが壊れます.しかし,volatileをサポー トしていないコンパイラでは,自分で何とかしてください.少なくともプログラ ムはコンパイルされますが,多分駄目でしょう.一般的に,
volatileキーワードはANSI Cの機能なので,__STDC__が定義されているときだけ,volatileが利用可能だと期 待するかもしれません.しかし,Ultrix 4.3のネイティブコンパイラはvolatileをサポートとしていますが,__STDC__を定義しません.
Cコンパイラがキーワード
inlineをサポートする場合,何もしません.そ れ以外では,受け入れられるものによって,inlineを__inline__や__inlineに定義し,それ以外ではinlineを空で定義します.
Cプリプロセッサが文字列作成オペレータをサポートする場合,
HAVE_STRINGIZEを定義します.文字列作成オペレータは`#'と,以 下のようなマクロで見つかります.#define x(y) #y
関数のプロトタイプをコンパイラが理解する場合(
AC_PROG_CCで決定され ます),`PROTOTYPES'と__PROTOTYPESを定義します.コンパイラが プロトタイプを処理しない場合,関数定義のプロトタイプを止めるために, Automake配布物でインストールされるansi2knrを使用すべきです.関数 のプロトタイプに対して,最初にPARAMSを定義すべきです.#ifndef PARAMS # if PROTOTYPES # define PARAMS(protos) protos # else /* no PROTOTYPES */ # define PARAMS(protos) () # endif /* no PROTOTYPES */ #endifそして,以下のように使用してください.
size_t my_strlen PARAMS ((const char *));
このマクロは,__PROTOTYPESも定義します.これは,ユーザの名前空間
を侵害するマクロが使用不可能なヘッダファイルの利便性ためです.