[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あなたの必要としている検査項目が既存のマクロで実現されていない場合、 自分であたらしいマクロを書かねばなりません。 以下のマクロは、マクロの基本部品です 以下のマクロは、他のマクロ内でOS/コンパイラの機能を検査したり、 結果を出力したりするのに使われています。
この章では、推奨されるマクロの書き方、 それから既存のマクロがどうして現在あるように記述されているのかについて 述べています。 既存のマクロがどのように書かれているのか見ることで、 どうやってAutoconfのマクロを記述すべきか学べるでしょう。 Autoconfのテストでなにかがうまくいかなかったら、 マクロがなにを仮定しているのか理解するのに この章の内容が役立つかもしれません。 マクロが仮定していることを理解すれば、 マクロの問題点をどう解くべきなのかを知るにも役立つでしょう (訳註: 相当意訳)。
以下のマクロは、Cコンパイラの出力を調べます。 以下のマクロは結果をキャッシュしません(see section 6.3 Caching Results)。 なぜなら、これらのマクロからは検査している内容がわからないし キャッシュ変数名も決められないからです。 Cコンパイラの特定の機能を調べるマクロは、結果をキャッシュしますし、 なにを調べているのかメッセージも出力されます。
複数のソフトウェアパッケージで利用できる検査を書いた場合、 新しいマクロを定義するのがよいでしょう。 どうやるかはSee section 7. Writing Macros参照。
5.1 Examining Declarations | Detecting header files and declarations. | |
5.2 Examining Syntax | Detecting language syntax features. | |
5.3 Examining Libraries | Detecting functions and global variables. | |
5.4 Checking Run Time Behavior | Testing for run-time features. | |
5.5 Portable Shell Programming | Shell script portability pitfalls. | |
5.6 Testing Values and Files | Checking strings and files. | |
5.7 Multiple Cases | Tests for several possible values. | |
5.8 Language Choice | Selecting which language to use for testing. |
AC_TRY_CPP
は特定のヘッダファイルが存在するか調べるためにあります。
ヘッダファイルひとつづつについて調べることもできますし、
ひとつの目的のために調べるのなら複数のヘッダファイルをまとめて
調べることもできます。
#include
文(訳註: ほんとは文じゃないね)と
定義文(訳註: `#define'とか)を記述します。
他の文を記述しても構いませんが、多分意味ないでしょう。
includesのところにはshell変数、
backquote、backslashによる置換が働きます
(訳註: 置換を避けたければ`['と`]'で囲め、ということです)。
プリプロセッサが処理中にエラーメッセージを出さなければ、
shellコマンドaction-if-trueが実行されます。
エラーがあればaction-if-falseが実行されます。
このマクロはCPPFLAGS
を使いますが、CFLAGS
は使いません。
`-g'とか`-O'は多くのCプリプロセッサで無効だからです。
次のマクロはヘッダファイルに特定の定義(typedef、構造体、構造体メンバ、
関数プロトタイプ)が入っているかどうか調べます。
ヘッダファイルを直接grep
せずに、AC_EGREP_HEADER
を使いましょう。
システムによっては、調べたいシンボルが、あなたがgrep
している
ヘッダファイルから`#include'されている他のヘッダファイルで
定義されているかもしれません。
egrep
の正規表現です。
ヘッダファイルで定義されたり、Cプリプロセッサで前もって定義されている
Cプリプロセッサシンボルを調べる場合、
AC_EGREP_CPP
を使いましょう。
以下に例題があります:
AC_EGREP_CPP(yes, [#ifdef _AIX yes #endif ], is_aix=yes, is_aix=no) |
egrep
の正規表現です。
このマクロは、もしまだ呼ばれていないなら、
AC_PROG_CPP
またはAC_PROG_CXXCPP
を呼び出します。
どちらを呼ぶかはどちらの言語を選んでいるかに依存します
(see section 5.8 Language Choice)。
「特定のキーワードを認識するかどうか」など、
C、C++ や Fortran 77コンパイラの文法的な機能を調べるためには、
AC_TRY_COMPILE
を使ってそのキーワードや機能を使う小さなプログラムを
コンパイルしてみましょう。
AC_TRY_COMPILE
を使うと、特定のシステムにしかない
構造体や構造体メンバを調べることもできます。
関数の中身がfunction-bodyの記述からなるようなテスト用のC、C++、 Fortran 77プログラム(現在選択されている言語に依存 see section 5.8 Language Choice)を書き出し、それがコンパイラでコンパイルできるかどうか調べます。
CとC++のため、includesはfunction-bodyのコードが必要とする、
あらゆる#include
です(現在選択されている言語がFortran 77の場合は無
視されます)。このマクロは、現在選択されている言語がCやC++の場合、
CFLAGS
やCXXFLAGS
も使用し、コンパイル時にはCPPFLAGS
も使用します。Fortran 77が現在選択されている言語の場合、コンパイル時に
FFLAGS
を使用します。
もしコンパイルできたなら、shellコマンドaction-if-foundを実行します。 もしできなかったらaction-if-not-foundを実行します。
このマクロはリンクを行おうとはしません(コンパイルしかしません)。
テストのためにリンクもしたい場合、AC_TRY_LINK
を使ってください
(see section 5.3 Examining Libraries)。
ライブラリ、関数、またはグローバル変数を調べるために、
Autoconfの生成するconfigure
スクリプトは、小さなプログラムを
コンパイルしてリンクしてみます。
Metaconfigは(デフォルトでは)Cライブラリに対しnm
やar
を
実行することで提供されている関数を調べますが、
AutoconfはMetaconfigとは違います。
実際に関数をリンクしてみる方が判定方法として確実です。
なぜなら、nm
やar
のさまざまなオプションや出力形式、
それから標準ライブラリの置き場所に関する差異を取り扱わなくて済みます。
クロスコンパイルできるかどうかも調べられます。
それに、必要なら関数の実行時の挙動を調べることもできます。
そのかわりに、実際関数をリンクしてみるのは、
ライブラリを一度調べればいいnm
式よりも遅いです。
ごく少数のシステムでは、リンク時に発見できない関数があってもリンカが
「失敗」とのexitステータスを変えしません。
このようなシステムでは、Autoconfで生成されたスクリプトが使えません。
ただし、このようなシステムの一部では、特定のコマンドラインオプションを
与えるとリンカが正しくexitステータスを返すようになります。
Autoconfは現在この問題を自動的に解決していません。
ユーザがこの問題にであった場合、環境変数LDFLAGS
にリンカが必要とする
オプションを設定して渡してやることで解決できるでしょう
(例えばMIPS RISC/OSの場合`-Wl,-dn')。
関数とグローバル変数について調べるためには、AC_TRY_LINK
を使って
テストプログラムをコンパイルしてみます。
このマクロはライブラリの検査(see section 4.2 Library Files)のためにAC_CHECK_LIB
の内部でも使われています。
このためには、LIB
に調べたいライブラリ名を一時的に追加し、
テストプログラムをリンクしてみます。
CやC++では、includeはfunction-bodyのコードで必要となる任意の
#include
文です(現在選択されている言語がFortran 77の場合は無< 視さ
れます)。もし現在選択されている言語がCやC++ならば、このマクロは
CFLAGS
やCXXFLAGS
も使用し、コンパイル時には、
CPPFLAGS
も使用します。もしFortran 77が現在選択されている言語なら
ば、コンパイル時にFFLAGS
を使用します。しかし、LDFLAGS
と
LIBS
は、全ての場合でリンク時に使います。
もし成功したなら、shellコマンドaction-if-foundを実行します。 もしできなかったらaction-if-not-foundを実行します。
もし成功したなら、shellコマンドaction-if-foundを実行します。 もしできなかったらaction-if-not-foundを実行します。
AC_TRY_LINK
に類似した、obsoleteなマクロです。
AC_COMPILE_CHECK
は、echo-textが空でなければ、テストの前に
`checking for echo-text'と標準出力に表示します。
テストの進行状況や結果を表示するには、
AC_MSG_CHECKING
とAC_MSG_RESULT
を使いましょう
(see section 6.4 Printing Messages)。
システムの機能に癖やバグがある場合など、 システムが実行時にどう振舞うのか知らないといけないことがあります。 可能なら、コンパイル時でなしにパッケージの実行時に検査しましょう。 例えば、マシンのendianをプログラムの初期化時に調べることは可能です。
実行時のふるまいをどうしてもパッケージのコンパイル前に調べたい場合、
テストプログラムを書き、AC_TRY_RUN
を使ってコンパイルして
実行し、結果を調べることができます。
可能な限りこの種のテストプログラムを使うことは避けましょう。
あなたのパッケージをクロスコンパイルできなくなります。
5.4.1 Running Test Programs | Running test programs. | |
5.4.2 Guidelines for Test Programs | General rules for writing test programs. | |
5.4.3 Test Functions | Avoiding pitfalls in test programs. |
システムが実行時にどう振舞うのかをコンパイル時に調べるためには、 以下のマクロを使いましょう。
CFLAGS
、CXXFLAGS
、CPPFLAGS
、LDFLAGS
、それから
LIBS
を利用します。
(クロスコンパイルしている等の理由で)現在使っているCコンパイラが、
configure
を実行しているシステムで動かないコードを出力する場合には、
テストプログラムは実行されません。
省略可能なshellコマンドaction-if-cross-compilingが指定された場合、
かわりにshellコマンドが実行されます。
action-if-cross-compilingが指定されていない場合にはconfigure
は
エラーメッセージを出力し終了します。
実行時の振舞いを調べられないクロスコンパイル時のために、
悲観的なデフォルト値を用意しておきましょう。
これは、
AC_TRY_RUN
の最後の引数(action-if-cross-compiling)を
与えることで達成できます。
autoconf
はconfigure
スクリプトを生成する際、
action-if-cross-compilingの指定のないAC_TRY_RUN
があるたび
警告を出します。
警告を無視しても構いませんが、その場合ユーザはあなたのパッケージを
クロスコンパイルできなくなります。
Autoconfと一緒に配布されているマクロには、
このような警告を出すマクロがごく少数あります。
クロスコンパイルのためにパッケージを設定する場合、 正規化されたシステム名(see section 8. Manual Configuration)によって action-if-cross-compilingで決める値を変えることができます。 または、各ターゲットシステムにあわせた正しい値を書いた キャッシュファイルを置いておくこともできます(see section 6.3 Caching Results)。
AC_TRY_RUN
は、Autoconf標準添付のマクロを含めて
他のマクロ内部から呼び出されることがあります。
このような場合に、クロスコンパイル時のためのデフォルト値を設定するためには、
AC_TRY_RUN
より前にAC_PROG_CC
を呼んでおくとよいでしょう。
AC_PROG_CC
を呼んだあと、shell変数cross_compile
が
`yes'だったら、AC_TRY_RUN
を呼ばず、
かわりの方法を使って設定結果の値を決めるのです。
テストプログラムは標準出力になにも書き出してはいけません。
テストが成功したら0を、成功しなかったら0以外を返してexit
すべきです。
これはテストの成功と、core dumpや他の理由によるテスト失敗とを
明確に区別するためです。
セグメンテーションフォールトやその他が起きたときにはexit statusは
0以外になります。
テストプログラムは関数main
からのreturn
でなしに
exit
で終了すべきです。
一部のシステム(少なくとも古いSun)では関数main
の返り値は無視されます。
テストプログラムは#if
や#ifdef
を使って、
既に実行された他のテストで定義されたプリプロセッサマクロを参照できます。
例えば、AC_HEADER_STDC
を呼び出したら、
以後`configure.in'の中で記述するテストプログラムでANSI Cヘッダファイルを
#include
することができます:
#if STDC_HEADERS # include <stdlib.h> #endif |
テストプログラムがデータファイルを使ったり作ったりしないといけない場合、
`conftest'で始まるファイル名、例えば`conftestdata'を使いましょう。
configure
スクリプトは、外部のテストプログラムが終了したときや
スクリプトが中断されたときに、`rm -rf conftest*'を実行して
データファイルを消去します。
テストプログラム中の関数定義をするときは、 C処理系の場合とC++処理系の場合とを条件分けして定義しなければなりません。 実際のところは、テストプログラム中で引数をとる関数を 使うことはめったにありません。
#ifdef __cplusplus foo(int i) #else foo(i) int i; #endif |
プロトタイプ宣言についても同様に条件分けしなければなりません。
C++処理系はC linkageの関数プロトタイプの前に`extern "C"'が必要だからです
(訳註: ちょと補足)。
`extern "C"'が入っていないようなヘッダファイルを
#include
しないように注意してください。
#ifdef __cplusplus extern "C" void *malloc(size_t); #else char *malloc(); #endif |
テストプログラム中で、(単に関数があるかないか調べるために)
不正な引数を使って関数を呼び出す場合、
間違って関数が呼び出されないように注意してプログラムを記述してください。
これは、目的の関数を、絶対呼び出されない関数foo
の中から
呼び出すよう記述することで実現できます。
exit
の後で目的の関数を呼び出すのではテストになりません。
GCCバージョン2は関数exit
のあと処理が戻らないことを知っていて、
exit
と同じブロックの以後の部分をコンパイルしない最適化を
するからです。
ヘッダファイルを#include
して、その中でプロトタイプ宣言されている
関数を呼び出す場合、
プロトタイプ宣言違反でコンパイルエラーが発生しないよう、
(引数が単に0であっても)引数の個数は定義どおりにしてください。
GCCバージョン2では、インライン展開される一部の関数(memcpy
とか)について
コンパイラ内部でプロトタイプ宣言を持っています。
このような関数の有無をチェックする場合、
正しい個数の引数を渡すか、char
などに返り値を変えて再定義してください
(訳註: 返り値の宣言変えて意味あるのか?)。
自分でテストマクロを記述する場合、
shellスクリプトの移植性を高く保つためにいくつかの記法を使わないように
しないといけません。
Bourne shellと(BashやKorn shell等の)上位互換のshellは
長年発達してきましたが、トラブルを避けるため、
1977年ごろのUNIX version 7以降に追加された機能は使わないようにしてください。
shellスクリプト内関数、alias、character classの反転
(訳註: 「negated character classes」)、それから
必ずしも全てのBourne shell互換shellに入っていない機能は使うべきではありません。
最小公約数的なスクリプトを書くように心がけてください。
一部のshellではunset
すら使えません!
スクリプトインタプリタを指定するための#!
の後には、
以下のようにスペースをつけてください:
#! /usr/bin/perl |
configure
スクリプトからは、ごく少数の外部プログラムしか
呼び出してはいけません。
呼び出していいプログラムのリストは
See section `Utilities in Makefiles' in GNU Coding Standardsにあります。
この制限により、プログラム間の依存関係を最小限にとどめ、
ユーザがパッケージをインストールするために
前もって用意しないといけないプログラムを最小限に抑えることができます。
呼び出していい外部プログラムのリストに載っているプログラムについても、
最低限の共通な機能だけを使いましょう(訳註: すごく意訳)。
例えば、ln
が`-f'をサポートしているとか
cat
にコマンドラインオプションがあるとか仮定してはいけません。
sed
スクリプト内には、コメントや8文字以上のラベルがあってはいけません。
`grep -s'で出力を抑制しようとしてはいけません。
System Vでは`grep -s'は出力を抑制せず、エラーメッセージだけ
抑制するからです。
かわりに、grep
の標準出力と標準エラー出力の両方を`/dev/null'に
リダイレクトしましょう
(標準エラー出力もリダイレクトするのは、エラー発生時に出力を出さないように
するためです)。
grep
のexitステータスで、matchする文字列がみつかったかどうか
確認しましょう。
configure
スクリプトは多くのファイルや文字列の特性を検査する必要が
あります。ここではそれら検査を行うときに用心するいくつかの移植性の問題を
あげます。
test
プログラムは多くのファイルや文字列をテストする手段です。それ
はしばしば別の名前`['で実行されます。しかしAutoconfコードの中でその
名前を使うことはそれがm4
のクォート文字の1つであるので災いを招きま
す。
test
を使った多重検査が必要なら、test
プログラムの演算子
`-a'と`-o'の代わりに、シェル演算子`&&'と`||'で組み合
わせてください。System V では`-a'と`-o'の優先順位が単項演算子
に関連して間違っています。したがってPOSIXはそれらを記していません。
だからそれらを使うことは移植性を損ないます。
もしあなたが`&&'と`||'を同じ文で組み合わせるなら、それらが
同じ優先順位を持つことを覚えておいてください。
configure
スクリプトがクロスコンパイルをサポートできるようにするに
は、ターゲットシステムの代わりにホストシステムの特性を検査するべきではあ
りません。しかし、時々あなたはいくつかの恣意的なファイルが存在するかどう
かを検査する必要を見つけるかも知れません。そうするには`test -f' や
`test -r'を使います。`test -x'を使っては行けません。なぜなら
4.3BSDそれを持たないので。
別の移植性を損なうシェルプログラミング構文は以下です。
var=${var:-value} |
sh
を含みます、は、コロンを受け付けず、
不平を言って終了します。移植性のある同等なものは以下です。
: ${var=value} |
Some operations are accomplished in several possible ways, depending on the UNIX variant. Checking for them essentially requires a "case statement". Autoconf does not directly provide one; however, it is easy to simulate by using a shell variable to keep track of whether a way to perform the operation has been found yet.
UNIXの種類に依存して、いくつかの処理は可能な方法で達成されます。本質的に それを調べるためには、"case文"が必要です。Autoconfは直接それを供給しま せん。しかし、実行する処理が見つかったかどうかの追跡を記録するため、シェ ル変数を使って簡単にシミュレーションができます。
ここに、調べる必要があるもののまだ残っているcaseの追跡を記録するため、シェ
ル変数fstype
を使用する例があります。
AC_MSG_CHECKING(how to get filesystem type) fstype=no # The order of these tests is important. AC_TRY_CPP([#include <sys/statvfs.h> #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4) if test $fstype = no; then AC_TRY_CPP([#include <sys/statfs.h> #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3) fi if test $fstype = no; then AC_TRY_CPP([#include <sys/statfs.h> #include <sys/vmount.h>], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX) fi # (more cases omitted here) AC_MSG_RESULT($fstype) |
CとC++の両方を使うパッケージは、両方のコンパイラの特徴をテストする必要が
あります。Autoconfが生成したconfigure
スクリプトは、デフォルトでC
の特徴を調べます。以下のマクロは`configure.in'のテストで、使ってい
る言語のコンパイラを決定します。
CC
とCPP
を使うコンパイルテストを行い、拡張子が`.c'のテ
ストプログラムを使います。もし実行されたならば、AC_PROG_CC
が求め
た値をシェル変数cross_compiling
に、それ以外では空に設定します。
CXX
とCXXCPP
を使うコンパイルテストを行い、拡張子が`.C'
のテストプログラムを使います。もし実行されたならば、AC_PROG_CC
が
求めた値をシェル変数cross_compiling
に、それ以外では空に設定します。
F77
and use extension `.f' for
test programs. Set the shell variable cross_compiling
to the
value computed by AC_PROG_F77
if it has been run, empty
otherwise.
F77
を使うコンパイルテストを行い、拡張子が`.f'のテストプログ
ラムを使います。もし実行されたならば、AC_PROG_CC
が求めた値をシェ
ル変数cross_compiling
に、それ以外では空に設定します。
AC_LANG_C
、AC_LANG_CPLUSPLUS
やAC_LANG_FORTRAN77
が
設定するように)現在の言語をスタックに覚えさせます。現在の言語を変更しま
せん。このマクロとAC_LANG_RESTORE
は、特定の言語を一時的に切替える
必要があるマクロで使ってください。
AC_LANG_SAVE
が設定するように、スタックのトップに保存されている言
語を選択し、スタックから削除します。このマクロは、AC_LANG_SAVE
が
最後に呼ばれた時、最も最近実行されたAC_LANG_C
、
AC_LANG_CPLUSPLUS
やAC_LANG_FORTRAN77
と同じです。
このマクロをAC_LANG_SAVE
より多くの回数、呼び出さないでください。
AC_PROG_CPP
やAC_PROG_CXXCPP
の引数で、現在の言語に依存して、
AC_REQUIRE
(see section 7.4.1 Prerequisite Macros)を呼び出してください。
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |