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


Autoconfマクロを書く

一つ以上のソフトウェアパッケージに適用する特徴テストを書くとき,新しい マクロの中にそれをカプセル化することが最も良い方法です.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-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のような,出力を生成しな いマクロに続く改行を除去するときに,より役に立ちます.

マクロ名

全ての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があります.

メッセージの報告

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

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を報告し,@command{autoconf}は終了します.

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

マクロ間の依存性

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

マクロの必要条件

書いているマクロが,以前に他のマクロが計算した値を使用する必要があるか もしれません.例えば,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を使用することが可能です.

推奨される順序

両方が呼び出されても,片方がもう一方が呼び出されることを要求し ない場合,もう一方のマクロの前に実行するすべきマクロもあります.例えば, 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が既に 呼び出されている場合,ユーザに警告します.

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の呼び出しを含んでいる 必要があります.

時代遅れのマクロ

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

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

Macro: AU_DEFUN (old-macro, implementation, @ovar{message})
implementationとしてold-macroを定義します.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.