Go to the first, previous, next, last section, table of contents.


テストを書く

既存の特徴テストでは必要なことができない場合,新しいものを書く必要があ ります.これらのマクロはブロックの組み立てです.他のマクロで様々な特徴 が利用可能かどうか調査し結果を報告するための方法を提供します.

この章には,提案と,既存のテストが書かれている方法の理由も含まれていま す.また,既存のものを見ることで,Autoconfテストの書き方について知るこ とが可能です.Autoconfのテストの一つ以上がうまくいかない場合,この情報 は背後で行われていることの理解を助けるので,最善の問題解決法が分かるで しょう.

以下のマクロは,現在の言語のコンパイラシステムの出力を調査します (see section 言語の選択).それらは,キャッシュ変数名を生成するために 調査している情報を十分には知らないので,将来使用するためにテスト結果を キャッシュしません(see section 結果のキャッシュ).同じ理由でメッセージも出 力しません.特定の種類の機能の調査では,これらのマクロを呼び出し,結果 をキャッシュし,そして調査していることに関するメッセージを出力します.

一つ以上のソフトウェアパッケージに適用可能な特徴テストを書いているとき, 新しいマクロに要約することがベストです.その方法は,See section Autoconfマクロを書く.

言語の選択

Autoconfが生成した@command{configure}スクリプトは,Cコンパイラとその特 徴をデフォルトで調査します.他のプログラム言語を使用するパッケージ(一 つ以上で,例えば,CとC++)は,それぞれの言語のコンパイラの特徴をテスト する必要があります.以下のマクロは`configure.ac'内のそれ以降のテ ストで使用されるプログラミング言語のコンパイラを決定します.

Macro: AC_LANG (language)
languageで指定されている,コンパイラ,プリプロセッサ,そしてファ イル拡張子をコンパイルテストで使用します.

サポートされている言語は以下のとおりです.

`C'
CCCPPを使用してコンパイルテストを行ない,テストプログ ラムでは`.c'の拡張子を使用します.
`C++'
CXXCXXCPPを使用してコンパイルテストを行ない,テストプ ログラムでは`.C'の拡張子を使用します.
`Fortran 77'
F77を使用してコンパイルテストを行ない,テストプログラムでは `.f'の拡張子を使用します.

Macro: AC_LANG_PUSH (language)
現在の言語を(AC_LANGに設定するように)スタックに記録してから, languageを選択します.このマクロとAC_LANG_POPを,一時的に 特定の言語に切替える必要があるマクロで使用してください.

Macro: AC_LANG_POP (@ovar{language})
AC_LANG_PUSHで設定するように,スタックのトップに保存されている 言語に選択し,スタックからそれを削除します.

language与えられている場合,それは言語をそのまま指定しま す.分かっているときは,Autoconfが間違いを検出するので(case...にす べきですが),それを指定することは良い考えです.

AC_LANG_PUSH(Fortran 77)
# Perform some tests on Fortran 77.
# ...
AC_LANG_POP(Fortran 77)

Macro: AC_REQUIRE_CPP
現在のテストに使用されるプリプロセッサが見つかることを保証します.現在 の言語に依存して,AC_PROG_CPPまたはAC_PROG_CXXCPPのいず れかの引数を用いて,AC_REQUIRE(see section マクロの必要条件)を呼 び出してください.

テストプログラムを書く

Autoconfのテストの流れは,共通の手法です.いくつかの入力をいくつかのプ ログラムに与え,ほとんどの場合,ソースファイルをコンパイラに与えます. このセクションでは,これらのソースのサンプルを提供します.

テストプログラムのためのガイドライン

テストサンプルを書くときに従うべきもっとも重要な規則は以下のとおりです.

現実を探してください.

このモットーは,テストサンプルが現実にかかれるプログラムと同じ厳密さで 書く必要があるということです.特に,"ショートカット"と単純にしたもの は避けるべきです.

コンパイルの準備をしたい場合,プリプロセッサだけで実行しないでください. 例えば,ヘッダが機能することを調査するために@command{cpp}を使用するだ けでは,@command{configure}がコンパイラのエラーを生じるヘッダを 受け入れるかもしれません.以前にインクルードした他のヘッダ,特に必要と されるヘッダを用いたヘッダの調査をためらわないでください.

使用しているシンボルが,適切に定義されている,すなわち適切なヘッダをイ ンクルードする代わりに,自分で関数を単純に定義していないことを確かめて ください.

テストプログラムは,標準出力に何かを書き出すべきではありません.コアダ ンプや他の異常終了と簡単に区別できるように,成功した場合は0,それ以外 ではゼロ以外を返すべきです.セグメンテーション違反やその他の異常終了は, 終了ステータスでゼロ以外を生成します.main内のreturnの引 数を無視するシステム(少なくとも古いSun)もあるので,テストプログラムの mainではreturnではなくexitを使用するべきです.

既に実行されたテストで定義されたプリプロセッサの値を調査するため,テス トプログラムで#if#ifdefを使用することが可能です.例え ば, AC_HEADER_STDCを呼び出す場合,`configure.ac'の後の方 で,条件付でANSI Cヘッダファイルをインクルードするテストプログラムを使 用することが可能です.

#if STDC_HEADERS
# include <stdlib.h>
#endif

テストプログラムでデータファイルを使用したり,作成したりする必要がある 場合, `conftest.data'のような,`conftest'で始まる名前を与え てください.@command{configure}スクリプトは,テストプログラム終了後や スクリプトが中断された場合,`rm -rf conftest*'を実行しクリーンアッ プします.

関数のテスト

テストプログラムでの関数宣言には,C++に対する条件付のプロトタイプを持 たせるべきです.しかし,テストプログラムで引数をとる関数が必要になるこ とは,実際には滅多にありません.

#ifdef __cplusplus
foo (int i)
#else
foo (i) int i;
#endif

テストプログラムが宣言する関数には,`extern "C"'プロトタイプを要 求するC++に対する条件付けも行なうべきです.壊れたプロトタイプを含んで いるヘッダファイルをインクルードしていないことを確かめてください.

#ifdef __cplusplus
extern "C" void *malloc (size_t);
#else
void *malloc ();
#endif

テストプログラムが(その存在の確認のためにだけ)無効なパラメータで関数を 呼び出す場合,その関数を決して呼び出さないことを保証するようにプログラ ムを構成してください.決して呼び出されないそれ以外の他の関数から関数を 呼び出すことで,こうすることが可能です.GCCバージョン2は,exit は値を返さず,同じブロックにあるそれ以降のコードを最適化で外してしまう ことが知られているので,exitの呼び出し以降にそれを書き込まない でください.

ヘッダファイルをインクルードする場合は,たとえ引数が0だけであっても, プロトタイプで生じるコンパイルエラーを避けるため,正しい数の引数を適切 にして関数を呼び出していることを確認してください.GCCのバージョン2は, 自動的にインライン化される関数プロトタイプ,例えばmemcpyもあり ます.それらを調査しているときのエラーを避けるため,正しい数の引数を与 えるか,(charのような)異なる戻り値で再定義してください.

ソースの生成

Autoconfは,テストソースファイルを生成するために使用することが可能なマ クロの組みを提供しています.それらは,一般的な言語で書かれていて,すな わち,それらは実際に現在の言語(see section 言語の選択)に依存して適切 な出力"フォーマット"になっています.

Macro: AC_LANG_CONFTEST (source)
現在のテストソースファイルにsourceのテキストを保存します. `conftest.extension'extensionは現在の言語に依存しま す.

通常のAutoconfマクロ引数のように,sourceは一度だけ評価され,その ため,(i)マクロ呼び出しに渡してもかまわず,(ii)そうでなければ,必要が あれば二重に引用符で囲む必要があることに注意してください.

Macro: AC_LANG_SOURCE (source)
現在の場所の(例えば,Cでは`#line 1234 "configure"') 適切な定義を 用いて,sourceに展開し,すべてのAC_DEFINEでの定義も実行し ます.

例えば,以下を実行します(二重の引用符を守ってください!).

AC_INIT(Autoconf Documentation, 2.57, bug-autoconf@gnu.org)
AC_DEFINE([HELLO_WORLD], ["Hello, World\n"])
AC_LANG_CONFTEST(
   [AC_LANG_SOURCE([[const char hw[] = "Hello, World\n";]])])
gcc -E -dD conftest.c -o -

結果は以下のようになります.

# 1 "conftest.c"
# 1169 "configure"

# 1 "confdefs.h" 1

#define PACKAGE_NAME "Autoconf Documentation"
#define PACKAGE_TARNAME "autoconf-documentation"
#define PACKAGE_VERSION "2.57"
#define PACKAGE_STRING "Autoconf Documentation 2.57"
#define PACKAGE_BUGREPORT "bug-autoconf@gnu.org"
#define HELLO_WORLD "Hello, World\n"
# 1170 "configure" 2

const char hw[] = "Hello, World\n";

Macro: AC_LANG_PROGRAM (prologue, body)
prologueの内容と,bodyをmain関数(例えばCのmain)とし てソースファイルに展開します.それはAC_LANG_SOURCEを使用するの で,後者の機能は利用可能です.

例えば以下のようにします.

AC_INIT(Autoconf Documentation, 2.57, bug-autoconf@gnu.org)
AC_DEFINE([HELLO_WORLD], ["Hello, World\n"])
AC_LANG_CONFTEST(
[AC_LANG_PROGRAM([[const char hw[] = "Hello, World\n";]],
                 [[fputs (hw, stdout);]])])
gcc -E -dD conftest.c -o -

結果は以下のようになります.

# 1 "conftest.c"
# 1169 "configure"

# 1 "confdefs.h" 1

#define PACKAGE_NAME "Autoconf Documentation"
#define PACKAGE_TARNAME "autoconf-documentation"
#define PACKAGE_VERSION "2.57"
#define PACKAGE_STRING "Autoconf Documentation 2.57"
#define PACKAGE_BUGREPORT "bug-autoconf@gnu.org"
#define HELLO_WORLD "Hello, World\n"
# 1170 "configure" 2

const char hw[] = "Hello, World\n";
int
main ()
{
fputs (hw, stdout);
  ;
  return 0;
}

Macro: AC_LANG_CALL (prologue, function)
prologueの内容と,functionの呼び出しをmain関数(例えばCの main)の本体としてソースファイルに展開します.それは AC_LANG_SOURCEを使用するので,後者の機能は利用可能です.

この関数は,おそらく将来の引数指定が利用可能なバージョンで置換されます. このマクロは特定のシステムをひどく侵害するので,その使用は推奨しません.

Macro: AC_LANG_FUNC_LINK_TRY (function)
main関数(例えばCではmain)の本体として,偽のfunctionを使用 している内容をソースファイルに展開します.単純な(関数ポインタの)割当で す.それはAC_LANG_SOURCEを使用するので,後者の機能は利用可能で す.

AC_LANG_CALLがあるので,このマクロは,補完の意味で説明していま す.ひどく壊れていて,(適切な型の引数を用いた)実際の関数の呼び出しに将 来は変更しようと考えています.

プリプロセッサの実行

いくつかのソースファイルでプリプロセッサを実行する必要があるときもあり ます.通常はプロジェクトをコンパイルする必要があり,プリプロセッ サを実行する必要があることは滅多に無いので,そうすることは,普通 は悪い考えです.そのため,きっとプリプロセッサではなくコンパイラを実 行したいと思うでしょう.安易な道をたどる誘惑に逆らってください.

それにもかかわらず,プリプロセッサを実行する必要がある場合, AC_PREPROC_IFELSEを使用してください.

Macro: AC_PREPROC_IFELSE (input, @ovar{action-if-true}, @ovar{action-if-false})
inputで現在の言語(see section 言語の選択)のプリプロセッサを実行 し,成功したらシェルコマンドaction-if-trueを実行し,そうでなけれ ばaction-if-falseを実行します.inputAC_LANG_PROGRAMとその仲間で作成することが可能です.

このマクロはCPPFLAGSを使用しますが,@option{-g},@option{-O}な どは多くのCプリプロセッサで有効なオプションではないので,CFLAGS は使用しません.

予期せぬ異常終了は,通常AC_MSG_FAILUREで報告します.

例えば以下のようにします.

AC_INIT(Autoconf Documentation, 2.57, bug-autoconf@gnu.org)
AC_DEFINE([HELLO_WORLD], ["Hello, World\n"])
AC_PREPROC_IFELSE(
   [AC_LANG_PROGRAM([[const char hw[] = "Hello, World\n";]],
                    [[fputs (hw, stdout);]])],
   [AC_MSG_RESULT([OK])],
   [AC_MSG_FAILURE([unexpected preprocessor failure])])

結果は以下のようになります.

checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking how to run the C preprocessor... gcc -E
OK

マクロAC_TRY_CPP(see section 時代遅れのマクロ)は, AC_PREPROC_IFELSEの役目を果たすために使用されていましたが,その 引数を二重の引用符で囲んでいるので,精巧なソースで使用することが不可能 でした.マクロAC_TRY_CPPAC_PREPROC_IFELSEをような古い 使い方を取り除くことも推奨しますが,最初にコンパイラではなくプリ プロセッサを実行する必要があるのかを確かめることを推奨します.

Macro: AC_EGREP_HEADER (pattern, header-file, action-if-found, @ovar{action-if-not-found})
システムヘッダファイルheader-fileでのプリプロセッサの実行での出 力が拡張正規表現のpatternにマッチする場合,シェルコマンド action-if-foundを実行し,それ以外ではaction-if-not-foundを 実行します.

Macro: AC_EGREP_CPP (pattern, program, @ovar{action-if-found}, @ovar{action-if-not-found})
programがCやC++プログラムのテキストで,そのなかではシェル変数, バッククオート,そしてバックスラッシュの代入が実行されたものになってい ます.programでのプリプロセッサの実行での出力が拡張正規表現の patternにマッチする場合,シェルコマンドaction-if-foundを実 行し,それ以外ではaction-if-not-foundを実行します.

コンパイラの実行

特定のキーワードやを認識するかどうかといった,(C,C++,またはFortran 77)コンパイラの構文の特徴を調査するため,また,単純にいくつかのライブ ラリの特徴を調査するため,それらの特徴を使用している小さなプログラムを コンパイルしてみるため,AC_COMPILE_IFELSEを使用してください.

Macro: AC_COMPILE_IFELSE (input, @ovar{action-if-found}, @ovar{action-if-not-found})
現在の言語(see section 言語の選択)のコンパイラをinputで実行し, 成功したらシェルコマンドaction-if-trueを,それ以外では action-if-falseを実行します.inputAC_LANG_PROGRAM やその仲間で作成することが可能です.

このマクロは,CやC++のいずれか一方が現在の言語として選択されている場合, CFLAGSCXXFLAGSを使用し,コンパイル時には,同様に CPPFLAGSを使用します.Fortran 77が現在の言語として選択されてい る場合,コンパイル時にはFFLAGSが使用されます.

慣習的に,予期せぬ異常終了はAC_MSG_FAILUREで報告します.このマ クロはリンクを試みません.そうする必要がある場合, AC_LINK_IFELSEを使用してください(see section リンカの実行).

リンカの実行

ライブラリ,関数,またはグローバル変数を調査するため,Autoconfの @command{configure}スクリプトは,それを使用している小さなプログラムの コンパイルとリンクを試みます.これはMetaconfigとは異なり,それはデフォ ルトで,C ライブラリで関数が利用可能かどうか判定するためにnmarを使用します.オプションとnmarの出力の違いと, 標準ライブラリの位置の違いを処理することを避けるので,関数とのリンクを 試みることは,通常,より信頼性が高い方法になります.クロスコンパイルの コンフィグレーションや,必要な場合は関数の実行時の動作を調査も可能です. 一方,一度のライブラリスキャンより遅くなるはずですが,正確さは時間より 重要です.

AC_LINK_IFELSEは,関数とグローバル変数に対するテストのため,テ ストプログラムをコンパイルするために使用されます.ライブラリを調査する AC_CHECK_LIBでも,調査しているライブラリを一時的にLIBSに 追加したり,小さなプログラムのリンクを試みたりすることで,使用されてい ます(see section ライブラリファイル).

Macro: AC_LINK_IFELSE (input, @ovar{action-if-found}, @ovar{action-if-not-found})
現在の言語(see section 言語の選択)のコンパイラとリンカをinputで 実行し,成功したらシェルコマンドのaction-if-trueを,それ以外では action-if-falseを実行します.inputAC_LANG_PROGRAM やその仲間で作成することが可能です.

このマクロは,CやC++のいずれか一方が現在の言語として選択されている場合, CFLAGSCXXFLAGSを使用し,コンパイル時には,同様に CPPFLAGSを使用します.Fortran 77が現在の言語として選択されてい る場合,コンパイル時にはFFLAGSが使用されます.

慣習的に,予期せぬ異常終了はAC_MSG_FAILUREで報告します.このマ クロはリンクを試みません.そうする必要がある場合,AC_RUN_IFELSE を使用してください(see section 実行時の動作の調査).

実行時の動作の調査

当該関数に特定の能力やバグがあるかどうかといった,実行時にシステムがど のような動作をするか調べる必要があることもあります.可能であれば,コン フィグレーション時ではなくプログラムを実行するときそのような調査をして ください.マシンのエンディアンのようなものは,プログラムの初期化時に調 査することが可能です.

コンフィグレーション時に実行時の動作を調査する必要が本当にある場合,結 果を決定するテストプログラムを書き,コンパイルしてAC_RUN_IFELSE を使用して実行することも可能です.これは,クロスコンパイルでパッケージ をコンフィグレーションする人々の妨げになるので,可能であれば,テストプ ログラムの実行は避けてください.

Macro: AC_RUN_IFELSE (input, @ovar{action-if-found}, @ovar{action-if-not-found}, @ovar{action-if-cross-compiling})
programのコンパイルとリンクが正常終了し,実行時に0の終了ステータ スが返る場合,シェルコマンドaction-if-trueを実行します.それ以外 では,シェルコマンドaction-if-falseを実行します.

inputは,AC_LANG_PROGRAMとその仲間で作成することが可能で す.このマクロは,CFLAGSCXXFLAGSCPPFLAGSLDFLAGS,そしてLIBSを使用します.

使用されるコンパイラが,@command{configure}が実行されているシステムで 実行する実行形式を生成しない場合,テストプログラムは実行されません.オ プションのシェルコマンドaction-if-cross-compilingが与えられてい る場合,それらが変わりに実行されます.それ以外の場合, @command{configure}はエラーメッセージを出力し終了します.

action-if-falseセクションでは,プログラムの終了ステータスはシェ ル変数`$?'で利用可能ですが,127未満の正の値に制限するよう十分注意 してください.大きな値は,programでファイルに保存すべきです.ま た,この終了ステータスがprogramで,またはそのコンパイルの異常終 了で,生成されることを保証されていないことに注意してください.言い替え ると,苛められるのが好きな人だけこの機能を使用してください.それは, Autoconfの管理者が飽き飽きするほど"バグの報告"を受けとることになっ たので,元に戻しました.

慣習的に,予期せぬ異常終了はAC_MSG_FAILUREで報告します.

クロスコンパイルで実行時のテストが不可能な時は,使用する悲観的なデフォ ルト値を提供してみてください.オプションの最後の引数を AC_RUN_IFELSEに渡すことでこうします.@command{autoconf}は, action-if-cross-compiling引数無しでAC_RUN_IFELSEを呼び出 すごとに,@command{configure}を生成するときに警告メッセージを出力しま す.警告を無視してもかまいませんが,ユーザはクロスコンパイルでパッケー ジのコンフィグレーションが不可能になります.Autoconfで配布されるマクロ には,この警告メッセージを生成するものもあります.

クロスコンパイルでコンフィグレーションするため,これらのパラメータの値 を標準的なシステム名を基に選択することも可能です(see section 手動のコンフィグレーション).または,テスト結果のキャッシュファイルをホストシステ ムに対する正しい値で設定してください(see section 結果のキャッシュ).

Autoconfとともに含まれている他のマクロに埋め込まれている, AC_RUN_IFELSEの呼び出しに対するデフォルトを提供するため,シェル 変数cross_compiling`yes'に設定されているかどうかを調査し, マクロ呼び出しの代わりに結果を取得するため,代わりの手法を使用してくだ さい.

システム

このセクションは,ドキュメントへのシステムとポインタを紹介することを目 的としています.ユーザが報告する特定の問題を解決するとき役に立つでしょ う.

@href{http://bhami.com/rosetta.html, Rosetta Stone for Unix}には,様々 なUnixの興味深い相互的な情報が大量にあります.

Darwin
DarwinはMac OS Xとしても知られています.ファイルシステムで大文字小文字 の違いを保存することが可能ですが,大文字小文字の区別をしないこ とに注意してください.例えば,`INSTALL'ファイルがあるパッケージで インストールを試みるとき,`make install'で「何もすることが無い!」 のような結果が得られ,これは厄介な問題になります. それは,ファイルシステムがUFS(大文字小文字を区別する)かHFS+(大文字小文 字の違いを保存する)かに依存します.デフォルトで,AppleはHFS+にOSをイン ストールして欲しがっています.残念ながら,本当にUFSでビルドする必要が あるソフトウェアもあります.DarwinをUFSとHFS+の両方で利用可能なように 再構築して(そして/local/buildのツリーに配置して)欲しいと思います.
@acronym{QNX 4.25}
@acronym{QNX}は,小さな組み込みシステムから百個のプロセッサを持つスー パーコンピュータまで幅広く利用できる,Intelアーキテクチャでまで動作す るリアルタイムオペレーティングシステムです.それは@acronym{POSIX}であ ることが証明されていると主張しています.@href{www.qnx.com, @acronym{QNX} home page} で,より多くの情報が利用可能で,そこには, @href{http://support.qnx.com/support/docs/qnx4/, @acronym{QNX} man pages}もあります.
Tru64
@href{http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/, documentation of several versions of Tru64}では,様々な書式が利用可能 です.
Unix version 7
@href{http://plan9.bell-labs.com/7thEdMan/index.html, V7 Manual}でドキュ メントは利用可能です.

複数のケース文

処理によっては,それぞれ異なるUNIXに依存して,考えられるいくつか の方法で達成されるものもあります.それを本質的に調査するためには, "case 文"が必要です.Autoconfは直接それを提供していません.しかし, 実行する処理が見つかったかどうかの追跡を続けるため,シェル変数を使用す ることで簡単にシミュレート可能です.

残っているcaseを調査する必要があるかどうかに関係なく追跡を続けるために, シェル変数fstypeを使用する例は,以下のようになります.

AC_MSG_CHECKING([how to get file system type])
fstype=no
# The order of these tests is important.
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statvfs.h>
#include <sys/fstyp.h>]])],
                  [AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4])
if test $fstype = no; then
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h>
#include <sys/fstyp.h>]])],
                  [AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3])
fi
if test $fstype = no; then
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h>
#include <sys/vmount.h>]])]),
                  [AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX])
fi
# (more cases omitted here)
AC_MSG_RESULT([$fstype])


Go to the first, previous, next, last section, table of contents.