今日からmrubyをはじめる人へ

ApacheCon NA 2013に参加し、早めにポートランド国際空港に到着しました。時間があるので、今日(2013年3月2日)からmrubyを始める人へ簡単なチュートリアルをしようと思います。

mrubyというプロジェクト

mrubyとは、組み込み機器やアプリ組み込みに最適化された軽量スクリプト言語です。記述方法は既存のRubyのように書くことができます。C言語で書かれたホストアプリにmrubyを組み込むことで、ホストアプリをRubyの記述でコントロールすることができます。例えばmod_mrubyは、RubyでApache APIをつつけるようにmrubyをApacheに組み込むためのモジュールで、ApacheモジュールをRubyで記述することができます。

mrubyはgithub上で実装、議論等が行われています。毎日盛んにissueやpull-requestでパッチに対する議論や、今後どうしていくかがやり取りされているので、まずはissuepull-requestを眺めてみると良いでしょう。数日で大量の議論が起票、解決されています。少し目を離していると、すぐおいていかれる程のスピード感があります。

mrubyのダウンロード

githubからソースをダウンロードします。大抵の場合、以下のようにすればよいでしょう。

[program lang=’bash’ escaped=’true’]

$ git clone git://github.com/mruby/mruby.git

[/program]

mrubyの拡張ライブラリ管理ツールmgemの導入

現在、mrubyの拡張ライブラリの組み込みはmgemとい呼ばれるコマンドで行われています。mgemによって、自分の組み込みたいmrbgemを自動的にダウンロードしてビルドするmrubyビルド用の設定ファイルbuild_config.rbを吐き出してくれます。

mgemコマンド自体はgemコマンドで導入することができます。

[program lang=’bash’ escaped=’true’]

$ gem install mgem

[/program]

導入後は、まずはmgemコマンドで有効なmrbgemのリストを最新版に更新します。

[program lang=’bash’ escaped=’true’]

$ mgem update

[/program]

現在利用可能なmrbgemのリストを以下のコマンドで表示してみましょう。現時点では56個のmrbgemが存在します。それぞれのmrbgemも全てgithubに存在するので、それらの内容を詳しく見たい場合はmrubyのWikiのRelated Projectを見ると良いでしょう。大体mから始まる人によって作られています。

[program lang=’bash’ escaped=’true’]

$ mgem size
Total # of GEMs: 56

[/program]

リストは以下のようになります。

[program lang=’text’ escaped=’true’]

$ mgem list
List of all GEMs:
  mruby-allegro                 mruby binding to Allegro 5
  mruby-allocate                Class allocate
  mruby-arduino                 Arduino binding
  mruby-audite                  Portable MP3 Player based on libmp123 and portaudio
  mruby-aws-s3                  Client library for Amazon's (AWS) S3 REST API
  mruby-base64                  Base64 Encoder/Decoder
  mruby-capability              Linux Capability Binding
  mruby-cfunc                   Interface to C functions based on libffi.
  mruby-cgroup                  cgroup binding
  mruby-cocoa                   Interface to Cocoa based on Objective-C Runtime and mruby-cfunc.
  mruby-core-ext                MRuby Core Extensions
  mruby-curl                    CURL HTTP Client
  mruby-digest                  MD5, RMD160, SHA1, SHA256, SHA384, SHA512 and HMAC Digests.
  mruby-dir                     Dir Class
  mruby-discount                html generater from markdown using discount
  mruby-dll                     DLL Windows Support
  mruby-eject                   Eject CD-ROM
  mruby-env                     ENV class implementation
  mruby-fltk3                   FLTK3 GUI binding.
  mruby-gles                    OpenGL ES 2.0 binding
  mruby-gntp                    Growl Notification Transfer Protocol
  mruby-growthforecast          GrowthForecast client class
  mruby-hs-regexp               Light-weight Henry Spencer's Regular Expression
  mruby-http                    HTTP Parser
  mruby-httprequest             create http request class
  mruby-iconv                   libiconv interface
  mruby-jpeg                    JPeg library
  mruby-json                    JavaScript Object Notation
  mruby-libqrng                 libQRNG interface
  mruby-md5                     MD5 Hash Alghorithm
  mruby-mecab                   Japanese morphological analyzer
  mruby-msagent                 Microsoft Agent
  mruby-mtest                   Minimum Test Framework
  mruby-mysql                   MySQL Database
  mruby-oauth                   OAuth class
  mruby-onig-regexp             Oniguruma Regular Expression
  mruby-pack                    Array#pack implementation
  mruby-pcre-regexp             PCRE - Perl Compatible Regular Expressions
  mruby-process                 Process interface (waitpid, pid, kill, fork, ppid)
  mruby-random                  random class with Mersenne Twister
  mruby-redis                   redis client using hiredis
  mruby-require                 require implementation
  mruby-sha1                    SHA1 Hash Alghorithm
  mruby-simple-random           Kernel#rand and Kernel#srand
  mruby-simplehttp              Simple http client
  mruby-sinatic                 Sinatra like Web Framework
  mruby-sleep                   Sleep Module
  mruby-sqlite3                 SQLite3 Database
  mruby-syslog                  Syslog binding
  mruby-thread                  Thread Library
  mruby-updategems              Rake task to update GEMs
  mruby-uv                      libuv interface
  mruby-v8                      V8 JavaScript Engine
  mruby-winapp                  Create non-console application for windows
  mruby-WiringPi                Binding for Wiring function of the Raspberry Pi
  mruby-zabbix                  zabbix 2.0 API client class

[/program]

mrbgemを組み込んでmrubyをビルド

さて、それでは実際にいくつかmrbgemを組み込んでみましょう。例えば、mruby-randomとmruby-sleepを組み込みたいとします。その場合は、以下のようなコマンドを実行します。

[program lang=’bash’ escaped=’true’]

$ mgem add mruby-random
'mruby-random' activated!

List of active GEMs:
  [X] mruby-random        random class with Mersenne Twister

[/program]

次にmruby-sleepを組み込みます。

[program lang=’bash’ escaped=’true’]

$ mgem add mruby-sleep
'mruby-sleep' activated!

List of active GEMs:
  [X] mruby-random        random class with Mersenne Twister
  [X] mruby-sleep         Sleep Module

[/program]

すると、このように2つのmrbgemがactive GEMsに登録されました。

mrubyでは、gemを静的にmrubyに組み込むようにしているので、そのためのビルド設定ファイルであるbuild_configをmgemで生成します。

また、最新のmrubyではコアからMathモジュール、Timeクラス、StructクラスがPluggableになったので、これらの機能が必要無い人は簡単に取り外せるようになっています。しかし、mruby的にはスタンダードモジュールなので、自身で外さない限りはデフォルトで組み込まれることになります。

では、実際にMathモジュールとTimeクラスは組み込まずに、Structクラスだけ組み込んで、かつ上記のmruby-randomとmruby-sleepを組み込んでみましょう。

この点に関しても、mgemで簡単にできるようにしています。まずは、mgemで以下の様に設定コマンドを実行します。

[program lang=’ruby’ escaped=’true’]

$ mgem config

Please choose your toolchain:
  'gcc' for GNU Compiler Collection
  'clang' for LLVM C Compiler
  'vs' for Visual Studio 2012 on Windows

Toolchain: gcc

Compile mrbc? (Y/n): Y
Compile mruby? (Y/n): Y
Compile mirb? (Y/n): Y

Include 'Struct' GEM? (Y/n): Y
Include 'Time' GEM? (Y/n): n
Include 'Math' GEM? (Y/n): n

############################
# Start of your build_config

MRuby::Build.new do ¦conf¦
  toolchain :gcc

  conf.bins = %w(mrbc mruby mirb)

  # mruby's default GEMs
  conf.gem 'mrbgems/mruby-struct'

  # user-defined GEMs
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-random.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-sleep.git'
end

# End of your build_config
############################

[/program]

このように、ビルドのためのTool chainやスタンダードモジュールの設定に関しては、インタラクティブに設定できるようになっています。mgem configコマンドの質問に従って、自分に必要な設定を入力していくと、それにあったbuild_config.rbを設定してくれます。上記の場合は、Toolchainはgcc、スタンダードモジュールとしてStruct意外は「n」を入力しています。また、以前にactiveにしていたmrbgemは自動的にbuild_configに反映されるようになっています。

そして、このbuild_configの出力をコピーして、mrubyレポジトリ以下にあるbuild_config.rbにコピペすると良いでしょう。

また、スタンダードモジュールやToolchainに変更がなく、mruby-*だけ追加したい場合は、mgem addコマンドの後、以下のようなコマンドで直接build_config.rbを上書きすると楽です。

[program lang=’bash’ escaped=’true’]

mgem config default > mruby/build_config.rb

[/program]

こうすることで、以下のようなbuild_config.rbが生成されます。

[program lang=’ruby’ escaped=’true’]

cat mruby/build_config.rb 

############################
# Start of your build_config

MRuby::Build.new do ¦conf¦
  toolchain :gcc

  conf.bins = %w(mrbc mruby mirb)

  # mruby's default GEMs
  conf.gem 'mrbgems/mruby-time'
  conf.gem 'mrbgems/mruby-struct'
  conf.gem 'mrbgems/mruby-math'

  # user-defined GEMs
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-random.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-sleep.git'
end

# End of your build_config
############################

[/program]

そして、最後にmrubyをビルドしましょう。build_config.rbが適切に記述されている状態で、以下のようにビルドします。

[program lang=’bash’ escaped=’true’]

rake

[/program]

このように、mrubyではビルドにCRubyを使うようになっています。組み込みのための言語なのにRubyがないとビルドできないの?と思う人もいるかもしれませんが、基本は組み込み対象の別のホストマシンでビルドを行なって、バイナリを対象機器のRAM等にコピーする事を想定しているので、特にRubyを使ってビルドすることもホストマシン上においてはさほど問題ないと考えています。

ビルドが成功すると、以下のような出力とともに、全てのバイナリが生成されます。

[program lang=’text’ escaped=’true’]

Build summary:

================================================
      Config Name: host
 Output Directory: build/host
         Binaries: mrbc, mruby, mirb
    Included Gems:
             mruby-time
             mruby-struct
             mruby-math
             mruby-random
             mruby-sleep
================================================

[/program]

自分の組み込みたいmrbgemが適切に組み込まれた事が分かりますね。では、実際にmrubyが動作するか、Hello Worldしてみましょう。

[program lang=’ruby’ escaped=’true’]

./bin/mruby -e 'puts "hello mruby world!"'
hello mruby world!

[/program]

成功しました。

最後に

今回はmrubyを使うための最新のビルド方法を紹介しました。これで、まずはmrubyを試してみるということができるでしょう。

ここまできたら、次はCで記述されたホストアプリケーションにmrubyを組み込んで、Rubyでそのホストアプリケーションをコントロールしたりすると、より理解が深まるでしょう。これができるようになれば、mrubyがどんどん楽しくなることでしょう。例えば、既存のミドルウェアであるPostfixにmrubyを組み込んで、PostfixをRubyでコントロールすることもできるでしょう。

また、僕自身も自分の研究でmrubyを使っているのですが、mrubyの良い所は自分の扱いたいクラスやモジュールを限定して、使わない物はコアから抜き取って、小さなバイナリに最適化しやすいところです。これによって、簡単にホストアプリの設定をRubyのDSLで記述し、かつ、そのバイナリを最小限に抑える事が容易になります。また、mruby拡張が非常に書きやすい事も挙げられます。

こういう楽しみが沢山あるmrubyですので、時間があれば、次回は、mrubyによるアプリ組み込み方法の簡単なチュートリアルを行いたいと思っています。

 

「今日からmrubyをはじめる人へ」への1件のフィードバック

  1. ピンバック: Daily Digest for 2013/03/03

コメントは受け付けていません。