mruby組み込み活用テクニック(1) ―― mrubyのビルド・ツールRakeを知る
組み込み分野向けのRuby処理系(実装)であるmruby(eMbeddable Ruby)は,オープン・ソースなので,自前でビルドする必要がある.当初のmrubyはビルドにGNU makeを用いていたが,2012年の秋ごろからはRakeというビルド・ツールを用いるようになり,組み込みソフトウェア開発に必要なクロス・コンパイル環境も充実してきた.本連載では,機器に組み込むことを目的とした際に必要となる,mruby のビルド環境について解説する.(筆者)
●mrubyのビルド・ツールの変遷
mrubyは,2012年4月20日に公開された若いソフトウェアです.しかし,オープン・ソース開発の気流に乗り,めまぐるしく進化しました.ビルドするためのツールも,当初はGNU makeでしたし,一時期はCMakeの採用が検討されたこともありました.そして,2012年の秋ごろからはRakeが採用され,現在に至っています.
ここで,mrubyのソース・ツリーを見たり,実際にビルドを試してみた方は,首をかしげておられるかもしれません.本稿執筆時点でも,GitHubに存在するmrubyの本家リポジトリ(https://github.com/mruby/mruby/)には,依然としてMakefileが含まれています.しかし,その中身を見ると,rakeコマンドのサブセットであるminirakeコマンドを呼び出すだけのものとなっています(リスト1.minirakeについては,稿末のコラム「minirakeコマンドの存在理由」を参照のこと).
# We provide a minimalistic version called minirake inside of our
# codebase.
RAKE = ruby ./minirake
.PHONY : all
all :
$(RAKE)
.PHONY : test
test : all
$(RAKE) test
.PHONY : clean
clean :
$(RAKE) clean
●ビルド・ツールRakeは言語内DSLである
Rakeは,Rubyの世界ではよく使われているビルド・ツールです.C言語の世界の MakeやCMake,Java言語の世界のAntやMavenなどと同様の機能を提供しています.
Rakeは,Ruby言語を核とする言語内DSL(Internal Domain Specific Language)として実装されています.言語内DSLであるということが,mrubyにおいて,MakeやCMake,Ant,MavenなどではなくRakeを用いる大きな動機となっています.
ここで,DSL(Domain Specific Language)と言語内DSLについて説明しましょう.DSLとは,ドメイン(問題領域)に特化したプログラミング言語の総称です.DSLに分類されている言語は,あえて汎用性を捨てて,特定の作業を行いやすいように設計されています.例えば,makeコマンドが用いるMakefileは,依存関係を見ながらビルドを行うための独自仕様のDSLです.Antのbuild.xmlやMavenのpom.xmlも,XMLで書かれたDSLと言えます.このほか,アプリケーションのカスタマイズを行うマクロ言語などもDSLと見なすことができます.
Makefileの記述はmakeが用いるDSLに従った記述であり,makeコマンドがビルドの対象とする言語(例えばC言語)とは異なります.このようなDSLを,外部DSL(External DSL)と呼びます.一方,Rakeは,Ruby言語のソース・コードの中に特定の記述法を持ち込むことで,DSLを実現しています.つまり,makeにとってのMakefileに相当するRakeのファイルRakefileは,実際にはRuby言語で書かれたスクリプトです.このようなDSLを,言語内DSLと呼びます.
ただし,Rakefileの記述は自由奔放なRubyスクリプトというわけではありません.ビルド・ツールに必須である,ソース・コードとオブジェクト・ファイルの依存関係を記述しやすいような枠組みが用意されています.そして,Rakefileを実行するrakeコマンドは,Ruby言語処理系を内部で呼び出してスクリプトの解釈を行わせています.
●言語内DSLのメリット,デメリット
Rakefileが,Ruby言語を用いた言語内DSLのスクリプトであるということは,メリットとデメリットをもたらします.このメリット/デメリットはRakeだからというものではなく,言語内DSLが持つ宿命のようなものです.
メリットは,拡張性が得られることです.Makefileには,GNUmakefikeのように,大幅に記述能力が向上している亜種もあります.しかしそれでも,結局のところはDSLで,汎用プログラミング言語の記述能力にはかないません.一方,RakefileはRuby言語のスクリプトです.必要であれば,Rakeが想定していなかった機能もRuby言語を用いて記述できます.本稿が解説しようとしているmrubyのビルドは,この拡張性というメリットをうまく利用して実現されています.
デメリットは,Rakefileの内容がDSLの枠を超えてしまい,複雑になりがちなことです.読者の方がRuby言語に詳しくないとしたら残念なお知らせになりますが,その典型例が,mrubyのビルド・スクリプトです.mrubyのビルド・スクリプトは,Ruby言語を知らなくても書けるように洗練されています.その代償として,ビルド環境の全ぼうを知ることが難しくなっています.少しでもカスタマイズしようとすると,途端にRuby言語に対する高度な知識が求められます.
従来からRuby言語に慣れ親しんでいる技術者にとっては,このデメリットは大したことではありません.しかし,組み込みソフトウェア技術者の多くはRuby言語ではなく,C言語に慣れ親しんでいることでしょう.そのような技術者にとっては,Rakeのデメリットは,大きな障壁となります.
本連載では,読者がRuby言語に詳しくないという前提で,mrubyのビルド環境の概要を解説していきます.ただし,全くRuby言語を知らなくても読み進められるかというと,それは少し難しいかもしれません.基本的な文法については,「組み込みC言語プログラマのためのmruby入門(中編)」を参照してください.その他のRuby言語の知識は,必要に応じて紹介していきます.