[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

9. Autoconfマクロを書く

一つ以上のソフトウェアパッケージに適用する特徴テストを書くとき,新しいマ クロの中にそれをカプセル化することが最も良い方法です.Autoconfマクロを書 くための説明とガイドラインは以下のようになります.


9.1 マクロの定義

Autoconfマクロは,M4組み込みのm4_defineマクロに似た AC_DEFUNマクロを使用して定義されています.マクロ定義に加える際, AC_DEFUNは,マクロを呼び出す順番を制限するために使用されるコード を加えます(see section マクロの必要条件).

Autoconfマクロ定義は以下のようになります.

 
AC_DEFUN(macro-name, macro-body)

マクロに渡す引数は,`$1',`$2'等のように参照することが可能です. M4マクロを書く際の完全な情報は,See (m4.info)Definitions section `How to define new macros' in GNU m4.

マクロが偶然前に定義されている場合の問題を避けるために, macro-bodymacro-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のような,出力を生成しな いマクロに続く改行を除去するときに,より役に立ちます.


9.2 マクロ名

全てのAutoconfマクロは,他のテキストと偶然衝突することを避けるため `AC_'で始まる全て大文字の名前になっています.内部目的で使用する全て のシェル変数は,`ac_'で始まるほとんど小文字の名前になっています.マ クロが,現在または将来のAutoconfマクロと衝突しないことを保証するため,マ クロ名と他の手続きで使用するシェル変数に,独自の接頭辞を付けてください. 可能性としては,イニシャルや組織やソフトウェアパッケージの名前の省略を含 めることになるでしょう.

ほとんどのAutoconfマクロ名は,名前によって調査している特徴の種類を示す, 構造化された命名則に続きます.複数の単語から成り立つマクロ名は,アンダー スコアで分けられ,最も一般的なものから最も特殊なものへとなっています. キャッシュ変数の名前も,同じ規則を使用しています(詳細はsee section キャッシュ変数名).

`AC_'の後の名前の最初の単語は,通常テストしている特徴のカテゴリを伝 えるものです.よく書くマクロの種類のテストマクロを指定するため,Autoconf が使用するカテゴリは以下のようになっています.それらはキャッシュ変数でも 全て小文字で使用されます.適用可能なものを使用してください.無ければ独自 のカテゴリを考え出してください.

C

C言語組み込み特徴.

DECL

ヘッダファイルでのC変数の宣言.

FUNC

ライブラリの関数.

GROUP

ファイルのUNIXグループオーナー.

HEADER

ヘッダファイル.

LIB

Cライブラリ.

PATH

プログラムを含むファイルのフルパス名.

PROG

プログラムのベース名.

MEMBER

集合体のメンバ.

SYS

オペレーティングシステムの特徴.

TYPE

C組み込みや宣言されている型.

VAR

ライブラリのC変数.

カテゴリの後には,特定の特徴をテストしている名前が来ます.マクロ名のそれ 以外の単語は,特徴の特定の側面を示します.例えば, AC_FUNC_UTIME_NULLは,NULLポインタで呼び出されたときの utime関数の動作を調査します.

内部マクロは,アンダースコアで始まる名前にすべきです.そのため,Autoconf 内部のものは`_AC_'で始まります.さらに,他のマクロ内部のサブルーチ ンとなるマクロは,アンダースコアと他のマクロ名ではじまり,内部マクロが行 うことを伝える一つ以上の単語が続きます.例えば, AC_PATH_Xは,内 部マクロに_AC_PATH_X_XMKMF_AC_PATH_X_DIRECTがあります.


9.3 メッセージの報告

マクロが良性または悪性の異常な状況を静的に診断しているとき,以下のマクロ を使用してそれを報告すべきです.動的な発行,すなわちconfigure が実行されているときは,メッセージの出力を参照してください.

Macro: AC_DIAGNOSE (category, message)

categoryの警告をオンにしている場合,messageを警告として(また はユーザが要求する場合はエラーとして)報告します.以下の現在含められてい る標準的なカテゴリを使用することを勧めます.

` all'

以下のカテゴリの一つに分類されないメッセージです.空のcategoryを使 用することと等価です.

` cross'

クロスコンパイルに関連する問題です.

` obsolete'

時代遅れの構成の使用です.

` syntax'

曖昧な構文構成,間違った順序のマクロ呼び出しです.

Macro: AC_WARNING (message)

`AC_DIAGNOSE([syntax], message)'と等価ですが,より良く分類さ れているカテゴリを使用することを推奨します.

Macro: AC_FATAL (message)

ひどいエラーmessageを報告し,autoconfは終了します.

ユーザが`autoconf -W error'を実行しているとき,AC_DIAGNOSEAC_WARNINGからの警告はエラーとして報告されます.configureを作成するためautoconfを使用するを参照してください.


9.4 マクロ間の依存性

正確に動作するために,最初に他のマクロが呼び出されていることに依存する Autoconfマクロもあります.Autoconfは,必要な場合はある特定のマクロが呼び 出されていることを保証する方法と,マクロが間違った処理を引き起こす順序で 呼び出された場合に警告する方法を供給します.


9.4.1 マクロの必要条件

書いているマクロが,以前に他のマクロが計算した値を使用する必要があるかも しれません.例えば,AC_DECL_YYTEXTは,flexlex の 出力を調査するので,シェル変数 LEXを設定するために, AC_PROG_LEXが最初に呼び出されていることに依存します.

マクロのユーザにそれら間の依存性を追跡させるより,自動的にするために AC_REQUIREを使用することが可能です.AC_REQUIREは,必要な 場合のみマクロが呼び出され,そして一度だけ呼び出されることを保証します.

Macro: AC_REQUIRE (macro-name)

M4マクロmacro-nameがまだ呼び出されていない場合,それを(引数無しで) 呼び出します.角カッコでmacro-nameを囲んでいることを確認してくださ い.macro-nameは,AC_DEFUNを使用して定義されている,または 呼び出されていることを示すAC_PROVIDEの呼び出しを含んでいる必要が あります.

AC_REQUIREAC_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を使用することが可能です.


9.4.2 推奨される順序

両方が呼び出されても,片方がもう一方が呼び出されることを要求しな い場合,もう一方のマクロの前に実行するすべきマクロもあります.例えば,C コンパイラの動作を変更するマクロは,Cコンパイラを実行するあらゆるマクロ の前に呼び出されるべきです.これらの依存性の多くはドキュメントに記されて います.

Autoconfは,これらの依存性を持つマクロが`configure.ac'ファイルで順 序が間違って現れるとき,ユーザに警告するAC_BEFOREを提供しています. 警告は,`configure.ac'からconfigureを作成するときに発生し ますが,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が既に呼 び出されている場合,ユーザに警告します.

Macro: AC_BEFORE (this-macro-name, called-macro-name)

called-macro-nameが既に呼び出されている場合,M4は標準エラー出力に 警告メッセージを出力します.this-macro-nameは,AC_BEFOREを 呼び出すマクロの名前にすべきです.マクロcalled-macro-nameは, AC_DEFUNを使用して定義されている,または呼び出されていることを示 すAC_PROVIDEの呼び出しを含んでいる必要があります.


9.5 時代遅れのマクロ

コンフィグレーションと移植性の技術は,何年もかかって進展しました.特定の 問題を解決するより良い方法が開発されたり,特別なアプローチが体系化される ことはよくあります.この過程はAutoconfの数多くの部分で発生しました.一つ の結果は,今では時代遅れ(obsolete)と思われるマクロの存在です.まだ 動作しますが,すでにそれが最善の方法ではなくなっていて,より近代的なマク ロで置換すべきでしょう.理想的には,autoupdateが古いマクロの呼 び出しを現在のマクロに置換すべきでしょう.

Autoconfは,マクロが時代遅れだということを意味する単純なものを提供してい ます.

Macro: AU_DEFUN (old-macro, implementation, [message])

implementationとしてold-macroを定義します.AC_DEFUN を用いたものとは,old-macroが現在は時代遅れだという警告をユーザが 受けるところだけが異なります.

autoupdateを使用する場合,old-macroの呼び出しは現在の implementationで置換されます.更に,messageが出力されます.


9.6 コーディングスタイル

Autoconfマクロはスクリプトコーディングスタイルに従います.以下のスタイル に従うように推奨し,特に,Autoconf自身に寄稿したり,その他の目的で,マク ロを配布する目的がある場合はそうしてください.

最初に必要なことは,引用符に大きく注意を払うことです.詳細は, Autoconf言語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をハッキ ングするより何か他のことをした方が良いでしょう:-)

sedを使用しているとき,字下げの目的以外で`-e'を使用しな いでください.sコマンドを用いた場合,`/'自身がコマンドで使用 されない限り,優先されるセパレータは`/'にし,コマンドで使用される場 合は`,'を使用すべきです.

マクロ定義の方法の詳細は,See section マクロの定義. マクロで AC_REQUIREを使用しておらず,AC_REQUIREディレクティブのオブ ジェクトがないことを期待する場合,m4_defineを使用してください.疑 わしい場合は,AC_DEFUNを使用してください.全てのAC_REQUIRE 文は,dnlされているマクロの最初に書くべきです.

引数の数に依存すべきではありません.引数が足りないことを調査する代わりに, 空でないことをテストしてください.より簡単でより予測可能なインターフェー スをユーザに提供し,余分な引数に対する余地を節約してください.

マクロが短くない場合は,行の最初に`])'を残し,定義されているマクロ の名前を繰り返すコメントを続けてください.これは,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

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.