一つ以上のソフトウェアパッケージに適用する特徴テストを書くとき,新しい マクロの中にそれをカプセル化することが最も良い方法です.Autoconfマクロ を書くための説明とガイドラインは以下のようになります.
Autoconfマクロは,M4組み込みのm4_define
マクロに似た
AC_DEFUN
マクロを使用して定義されています.マクロ定義に加える際,
AC_DEFUN
は,マクロを呼び出す順番を制限するために使用されるコー
ドを加えます(see section マクロの必要条件).
Autoconfマクロ定義は以下のようになります.
AC_DEFUN(macro-name, macro-body)
マクロに渡す引数は,`$1',`$2'等のように参照することが可能で す.M4マクロを書く際の完全な情報は,See section `How to define new macros' in @acronym{GNU m4}.
マクロが偶然前に定義されている場合の問題を避けるために, macro-bodyとmacro-nameの両方を,適切に引用符で囲ん でいることを確かめてください.
それぞれのマクロには,そのプロトタイプと短い説明を付与するため,ヘッダ のコメントを書くべきです.引数がデフォルト値の場合,そのプロトタイプを 表示してください.例えば以下のようにします.
# AC_MSG_ERROR(ERROR, [EXIT-STATUS = 1]) # -------------------------------------- m4_define([AC_MSG_ERROR], [{ _AC_ECHO([configure: error: $1], 2); exit m4_default([$2], 1); }])
マクロに関するコメントは,ヘッダコメントに残すべきです.その他のほとん どのコメントは,勝手に`configure'に入るので,コメントを導入するた めに`#'を使用し続けるだけで結構です.
ピュアなM4コードに関して,非常に特殊なコメントがある場合は,コメントを
`configure'とヘッダコメントに入れる意味がないので,組み込みの
dnl
を使用してください.それでM4は,次の改行までのテキストを廃棄
します.
dnl
がコメントの導入に必要になることは滅多にないということを覚えて
おいてください.dnl
は,AC_REQUIRE
のような,出力を生成しな
いマクロに続く改行を除去するときに,より役に立ちます.
全てのAutoconfマクロは,他のテキストと偶然衝突することを避けるため `AC_'で始まる全て大文字の名前になっています.内部目的で使用する全 てのシェル変数は,`ac_'で始まるほとんど小文字の名前になっています. マクロが,現在または将来のAutoconfマクロと衝突しないことを保証するため, マクロ名と他の手続きで使用するシェル変数に,独自の接頭辞を付けてくださ い.可能性としては,イニシャルや組織やソフトウェアパッケージの名前の省 略を含めることになるでしょう.
ほとんどのAutoconfマクロ名は,名前によって調査している特徴の種類を示す, 構造化された命名則に続きます.複数の単語から成り立つマクロ名は,アンダー スコアで分けられ,最も一般的なものから最も特殊なものへとなっています. キャッシュ変数の名前も,同じ規則を使用しています(詳細はsee section キャッシュ変数名).
`AC_'の後の名前の最初の単語は,通常テストしている特徴のカテゴリを 伝えるものです.よく書くマクロの種類のテストマクロを指定するため, Autoconf が使用するカテゴリは以下のようになっています.それらはキャッ シュ変数でも全て小文字で使用されます.適用可能なものを使用してください. 無ければ独自のカテゴリを考え出してください.
C
DECL
FUNC
GROUP
HEADER
LIB
PATH
PROG
MEMBER
SYS
TYPE
VAR
カテゴリの後には,特定の特徴をテストしている名前が来ます.マクロ名のそ
れ以外の単語は,特徴の特定の側面を示します.例えば,
AC_FUNC_UTIME_NULL
は,NULL
ポインタで呼び出されたときの
utime
関数の動作を調査します.
内部マクロは,アンダースコアで始まる名前にすべきです.そのため,
Autoconf 内部のものは`_AC_'で始まります.さらに,他のマクロ内部の
サブルーチンとなるマクロは,アンダースコアと他のマクロ名ではじまり,内
部マクロが行うことを伝える一つ以上の単語が続きます.例えば,
AC_PATH_X
は,内部マクロに_AC_PATH_X_XMKMF
と
_AC_PATH_X_DIRECT
があります.
マクロが良性または悪性の異常な状況を静的に診断しているとき,以下のマク ロを使用してそれを報告すべきです.動的な発行,すなわち @command{configure} が実行されているときは,section メッセージの出力を 参照してください.
ユーザが`autoconf -W error'を実行しているとき,AC_DIAGNOSE
とAC_WARNING
からの警告はエラーとして報告されます.section @command{configure}を作成するため@command{autoconf}を使用するを参照してください.
正確に動作するために,最初に他のマクロが呼び出されていることに依存する Autoconfマクロもあります.Autoconfは,必要な場合はある特定のマクロが呼 び出されていることを保証する方法と,マクロが間違った処理を引き起こす順 序で呼び出された場合に警告する方法を供給します.
書いているマクロが,以前に他のマクロが計算した値を使用する必要があるか
もしれません.例えば,AC_DECL_YYTEXT
は,flex
やlex
の出力を調査するので,シェル変数 LEX
を設定するために,
AC_PROG_LEX
が最初に呼び出されていることに依存します.
マクロのユーザにそれら間の依存性を追跡させるより,自動的にするために
AC_REQUIRE
を使用することが可能です.AC_REQUIRE
は,必要な
場合のみマクロが呼び出され,そして一度だけ呼び出されることを保証します.
AC_DEFUN
を使用して定義されている,
または呼び出されていることを示すAC_PROVIDE
の呼び出しを含んでい
る必要があります.
AC_REQUIRE
はAC_DEFUN
マクロの内部で使用する必要があります.
それはトップレベルから呼び出してはいけません.
AC_REQUIRE
はよく誤解されます.一つのマクロが他のものに依存して
いる場合,後者は前者の本体の前に展開されるように,それはマクロ
間の依存性を実装しています.特に,`AC_REQUIRE(FOO)'は,FOO
の本体では置換されません.例えば,マクロを以下のように定義したとします.
AC_DEFUN([TRAVOLTA], [test "$body_temperature_in_celsius" -gt "38" && dance_floor=occupied]) AC_DEFUN([NEWTON_JOHN], [test "$hair_style" = "curly" && dance_floor=occupied]) AC_DEFUN([RESERVE_DANCE_FLOOR], [if date | grep '^Sat.*pm' >/dev/null 2>&1; then AC_REQUIRE([TRAVOLTA]) AC_REQUIRE([NEWTON_JOHN]) fi])
これを`configure.ac'で使用します.
AC_INIT RESERVE_DANCE_FLOOR if test "$dance_floor" = occupied; then AC_MSG_ERROR([cannot pick up here, let's move]) fi
それは以下のように展開されるので,土曜日の夜以外に仲間に会う機会が残っ ていません.
test "$body_temperature_in_Celsius" -gt "38" && dance_floor=occupied test "$hair_style" = "curly" && dance_floor=occupied fi if date | grep '^Sat.*pm' >/dev/null 2>&1; then fi
この動作は意図的に選択されました.(i) それは要求されるマクロのメッセー ジが,要求しているマクロのメッセージとして解釈されることを妨げます. (ii) それは,シェルの条件文が使用されるときひどく驚くことを妨げます. 以下のようになります.
if ...; then AC_REQUIRE([SOME_CHECK]) fi ... SOME_CHECK
マクロの最初に全てのAC_REQUIRE
を書き込むことを推奨します.空の
行が残ることを避けるため,dnl
を使用することが可能です.
両方が呼び出されても,片方がもう一方が呼び出されることを要求し ない場合,もう一方のマクロの前に実行するすべきマクロもあります.例えば, Cコンパイラの動作を変更するマクロは,Cコンパイラを実行するあらゆるマク ロの前に呼び出されるべきです.これらの依存性の多くはドキュメントに記さ れています.
Autoconfは,これらの依存性を持つマクロが`configure.ac'ファイルで
順序が間違って現れるとき,ユーザに警告するAC_BEFORE
を提供してい
ます.警告は,`configure.ac'から@command{configure}を作成するとき
に発生しますが,@command{configure}実行時には発生しません.
例えばAC_PROG_CPP
は,Cコンパイラに`-E'オプションが与えられ
ているとき,Cプリプロセッサが実行可能かどうか調査します.従って,使用
されるCコンパイラが変更されるAC_PROG_CC
のようなマクロの後で,そ
れは呼び出すべきです.そのため,AC_PROG_CC
は以下を含んでいます.
AC_BEFORE([$0], [AC_PROG_CPP])dnl
これで,AC_PROG_CC
が呼び出されたとき,AC_PROG_CPP
が既に
呼び出されている場合,ユーザに警告します.
AC_BEFORE
を呼び出すマクロの名前にすべきです.マクロ
called-macro-nameは,AC_DEFUN
を使用して定義されている,ま
たは呼び出されていることを示すAC_PROVIDE
の呼び出しを含んでいる
必要があります.
コンフィグレーションと移植性の技術は,何年もかかって進展しました.特定 の問題を解決するより良い方法が開発されたり,特別なアプローチが体系化さ れることはよくあります.この過程はAutoconfの数多くの部分で発生しました. 一つの結果は,今では時代遅れ(obsolete)と思われるマクロの存在です. まだ動作しますが,すでにそれが最善の方法ではなくなっていて,より近代的 なマクロで置換すべきでしょう.理想的には,@command{autoupdate}が古いマ クロの呼び出しを現在のマクロに置換すべきでしょう.
Autoconfは,マクロが時代遅れだということを意味する単純なものを提供して います.
AC_DEFUN
を用いたものとは,old-macroが現在は時代遅れだという警告をユーザ
が受けるところだけが異なります.
@command{autoupdate}を使用する場合,old-macroの呼び出しは現在の implementationで置換されます.更に,messageが出力されます.
Autoconfマクロはスクリプトコーディングスタイルに従います.以下のスタイ ルに従うように推奨し,特に,Autoconf自身に寄稿したり,その他の目的で, マクロを配布する目的がある場合はそうしてください.
最初に必要なことは,引用符に大きく注意を払うことです.詳細は, section Autoconf言語とsection M4の引用符を参照してください.
新たなインターフェースの発明は試みないでください.定義しているマクロに 似ているAutoconfマクロが存在することはよくあります.この既存のインター フェースに従ってみてください(引数の順序,デフォルト値,等々).我々は, これらのインターフェースに完全でないものがあることは,意識してい ます.それにもかかわらず,無害なときは,創造性より均質性が好まれるで しょう.
M4シンボル間とシェル変数間の両方の衝突に注意してください.
推奨されるM4命名規則(see section マクロ名)に従う場合,衝突が生じること
はあまりないでしょう.それにもかかわらず,特殊な値を設定する必要がある
とき,通常のマクロ名を使用することを避けてください."信じられ
ない"名前を使用する代わりです.例えば,バージョン2.13までは,通常のマ
クロ名AC_SUBST_symbol
を設定することで既に定義されている
symbolを記憶するため,マクロAC_SUBST
を使用していました.
しかし,AC_SUBST_FILE
と命名されているマクロが存在するので,
`AC_SUBST(FILE)'を使用することはできませんでした!この場合,
AC_SUBST(symbol)
や_AC_SUBST(symbol)
が使用さ
れるべきでした(そうです,カッコは使用します)...または,より良い方
法として,AC_EXPAND_ONCE
のようなハイレベルのマクロを使用すべき
でした.
Autoconfマクロは,ユーザ変数の名前空間に入るべきではありません.すなわ
ち,実際のマクロの実行結果となる変数以外の,全てシェル変数はac_
で始めるべきです.さらに,小さなマクロや他のマクロに埋め込まれるような
マクロは,明示的な名前を使用しないように注意すべきです.
コメントを導入するために,dnl
を使用しないでください.書こうとし
ているコメントのほとんどは,出力されないヘッダコメント,または,
`configure'に書かれるべきコメントです.特殊なM4の構成のコメントが
欲しい場合は例外があり,その場合はdnl
が正しいのですが,あまりな
いことだということを覚えておいてください.
M4は,引数に前置されるスペースを無視します.呼び出されているマクロの開 カッコに,引数が整列するように字下げするために,この特徴を使用してくだ さい.例えば,以下の代わりを考えます.
AC_CACHE_CHECK(for EMX OS/2 environment, ac_cv_emxos2, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __EMX__;])], [ac_cv_emxos2=yes], [ac_cv_emxos2=no])])
以下のように書いてください.
AC_CACHE_CHECK([for EMX OS/2 environment], [ac_cv_emxos2], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return __EMX__;])], [ac_cv_emxos2=yes], [ac_cv_emxos2=no])])
または,以下のようにしてください.
AC_CACHE_CHECK([for EMX OS/2 environment], [ac_cv_emxos2], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return __EMX__;])], [ac_cv_emxos2=yes], [ac_cv_emxos2=no])])
AC_RUN_IFELSE
や,クロスコンパイルで動作不可能なマクロを使用して
いるとき,悲観的な値(通常は`no')を提供してください.
構文をハイライト表示するエディタのような,補助ツールが不適切に動作する ことを避けるため,様々な手段を自由に使用してください.例えば以下を考え ます.
m4_bpatsubst([$1], [$"])
以下を使用してください.
m4_bpatsubst([$1], [$""])
それは,Emacsenが最初の引用符で終りのない"文字列"を開いたままにしな いようにするためです.同じ理由から以下のようなことは避けてください.
test $[#] != 0
以下を使用してください.
test $[@%:@] != 0
そうしない場合,閉カッコは`#'コメント内に隠され,Emacsenのカッコ
一致のハイライト表示を破壊します.好ましいスタイルは,M4からエスケープ
されるように注意してください.`$[1]',`$[@]',等です.不必
要なときにエスケープしないようにしてください.意味のない引用符の一般的
な例は,`[$]$1'(`$$1'と書いてください),
`[$]var'(`$var'を使用してください),等です.移植性の問題をこ
の状態に加える場合,`"[$]@"'より`${1+"$[@]"}'にした方が
良く,Autoconfをハッキングするより何か他のことをした方が良いでしょう
:-)
.
@command{sed}を使用しているとき,字下げの目的以外で@option{-e}を使用し
ないでください.s
コマンドを用いた場合,`/'自身がコマンドで
使用されない限り,優先されるセパレータは`/'にし,コマンドで使用さ
れる場合は`,'を使用すべきです.
マクロ定義の方法の詳細は,See section マクロの定義. マクロで
AC_REQUIRE
を使用しておらず,AC_REQUIRE
ディレクティブのオ
ブジェクトがないことを期待する場合,m4_define
を使用してください.
疑わしい場合は,AC_DEFUN
を使用してください.全ての
AC_REQUIRE
文は,dnl
されているマクロの最初に書くべきです.
引数の数に依存すべきではありません.引数が足りないことを調査する代わり に,空でないことをテストしてください.より簡単でより予測可能なインター フェースをユーザに提供し,余分な引数に対する余地を節約してください.
マクロが短くない場合は,行の最初に`])'を残し,定義されているマク ロの名前を繰り返すコメントを続けてください.これは, @command{configure}に余分な改行を導入します.通常は問題ありませんが, 削除したい場合は,行の最後に`[]dnl'を使用することが可能です.同様 に,マクロ呼び出しの後に,改行を削除するため,`[]dnl'を使用するこ とも可能です.M4が`dnl' をテキストやマクロ出力の前に付けられてい るものとして解釈しないことを確実にするため,`[]dnl'は`dnl'の 代わりとして推奨されています.例えば以下の代わりを考えます.
AC_DEFUN([AC_PATH_X], [AC_MSG_CHECKING([for X]) AC_REQUIRE_CPP() # ...omitted... AC_MSG_RESULT([libraries $x_libraries, headers $x_includes]) fi])
以下のように書くべきです.
AC_DEFUN([AC_PATH_X], [AC_REQUIRE_CPP()[]dnl AC_MSG_CHECKING([for X]) # ...omitted... AC_MSG_RESULT([libraries $x_libraries, headers $x_includes]) fi[]dnl ])# AC_PATH_X
マクロが長い場合,論理的な塊に分けてみてください.通常マクロは,関数の
バグを調査し,このセットアップを実行するための補助マクロがある
AC_LIBOBJ
の置換を準備します.コードの要素に補助マクロを導入する
ことをためらわないでください.
推奨されるコーディングスタイルを強調するために,古い手法で書かれている マクロを紹介します.
dnl Check for EMX on OS/2. dnl _AC_EMXOS2 AC_DEFUN(_AC_EMXOS2, [AC_CACHE_CHECK(for EMX OS/2 environment, ac_cv_emxos2, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, return __EMX__;)], ac_cv_emxos2=yes, ac_cv_emxos2=no)]) test "$ac_cv_emxos2" = yes && EMXOS2=yes])
新しい方法は以下のようにします.
# _AC_EMXOS2 # ---------- # Check for EMX on OS/2. m4_define([_AC_EMXOS2], [AC_CACHE_CHECK([for EMX OS/2 environment], [ac_cv_emxos2], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return __EMX__;])], [ac_cv_emxos2=yes], [ac_cv_emxos2=no])]) test "$ac_cv_emxos2" = yes && EMXOS2=yes[]dnl ])# _AC_EMXOS2
Go to the first, previous, next, last section, table of contents.