既存の特徴テストでは必要なことができない場合,新しいものを書く必要があ ります.これらのマクロはブロックの組み立てです.他のマクロで様々な特徴 が利用可能かどうか調査し結果を報告するための方法を提供します.
この章には,提案と,既存のテストが書かれている方法の理由も含まれていま す.また,既存のものを見ることで,Autoconfテストの書き方について知るこ とが可能です.Autoconfのテストの一つ以上がうまくいかない場合,この情報 は背後で行われていることの理解を助けるので,最善の問題解決法が分かるで しょう.
以下のマクロは,現在の言語のコンパイラシステムの出力を調査します (see section 言語の選択).それらは,キャッシュ変数名を生成するために 調査している情報を十分には知らないので,将来使用するためにテスト結果を キャッシュしません(see section 結果のキャッシュ).同じ理由でメッセージも出 力しません.特定の種類の機能の調査では,これらのマクロを呼び出し,結果 をキャッシュし,そして調査していることに関するメッセージを出力します.
一つ以上のソフトウェアパッケージに適用可能な特徴テストを書いているとき, 新しいマクロに要約することがベストです.その方法は,See section Autoconfマクロを書く.
Autoconfが生成した@command{configure}スクリプトは,Cコンパイラとその特 徴をデフォルトで調査します.他のプログラム言語を使用するパッケージ(一 つ以上で,例えば,CとC++)は,それぞれの言語のコンパイラの特徴をテスト する必要があります.以下のマクロは`configure.ac'内のそれ以降のテ ストで使用されるプログラミング言語のコンパイラを決定します.
サポートされている言語は以下のとおりです.
CC
とCPP
を使用してコンパイルテストを行ない,テストプログ
ラムでは`.c'の拡張子を使用します.
CXX
とCXXCPP
を使用してコンパイルテストを行ない,テストプ
ログラムでは`.C'の拡張子を使用します.
F77
を使用してコンパイルテストを行ない,テストプログラムでは
`.f'の拡張子を使用します.
AC_LANG
に設定するように)スタックに記録してから,
languageを選択します.このマクロとAC_LANG_POP
を,一時的に
特定の言語に切替える必要があるマクロで使用してください.
AC_LANG_PUSH
で設定するように,スタックのトップに保存されている
言語に選択し,スタックからそれを削除します.
language与えられている場合,それは言語をそのまま指定しま す.分かっているときは,Autoconfが間違いを検出するので(case...にす べきですが),それを指定することは良い考えです.
AC_LANG_PUSH(Fortran 77) # Perform some tests on Fortran 77. # ... AC_LANG_POP(Fortran 77)
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 言語の選択)に依存して適切 な出力"フォーマット"になっています.
通常のAutoconfマクロ引数のように,sourceは一度だけ評価され,その ため,(i)マクロ呼び出しに渡してもかまわず,(ii)そうでなければ,必要が あれば二重に引用符で囲む必要があることに注意してください.
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";
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; }
main
)の本体としてソースファイルに展開します.それは
AC_LANG_SOURCE
を使用するので,後者の機能は利用可能です.
この関数は,おそらく将来の引数指定が利用可能なバージョンで置換されます. このマクロは特定のシステムをひどく侵害するので,その使用は推奨しません.
main
)の本体として,偽のfunctionを使用
している内容をソースファイルに展開します.単純な(関数ポインタの)割当で
す.それはAC_LANG_SOURCE
を使用するので,後者の機能は利用可能で
す.
AC_LANG_CALL
があるので,このマクロは,補完の意味で説明していま
す.ひどく壊れていて,(適切な型の引数を用いた)実際の関数の呼び出しに将
来は変更しようと考えています.
いくつかのソースファイルでプリプロセッサを実行する必要があるときもあり ます.通常はプロジェクトをコンパイルする必要があり,プリプロセッ サを実行する必要があることは滅多に無いので,そうすることは,普通 は悪い考えです.そのため,きっとプリプロセッサではなくコンパイラを実 行したいと思うでしょう.安易な道をたどる誘惑に逆らってください.
それにもかかわらず,プリプロセッサを実行する必要がある場合,
AC_PREPROC_IFELSE
を使用してください.
AC_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_CPP
のAC_PREPROC_IFELSE
をような古い
使い方を取り除くことも推奨しますが,最初にコンパイラではなくプリ
プロセッサを実行する必要があるのかを確かめることを推奨します.
特定のキーワードやを認識するかどうかといった,(C,C++,またはFortran
77)コンパイラの構文の特徴を調査するため,また,単純にいくつかのライブ
ラリの特徴を調査するため,それらの特徴を使用している小さなプログラムを
コンパイルしてみるため,AC_COMPILE_IFELSE
を使用してください.
AC_LANG_PROGRAM
やその仲間で作成することが可能です.
このマクロは,CやC++のいずれか一方が現在の言語として選択されている場合,
CFLAGS
やCXXFLAGS
を使用し,コンパイル時には,同様に
CPPFLAGS
を使用します.Fortran 77が現在の言語として選択されてい
る場合,コンパイル時にはFFLAGS
が使用されます.
慣習的に,予期せぬ異常終了はAC_MSG_FAILURE
で報告します.このマ
クロはリンクを試みません.そうする必要がある場合,
AC_LINK_IFELSE
を使用してください(see section リンカの実行).
ライブラリ,関数,またはグローバル変数を調査するため,Autoconfの
@command{configure}スクリプトは,それを使用している小さなプログラムの
コンパイルとリンクを試みます.これはMetaconfigとは異なり,それはデフォ
ルトで,C ライブラリで関数が利用可能かどうか判定するためにnm
や
ar
を使用します.オプションとnm
とar
の出力の違いと,
標準ライブラリの位置の違いを処理することを避けるので,関数とのリンクを
試みることは,通常,より信頼性が高い方法になります.クロスコンパイルの
コンフィグレーションや,必要な場合は関数の実行時の動作を調査も可能です.
一方,一度のライブラリスキャンより遅くなるはずですが,正確さは時間より
重要です.
AC_LINK_IFELSE
は,関数とグローバル変数に対するテストのため,テ
ストプログラムをコンパイルするために使用されます.ライブラリを調査する
AC_CHECK_LIB
でも,調査しているライブラリを一時的にLIBS
に
追加したり,小さなプログラムのリンクを試みたりすることで,使用されてい
ます(see section ライブラリファイル).
AC_LANG_PROGRAM
やその仲間で作成することが可能です.
このマクロは,CやC++のいずれか一方が現在の言語として選択されている場合,
CFLAGS
やCXXFLAGS
を使用し,コンパイル時には,同様に
CPPFLAGS
を使用します.Fortran 77が現在の言語として選択されてい
る場合,コンパイル時にはFFLAGS
が使用されます.
慣習的に,予期せぬ異常終了はAC_MSG_FAILURE
で報告します.このマ
クロはリンクを試みません.そうする必要がある場合,AC_RUN_IFELSE
を使用してください(see section 実行時の動作の調査).
当該関数に特定の能力やバグがあるかどうかといった,実行時にシステムがど のような動作をするか調べる必要があることもあります.可能であれば,コン フィグレーション時ではなくプログラムを実行するときそのような調査をして ください.マシンのエンディアンのようなものは,プログラムの初期化時に調 査することが可能です.
コンフィグレーション時に実行時の動作を調査する必要が本当にある場合,結
果を決定するテストプログラムを書き,コンパイルしてAC_RUN_IFELSE
を使用して実行することも可能です.これは,クロスコンパイルでパッケージ
をコンフィグレーションする人々の妨げになるので,可能であれば,テストプ
ログラムの実行は避けてください.
inputは,AC_LANG_PROGRAM
とその仲間で作成することが可能で
す.このマクロは,CFLAGS
やCXXFLAGS
,CPPFLAGS
,
LDFLAGS
,そして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の興味深い相互的な情報が大量にあります.
処理によっては,それぞれ異なる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.