Ruby の拡張ライブラリのための Makefile を作成するライブラリです。通常 extconf.rb という名の ruby スクリプトの中で require され、このスクリプ トを実行することで Makefile を作成するのが慣習となっています。
拡張ライブラリの作り方(extconf.rbの書き方)に関しては ruby のアーカイブ に含まれる [ruby-src:README.EXT] (日本語版は [ruby-src:README.EXT.ja])も参照してください。
架空の拡張ライブラリ foo.so を作成することを考えます。この拡張ライブラ リを作成するためには、ヘッダファイル bar.h とライブラリ libbar.a の関 数 baz() が必要だとします。このための extconf.rb は以下のように書きま す。
require 'mkmf.rb' dir_config('bar') if have_header('bar.h') and have_library('bar', 'baz') create_makefile('foo') end
そして、拡張ライブラリを作成、インストールするには以下のようにします。
$ ruby extconf.rb $ make $ make site-install
dir_config('bar')
により、ヘッダファイルのパス、ライブラリのパス
を以下のように指定できます。
$ ruby extconf.rb --with-bar-include=/usr/local/include \ --with-bar-lib=/usr/local/lib あるいは $ ruby extconf.rb --with-bar-dir=/usr/local
詳細は dir_config を参照してください。
ここでの configure オプションとは ruby インタプリタ作成時に指定された configure スクリプトのオプション、または extconf.rb 実行時のオプショ ンのことです。extconf.rb の作成者は任意のオプションを定義できます。 (arg_config を参照)。
また、以下のオプションがデフォルトで利用可能です。
ヘッダファイルを探索するディレクトリ directory を追加します。
ライブラリファイルを探索するディレクトリ directory を追加します。
ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。
extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。
ヘッダファイルを探索するディレクトリ directory を追加します。
extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。
ライブラリを探索するディレクトリ directory を追加します。
extconf.rb の中で dir_config(target) を実行していればこ のオプションを指定できます。
ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。
カレントディレクトリに depend という名前のファイルがあればこの内容は生 成される Makefile の最後に追加されます。
このファイルは、ソースファイルの依存関係を記述するために使用します。例 えば、拡張ライブラリのソース foo.c が foo.h をインクルードしていれば foo.h が更新されたときにも foo.c を再コンパイルしたくなります。
このような依存関係を記述するには depend ファイルに以下を書きます。
foo.o: foo.c foo.h
これは、foo.o が foo.c と foo.h に依存し、これらが更新されれば foo.o は再作成されることを示します。
C コンパイラによっては、このような出力を自動生成することができます。こ のためのオプションは -M として知られています。
cc -M *.c > depend
は、上記の出力を得ます。
gcc では、さらに -MM というオプションがあります。これは(通常更新するこ とのないstdio.hなど)システムのヘッダファイルを依存ファイルとみなしませ ん。(#include <...> の形式で参照されるヘッダファイルをシステムのヘッダ ファイルとみなすようです)
gcc -MM *.c > depend
のように使います。
depend ファイルを他の用途で使用しては行けません。mkmf.rb はこの内容を Makefile に出力する際に多少の加工を行う場合があります。
extconf.rb が生成した Makefile には以下のターゲットが定義されています。
拡張ライブラリを作成します。
作成した拡張ライブラリ、オブジェクトファイルなどを削除します。
clean に加えて Makefile extconf.h(create_header参照) core ruby などを削除します。
作成した拡張ライブラリを $archdir にインストールします。カレン トディレクトリにディレクトリ lib があればその配下の ruby スクリプト (.rb ファイル)をディレクトリ階層ごと $libdir にインストールし ます。
独立したライブラリとしてコンパイルされた場合、拡張ライブラリは $sitearchdir に、 ruby スクリプトは $sitelibdir にインストールされます。
以下は、extconf.rb を記述するのに有用な関数です。ヘッダファイルの存在 チェック、ライブラリの存在チェックなど、システム間の差異を調べシステム に適した Makefile を生成するためにこれらの関数が必要となります。
try_link(src[, opt])
C ソース src をコンパイル、リンクします。リンクの結果が正常 かどうかを true または false で返します。
optが指定されていればリンク時のコマンド引数として渡されます。 このメソッドは、$CFLAGS、$LDFLAGS の値もコンパイラ、リ ンカに渡します。
src には直接 C ソースを文字列で書きます。
try_cpp(src[, opt])
C ソース src をプリプロセスし、その結果が正常かどうかを true または false で返します。
$CFLAGS opt
をプリプロセッサの引数に渡します。
src には直接 C ソースを文字列で書きます。
このメソッドはヘッダファイルの存在チェックなどに使用します。
egrep_cpp(pat, src[, opt])
C ソース src をプリプロセスし、その結果が正規表現 pat にマッチするかどうかを判定します。pat には、egrepの正 規表現を文字列で指定します。
を実行し、その結果が正常かどうかを true または false で返します。
src には直接 C ソースを文字列で書きます。
このメソッドはヘッダファイルに関数などの宣言があるかどうかを検 査するのに使用します。
try_run(src[, opt])
C ソース src をコンパイルし、生成された実行ファイルを実行し た結果が正常かどうかを true または false で返します。
src には直接 C ソースを文字列で書きます。
install_rb(mfile, dest[, srcdir])
このメソッドは、create_makefile が使用します
ディレクトリ srcdir/lib
配下の ruby スクリプト
(.rb
ファイル)をdest にインストールするための Makefile
規則を mfile に出力します。mfile は IO クラスの
インスタンスです。
srcdir/lib
のディレクトリ構造はそのまま dest 配
下に反映されます。
引数 srcdir のデフォルトは "." です。
append_library(libs, lib)
ライブラリ lib をライブラリのリスト libs の先頭に追加 した結果を返します。
引数 libs とこのメソッドの戻り値はリンカに渡す引数形式の文字 列です。これは UNIX では、
"-lfoo -lbar"
であり、MS-Windows などでは
"foo.lib bar.lib"
です。引数 lib は、この例での "foo"
や "bar"
に
あたります。
have_library(lib[, func])
ライブラリ lib がシステムに存在し、関数 func が定義され ているかどうかを検査します。検査に成功すれば $libs に lib を追加し true を返します。そうでなければ false を返しま す。
func の指定を省略した場合、関数の存在は検査しません。
func が nil または空文字列("") であれば特に何も検査をせずに、 無条件で lib を追加します。
find_library(lib, func[, path1[, path2[, ...]]])
関数 func が定義されたライブラリ lib を探します。最初 にパス指定なしで検査し、次にpath1を指定、ダメならpath2 を指定・・・といったように順にリンク可能なライブラリを探索します。
検査に成功すれば lib を $libs に追加し、見つかったパス を $LDFLAGS に追加して true を返します。指定されたすべての パスを検査してもライブラリ lib が見つからなければ false を返 します。
path の指定がなければhave_libraryと同じです。
have_func(func[, header])
関数 func が存在するかどうかを検査します。
func が存在すれば $defs に -DHAVE_func
(func は大文字に変換されます)を追加して true を返します。そ
うでなければ false を返します。
header には、関数funcを使用するのに必要なヘッダファイ ル名を指定します。これは引数の型チェックのためではなく(そのような 検査はこのメソッドでは行われません)関数が実際にはマクロで定義され ている場合などのために使用します。
have_header(header)
ヘッダファイル header が存在するかどうかを検査します。
header が存在すれば $defs に、
-DHAVE_header
(header は実際には大文字に変換され
文字 "-", "." が、"_" に置き換えられます)を追加して true を返しま
す。そうでなければ false を返します。
arg_config(config[, default])
configure オプション --config の値を返します。値が設定 されていなければ default を返します。
extconf.rb の場合、
ruby extconf.rb --foo --bar=baz
と実行すれば arg_config("foo") の値は true、arg_config("bar") の値は "baz" です。
with_config(config[, default])
arg_config と同じですが、--with-config
オプショ
ンの値だけを参照します。
enable_config(config[, default])
arg_config と同じですが、--enable-config
オプショ
ン、または--disable-config
オプションの値だけを参照しま
す。
create_header()
have_funcなどの検査結果を元に
#define HAVE_FUNC 1 #define HAVE_HEADER_H 1
などを定義した extconf.h ファイルを生成します。
dir_config(target[, default])
dir_config(target[, idefault, ldefault])
システムに標準では存在しないヘッダファイルやライブラリがあるディレ クトリを extconf.rb の利用者が指定できるようにします。
最初の形式では、configure オプション
--with-target-dir=path
が指定されていれば、
$CFLAGS に "-Ipath/include" を $LDFLAGS に
"-Lpath/lib" を追加します。
--with-target-dir
の代わりに configure オプション
--with-target-include
、--with-target-lib
が指定されていれば、これらの値を $CFLAGS
、$LDFLAGS
に
それぞれ追加します。
configure オプションがいずれも指定されていなければ、省略可能な引数
deafult、idefault、ldefault が使用されます。最初
の形式では、"-Idefault/include"
、
"-Ldefault/lib"
をそれぞれ追加し、二番目の形式では
"-Iidefault"
、"-Lldefault"
をそれぞれ追加
します。
create_makefile(target[, srcdir])
have_libraryなどの各種検査の結果を元に 拡張ライブラリ target.so を作成する Makefile を生成します。
srcdir は make 変数 srcdir の値になり、これにはソー スがあるディレクトリ名を指定します。省略した場合は、 extconf.rb があるディレクトリです。
extconf.rb は普通このメソッドの呼び出しで終ります。
CONFIG
Config::MAKEFILE_CONFIG と同じです。
CFLAGS
この値は、Makefileにも反映されます。
LINK
リンクを検査するときのコマンドラインのフォーマットです。 try_linkなどが使用します。
CPP
プリプロセスを検査するときのコマンドラインのフォーマットです。 try_cppなどが使用します。
$srcdir
ruby インタプリタを make したときのソースディレクトリです。
$libdir
ruby のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/version
です。
$archdir
マシン固有のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/version/arch
です。
$sitelibdir
サイト固有のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/site_ruby/version
です。
$sitearchdir
サイト固有でかつマシン固有のライブラリを置くディレクトリです。
通常 /usr/local/lib/ruby/site_ruby/version/arch
です。
$hdrdir
ruby のヘッダファイル ruby.h
が存在するディレクトリです。
通常 /usr/local/lib/ruby/version/arch
です。
$topdir
拡張ライブラリを make するためのヘッダファイル、ライブラリ等が存在 するディレクトリです。
通常 /usr/local/lib/ruby/version/arch
です。
$defs
拡張ライブラリをコンパイルするときのマクロ定義を指定する配列です。
have_func、have_header の検査結果はこの配列の要素になり
["-DHAVE_FUNC", "-DHAVE_HEADER_H"]
といった値になります。
create_header は、この変数の値を参照してヘッダファイルを生成 します。
$libs
拡張ライブラリをリンクするときに一緒にリンクされるライブラリを指定 する文字列です。
have_library、find_library の検査結果はこの文字列に
"-lfoo -lbar"
のように間に空白を置いて連結されます。
$CFLAGS
拡張ライブラリをコンパイルするときの C コンパイラのオプション、ヘッ ダファイルのディレクトリを指定する文字列です。
dir_config はこの変数に値 "-Idir" を追加します。
$LDFLAGS
拡張ライブラリをリンクするときのリンカのオプション、ライブラリファ イルのディレクトリを指定する文字列です。
find_library、dir_config はこの変数に値 "-Ldir" を追加 します。