Cライブラリ拡張を持つRubyGemで且つ、そのCライブラリ拡張をトップレベルじゃなくて特定の名前空間module配下にインストールされるように作る方法。早い話が、例えば
Foo::Barクラスを作る。但し、Barクラスの実装はCで書く。
Foo::Barを直接読み込む場合はrequire 'foo/bar'となるように。
という条件です。
まずはソースツリーを作るところから。手で作るのは面倒なので、
newgemを使うのが便利。
newgem foo
とすると、fooディレクトリ配下に雛形となるファイルを自動生成してくれるので、これをベースにします。このあたりはsecondlifeさん@はてなの
エントリーにも詳しいので、良かったらそちらも併せてどうぞ。以下、
newgemでツリーを作ったのを前提の話になります。
次に、Cライブラリ拡張のソースを置く場所を作る。
extディレクトリに入れるのが慣例らしいので、それに合わせます。名前空間
fooを使いたいので、もう一段ディレクトリを掘る。Cのソースファイルbar.cはその下に。
ext以下のツリーはこんな感じに。
ext
ext/foo
ext/foo/bar.c
Cソースの書き方については、長くなりそうなので割愛。
bar.cと同じ階層に
extconf.rbを作る。
ext
ext/foo
ext/foo/bar.c
ext/foo/extconf.rb
拡張子を見ての通り、中身は普通のRubyスクリプトで、中身はこんな感じ。
require 'mkmf'
(中略)
create_makefile 'foo/bar'
extconf.rbと
bar.cが同じディレクトリに置かれているにもかかわらず、敢えて
create_makefileの引数に
'foo/bar'と指定するところがポイント。ここを
create_makefile('bar')だと、最終的なインストール先が
lib/bar.soになってしまうので。
トップディレクトリに戻って、
Rakefileを書き替える。
newgemを使った場合は既にある
Rakefileの一番下、
# Generate all the Rake tasks
# Run 'rake -T' to see list of generated tasks (from gem root directory)
hoe = Hoe.new(GEM_NAME, VERS) do |p|
p.author = AUTHOR
(中略)
end
とあるブロックの中に
p.spec_extras = {
:extensions => ['ext/foo/extconf.rb'],
}
と書いておけばOK。
最後に、
Manifest.txtを書き替える。このファイルはパッケージに含まれるべきファイルを列挙してあるだけなので、
ext配下のファイルを追加してやれば良い。
ext/foo/extconf.rb
ext/foo/bar.c
ちなみに、Makefileは
gem installするときに自動生成されるので、Gemパッケージには含めないようにご注意を。
rake package(またはrake repackage)でGemを作る。お疲れさまでした。
ちなみに、RubyGems-0.9.1から、
require_gemと書くと警告が出るようになってます。代わりに
gemメソッドを使えとのこと。
require 'rubygems'
gem 'activerecord'
例えばこんな感じに書いておけばOK。
続きを読む
posted by cesare at 00:06
|
Comment(0)
|
TrackBack(0)
|
技術関連