moclを購入したのでiOS用のサンプルを動かす手順をまとめてみた(Common Lisp)
moclについて
moclとは、iOSとAndroid(現在)を開発するためのCommon Lispの実装です。moclを利用することで、iOS, Androidのアプリの一部をCommon Lispで開発できるようになります。つい最近のECLM 2013で発表が行われました。Common LispはGUIが一昔前な印象を持っていたのでどんな感じなのかと思ったら、画面の表示周りはXcodeやAndroidだとeclipse (今だとAndroid Studio?) に任せてしまうようです。で、どうやらllvm/clangでコンパイルして、それをアプリで使ってビルドするらしい。ちなみに、Androidだとndkに渡します。REPLに関しては、#-mocl (declaim (declaration call-in 関数名)) というようにmocl専用のコードはそれ以外の環境で読み込まれないようにして、Common Lispのプログラミング箇所は普段使ってるCommon Lispの環境で試してね、というスタンスらしい。moclと似たようなものにGambit Schemeというものがあるみたいですが、Scheme界隈は全く知らないため詳細不明。moclって、MObile Common Lispっていうことだろうか。moclについての情報は、公開されたばかりで現在全くありませんが、今後、本家のWukixがヘルプを作ってくれたり、色々な情報がウェブで賑わったらいいなと思うので1つ増やしてみました。
唐突にサンプルプログラムを動かすまで
ECLIM 2013のPDFとかmoclを買ったときについてきたMANUAL.pdfとかを見たり、twitterでエラー書いてたらWukixの人がそれとなく教えてくれたりしたので、iOSでサンプルプログラムを動かすまでの手順を書きます。
Xcode: version 4.6.3, iOS: 6.1, mocl: 13.06
まず、moclを購入します。個人で$199。今が買いかはちょっと不明。個人的には、値段よりmoclのソースコードが見えない&ヘルプがない(分からない)ため、今後、そこらへんが充実してほしいという期待を込めてご祝儀的な感じで買っちゃいました。
ターミナルのターン
前提条件としてダウンロードして展開したmoclフォルダはホームディレクトリーにあります (*username*はユーザー名)。とりあえずデフォルトでやってみることに。
$ pwd
/Users/*username*
$ sudo install mocl/bin/mocl /usr/local/bin/mocl
$ mocl
Could not find .moclconfig.lisp in your home directory. Create now? (y or n) y
mocl root directory location? [/Users/*username*/mocl/]
ASDF registry location? mocl will search here for .ASD links [/Users/*username*/mocl/systems/]
/Users/*username*/.moclconfig.lisp created.
mocl 13.06 Copyright (C) 2013 Wukix, Inc. (http://wukix.com)
usage: mocl [options] <file>
or mocl repl [options]
target options:
--android <dir> Set target OS to Android. <dir> is an ADT (Android
Developer Tools) project directory for output
--ios <dir> Set target OS to iOS. <dir> is an Xcode project
directory for output
general options:
--help Print this help message
-O0 Disable optimization
-v, --verbose Verbose mode
--version Print mocl version
これで、$ mocl で真っ先に呼ばれる .moclconfig.lisp が作られます。
次に、サンプルをgithubから取得します。moclの中には mocl/example/contacts/app.lisp があったのですが、これだけではどうしようもないのでgithubからとってきます。とういか、これで何をやるのだろう…
$ pwd
/Users/*username*
$ git clone https://github.com/Wukix/mocl-example-lisp-contacts-ios.git
しかしながら、このサンプルもこれだけでは動きません。
これはエラーが出るのでやる意味ないです
$ mocl --ios /Users/*username*/mocl-example-lisp-contacts-ios/LispContacts/ /Users/*username*/mocl-example-lisp-contacts-ios/app.lisp
(app.lisp:2) Error in form (REQUIRE :VECTOMETRY)
-> Don't know how to REQUIRE :VECTOMETRY
というわけで、これからasdfのターン。asdfに詳しくないので作法としていいのかどうかは不明。
$ pwd
/Users/*username*
$ cd mocl/systems
$ git clone https://github.com/xach/vectometry.git
$ ln -s vectometry/vectometry.asd vectometry.asd
$ git clone https://github.com/xach/geometry.git
$ ln -s geometry/geometry.asd geometry.asd
$ git clone https://github.com/Wukix/vecto.git
$ ln -s vecto/vecto.asd vecto.asd
$ git clone https://github.com/xach/zpb-ttf.git
$ ln -s zpb-ttf/zpb-ttf.asd zpb-ttf.asd
$ git clone https://github.com/xach/zpng.git
$ ln -s zpng/zpng.asd zpng.asd
$ git clone https://github.com/xach/salza2.git
$ ln -s salza2/salza2.asd salza2.asd
$ git clone https://github.com/fjolliton/cl-vectors.git
$ ln -s cl-vectors/cl-vectors.asd cl-vectors.asd
$ ln -s cl-vectors/cl-paths.asd cl-paths.asd
$ ln -s cl-vectors/cl-aa.asd cl-aa.asd
ここまでやると、Warningsが20個くらいでるけど通りました。
$ mocl --ios /Users/*username*/mocl-example-lisp-contacts-ios/LispContacts/ /Users/*username*/mocl-example-lisp-contacts-ios/app.lisp
ここでは完全にmocl用でgit clone, ln -sの嵐ですが、asdfを普段のCommon Lispの環境で使っているなら、.moclconfig.lispのasdf-registryに追加してもいいんじゃないですかね(適当)
Xcodeのターン
次に、mocl-example-lisp-contacts-ios/LispContacts/LispContacts.xcodeproj を開きます。
すると、早速、エラーでお出迎え。
#include "mocl.h"が見つからないというわけです。
プロジェクト内に専用のmoclフォルダが作成されている(mocl-example-lisp-contacts-ios/LispContacts/LispContacts/mocl)のですが、Xcodeのプロジェクトには認識されていないので、位置的にRunの下にあるタブ(Show the project navigator)をクリックして、File > Add Files to "LispContacts"からファイルを追加します。
moclフォルダを選択します。
補足: moclのフォルダが表示される他に、libz.dylibが必要です。このサンプルにはありますが、自分でハローワールド的なものを作る場合は追加する必要があるようです。左のプロジェクト、targetsのアプリ名(LispContacts)、Build Phasesを順にクリック、Link Binary with Libraliesの[+]からlibz.dylibを選択して追加します。
iOS Simulatorのターン
待ちに待ったRunのお時間です。
こうなります。サンプルでは文字も画像にしているのか少し気になります。ちなみに、RetinaのiPhoneシミュレーターだと全然気になりませんでした。
Email欄が、選択候補で隠れちゃうなー(実機では未確認)
日本語は、
だめでした…(ここらへんはutf-8とかで何とかなる?) <--- 設定変えたら表示された
■2013.06.28 am2:22 追記
日本語を表示できるようにするために
というわけで、Wukixの人から再度twitterでお告げが。
@jiroukaja The example font 'DejaVuSans.ttf' cannot display the Japanese language. It works with 'Arial Unicode.ttf' pic.twitter.com/nPaCnFwejT
— Wukix (@Wukix) 2013, 6月 27
使用しているフォントのDejaVuSans.tffをArial Unicode.tffに変更するだけでいいらしい。テストなので /Library/fontsからArial Unicode.ttfをコピーしてlibz.dylibを追加した要領でファイルを追加します。
WuViewController.m 44行目
- NSString *fontpath = [appFolderPath stringByAppendingString:@"/DejaVuSans.ttf"];
+ NSString *fontpath = [appFolderPath stringByAppendingString:@"/Arial Unicode.ttf"];
あと、念のため、Product > Clean とシミュレーターのアプリも削除して入れ直しました。
やったね!
まとめ
moclのサンプルをiOSで動かす手順なため、#include "mocl.h"とか、AppDelegate.mファイルの - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions内にcl_init();が必要とか、Objective-C内で呼び出すためには、(declaim (call-in 関数名))のように宣言する必要があるとかは飛ばしました。細かい箇所では何かしらトラップがありそうですが、Common Lispが使えるというだけでワクワクしますね。