blog.tmp.tokyo

No Promises Await at Journey's End

ロンリーハッカソン

おはようございます。徹夜してしまいました。

先日,

tomohiko37-i.hatenablog.jp

に書いた通り,iPhone 上でプログラミングができる処理系が欲しくて,いいのが見つからないのでプログラマらしく自分で作ってしまえ,ということでいろいろやり始めていたらいつの間にか空が明るくなってきたのでした。

参考にしたのは,

ramemiso.hateblo.jp

だったのですが,mrubyOS X Yosemite 上の Xcode 6.4 が入っている環境でビルドするとエラーが出てしまいました。

Undefined symbols for architecture x86_64:
  "_GENERATED_TMP_mrb_mruby_eval_gem_final", referenced from:
      _mrb_final_mrbgems in libmruby.a(gem_init.o)
  "_GENERATED_TMP_mrb_mruby_eval_gem_init", referenced from:
      _mrb_init_mrbgems in libmruby.a(gem_init.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Undefined symbols for architecture x86_64:
  "_GENERATED_TMP_mrb_mruby_eval_gem_final", referenced from:
      _mrb_final_mrbgems in libmruby.a(gem_init.o)
  "_GENERATED_TMP_mrb_mruby_eval_gem_init", referenced from:
      _mrb_init_mrbgems in libmruby.a(gem_init.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
rake aborted!
Command Failed: 

・・・()・・・

rakefile:67:in `block (4 levels) in <top (required)>'
make: *** [all] Error 1

よく iOS 系の開発をしていると出てくることはあるのですが,コンパイルはできているけどリンクに失敗している様子。最初にこの事象に出会ったのは会社の mac で試してみたとき。自宅でも同じかと思ってやってみたのですが,同じでした。

tomohiko37-i.hatenablog.jp

この記事を書き終えたのが 2 時近かったように思うので,それから調べ始めて 4 時過ぎまでいろいろ設定をいじったりしながら何度もやってみましたが結果は変わらず。そんななかで,

qiita.com

安心・安定の Qiita の記事を見つけたのでこれを読んでいたら,どうやら同じようなことを考えている人が世の中にはいるようでした。gitHub にソースを公開しているようでしたので,ありがたく頂戴してくることにしました。

github.com

ここの README.md に書かれた方法で MRuby.framework が作れました。素晴らしい。これができてしまえば,あとは Xcode で適当なプロジェクトを作って,適当な場所でとりあえず実行してみれば OK です。

とりあえず Single View Application の形式で新しいプロジェクトを作り,ViewController.mviewDidLoad メソッドに書いてみました。

#import "ViewController.h"

#include "mruby/mruby.h"
#include "mruby/mruby/proc.h"
#include "mruby/mruby/dump.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    const char* rubyCode = "puts 'Hello, world.'";
    
    mrb_state* mrb = mrb_open();
    mrb_load_string(mrb, rubyCode);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

viewDidLoad に書いた,

    const char* rubyCode = "puts 'Hello, world.'";
    
    mrb_state* mrb = mrb_open();
    mrb_load_string(mrb, rubyCode);

のあたりは先ほどのサイトに書かれていたものをそのまま記載。要するに puts 'Hello, world.' という Ruby のコードを Objective-C 内で*1実行してしまえ,というコードになっています。

これを実行すると Xcode のコンソールに Hello, world が表示されます。なんとかこの文字列を捕まえてラベルなりで iPhone の画面に表示してやれば,念願の実行環境のベースが作れそうです。

さて,現在 6:00 です。眠くなりましたので少し寝ます。

*1:もうほとんど C 言語みたいだけど。