mrubyの機能拡張には、mrbgem(以下mgem)という所謂CRubyでのgemのような拡張モジュールを使います。mgemを開発していくと、もちろん以前作ったmgemの機能を再利用したい場合や、すでに存在する優れたmgemを使ってさらなる機能を実装したい場合が多くなるはずです。
昔は、mrubyのbuild_config.rbに粛々と依存するmgemを羅列していって、ビルドして依存関係に関する警告が出たらそのmgemを追加していくというかなり面倒な作りになっていました。
ですが、今は開発したmgemの所謂設定であるmrbgem.rakeファイルに依存関係を書いておくと、自動的にそれをmgem-listと呼ばれるmgemの登録リポジトリから検索してビルドしてくれるようになっており、以前と比べると非常に簡単になっています。
つまり言い換えると、mgem-listに登録していないmgemに関しては、依存関係にmgem名だけを書いていたとしても自動で解決してくれないのです。(一応登録していないmgemの自動解決の方法はあるが、mgemがどこにいるのかなど付加情報を幾つか書かないといけなくて設定内容も増えて面倒)
ということで、作ったmgemはできるだけmgem-listにPRを投げて登録しておくようにしましょう。
またmgemそのものの書き方については、以下のサイトを参考に作ってみてはどうでしょうか。
ここで簡単にまとめると、
- mrubyの設定ファイルが
build_config.rbでここにリンクしたいmgemを書く - mgemの設定ファイルが
mrbgem.rakeでここにmgemの依存を書く
ということになり、mrubyのbuild時にbuild_config.rb経由でmgemのmrbgem.rakeを解析し、依存を自動で解決し組み込むという流れになります。
依存関係の書き方
今回は依存関係の書き方についても整理しておきます。
例えば、HTTPクライアントであるmruby-simplehttpというmgemを書いた上で、さらにそれをwrapしてmruby-httprequestというmgemを作るとします。その場合、mruby-simplehttpが以下のように依存関係をmgemのmrbgem.rakeに書きます。
MRuby::Gem::Specification.new('mruby-simplehttp') do |spec| spec.license = 'MIT' spec.authors = 'MATSUMOTO Ryosuke' spec.version = '0.0.1' spec.add_dependency 'mruby-socket' spec.add_dependency 'mruby-sprintf' spec.add_dependency 'mruby-polarssl' end
さらに、それをwrapするmruby-httprequestは以下のような依存関係だったとします。
MRuby::Gem::Specification.new('mruby-httprequest') do |spec| spec.license = 'MIT' spec.authors = 'MATSUMOTO Ryosuke' spec.version = '0.0.1' spec.add_dependency 'mruby-simplehttp' spec.add_dependency 'mruby-http' end
その場合、以前は依存しているmgemを再帰的にチェックしてbuild_config.rbにない場合は警告を出すだけでしたが、今ではきちんと再帰的に依存するmgemをmgem-listから検索して自動でダウンロードしてくれます。
なので、上記の例では、最終的にHTTPクライアント機能をmrubyで使いたい場合、mruby-httprequestだけmrubyのbuild_config.rbに書いておけばちゃんと関連するすべてのmgemをダウンロードします。
build_config.rbは以下のようになります。
MRuby::Build.new do |conf| toolchain :gcc conf.gembox 'full-core' conf.gem :mgem => 'mruby-httprequest' end
これをmrubyリポジトリ内においてrakeするだけでビルドが完了します。
テストで利用するmgemの依存関係
mrubyのテストでは、明示的にテストで利用するmgemを書いていない場合は、基本的に最小コアの機能だけでテストをするようになっています。そのため、例えばテストの中でmruby-sleepを使いたい場合は、以下のようにmrbgem.rakeにテストの依存関係であるspec.add_test_dependencyを書いておきます。
MRuby::Gem::Specification.new('mruby-httprequest') do |spec| spec.license = 'MIT' spec.authors = 'MATSUMOTO Ryosuke' spec.version = '0.0.1' spec.add_dependency 'mruby-simplehttp' spec.add_dependency 'mruby-http' spec.add_test_dependency 'mruby-sleep' end
このように書いておくと、このmruby-httprequestのテストにmruby-sleepをリンクした状態でテストが走ります。
mgem-listへの登録の仕方
mruby/mgem-listというGitHubのリポジトリでmgemを管理していますので、そこにmgemの設定を書いたファイルをPRするだけでよいです。設定内容は以下のようなyamlになっています。
name: mruby-httprequest description: create http request class author: MATSUMOTO Ryosuke website: https://github.com/matsumoto-r/mruby-httprequest protocol: git repository: https://github.com/matsumoto-r/mruby-httprequest.git dependencies: - mruby-simplehttp - mruby-http
このようなファイルをリポジトリにPRすると良いです。
まとめ
ということで、今回はmrubyのmgemの依存関係やmgem-listへ登録しておくことのメリットを紹介しました。登録していないと、依存するmgemがどこに存在するかといった情報をmrbgem.rakeに書かないと行けなかったりして面倒になるので、できるだけmgem-listに登録してspecにはmruby-sleepといったmgem名だけを書いておけばよい状態にしておくと、みんなが幸せになるでしょう。