ARMマイコンに軽量Rubyを(その2)

ちょっと寄り道

暫くmrubyの総本山GitHubを訪れていなかったのですが、おや! "mirb"と言うインタラクティブRuby Shellが追加されてますね。Cygwin下では tools/mirb/mrib.exeを実行すると、入力プロンプトが表示され、Rubyプログラムをインタラクティブに実行できるようです。

$ ./tools/mirb/mirb.exe
mirb - Embeddable Interactive Ruby Shell

This is a very early version, please test and report errors.
Thanks :)

> print "Hello"
Hello => nil

その他に変わったところは、srcディレクトリにmath.c,time.cが追加された、testスイートのディレクトリが用意された、そしてMakefileが整理されたといったところでしょうか。

最初の一歩はビルドスクリプトから

さて、ARMマイコンへのポーティングは遅々として進んでいませんが、まずはMakefileを調べてビルドのファイル依存関係を整理してみました。ビルドツールにmakeを選ぶと、大概Makefileの中身がマクロだらけになるので、私的には好きになれないんですよね。

lib/libmruby.a:
    array.c    ascii.c   cdump.c    class.c     codegen.c
    compar.c   crc.c     dump.c     encoding.c  enum.c
    error.c    etc.c     gc.c       hash.c      init.c
    init_ext.c kernel.c  load.c     math.c      numeric.c
    object.c   pool.c    print.c    proc.c      range.c
    re.c       regcomp.c regenc.c   regerror.c  regexec.c
    regparse.c sprintf.c st.c       state.c     string.c
    struct.c   symbol.c  time.c     transcode.c unicode.c
    us_ascii.c utf_8.c   variable.c version.c   vm.c
    init_mrblib.c
    parse.y
;
tools/mrbc/mrbc.exe:
    mrbc.c
    lib/libmruby.a
;
tools/mruby/mruby.exe:
    mruby.c init_mrblib.c
    array.rb  compar.rb  enum.rb  error.rb hash.rb
    kernel.rb numeric.rb print.rb range.rb string.rb
    struct.rb
    lib/libmruby.a
;
tools/mirb/mirb.exe:
    mirb.c init_mrblib.c
    array.rb  compar.rb  enum.rb  error.rb hash.rb
    kernel.rb numeric.rb print.rb range.rb string.rb
    struct.rb
    lib/libmruby.a
;

この依存関係を、私のお気に入りのビルドツールFTJam*1で書き換えると次のようになります。ねっ、スッキリするでしょ‥‥そーでもないか :-p

mruby/Jamfile

SubDir PROJ ;
#
# アプリケーション依存のコマンド・オプション指定
#
if $(OS) = CYGWIN
{
	PRE       = CY_ ;
	CCFLAGS  += -Wall -Werror-implicit-function-declaration ;
	OPTIM     = -g -O3 ;
	NOARSCAN  = true ;

         CAT ?= cat ;
}
#
# カスタム・ルール
#    *.rb => *.c
rule Mrbc
{
    local _t = [ FGristSourceFiles $(<) ] ;
    local _r = [ FAppendSuffix mrbc : $(SUFEXE) ] ;
    Depends $(_t) : $(_r) $(>) ;
    Mrbc1 $(_t) : $(_r) $(>) ;
    Clean clean : $(_t) ;
}

rule Mrbc1
{
    MakeLocate $(<) : $(LOCATE_SOURCE) ;
    SEARCH on $(>) = $(SEARCH_SOURCE) ;
}

actions Mrbc1
{
    $(CAT) $(>[2-]) > mrblib_tmp.rb
    $(>[1]) -Bmrblib_irep -o$(<) mrblib_tmp.rb
    $(RM) mrblib_tmp.rb
}
#
# ビルドスクリプト
#
HDRS = include src ;

MRBDIR = mrblib ;
BINDIR = bin ;
LIB    = lib/libmruby ;

SubInclude PROJ src ;
SubInclude PROJ mrblib ;
SubInclude PROJ tools mrbc ;
SubInclude PROJ tools mruby ;
SubInclude PROJ tools mirb ;

src/Jamfile

SubDir PROJ src ;

Library $(LIB) : 
    array.c    ascii.c   cdump.c    class.c     codegen.c
    compar.c   crc.c     dump.c     encoding.c  enum.c
    error.c    etc.c     gc.c       hash.c      init.c
    init_ext.c kernel.c  load.c     math.c      numeric.c
    object.c   pool.c    print.c    proc.c      range.c
    re.c       regcomp.c regenc.c   regerror.c  regexec.c
    regparse.c sprintf.c st.c       state.c     string.c
    struct.c   symbol.c  time.c     transcode.c unicode.c
    us_ascii.c utf_8.c   variable.c version.c   vm.c
    parse.y
;

mrblib/Jamfile

SubDir PROJ mrblib ;

Library $(LIB) :
    init_mrblib.c
;

tools/mrbc/Jamfile

SubDir PROJ tools mrbc ;

Main mrbc :
	mrbc.c
;
LinkLibraries mrbc : $(LIB) ;
InstallBin $(BINDIR) : mrbc ;

tools/mruby/Jamfile

SubDir PROJ tools mruby ;

SEARCH_SOURCE += $(MRBDIR) ;

Mrbc mrblib_irep.c :
	array.rb
	compar.rb
	enum.rb
	error.rb
	hash.rb
	kernel.rb
	numeric.rb
	print.rb
	range.rb
	string.rb
	struct.rb
;
Main mruby :
	mruby.c
	mrblib_irep.c
;
LinkLibraries mruby : $(LIB) ;
InstallBin $(BINDIR) : mruby ;

tools/mirb/Jamfile

SubDir PROJ tools mirb ;

SEARCH_SOURCE += $(MRBDIR) ;

Mrbc mrblib_irep.c :
	array.rb
	compar.rb
	enum.rb
	error.rb
	hash.rb
	kernel.rb
	numeric.rb
	print.rb
	range.rb
	string.rb
	struct.rb
;
Main mirb :
	mirb.c
	mrblib_irep.c
;
LinkLibraries mirb : $(LIB) ;
InstallBin $(BINDIR) : mirb ;

*1:C++の有名なライブラリBoostのビルドではJamをカスタマイズしたものが使われていたかと...