wxErlang が動きませんよ?
(要約) Chromebook Flip (ARM cortex-A17 環境) 上の crouton Ubuntu 14.04 LTS で wxErlang を動かそうとしたら、最終的にソースコードからのビルドになった、という話。
* * *
今年の豊富ついでに早速 wxErlang でもやってみようと思いました。幸い Chromebook Flip に構築した Ubuntu 環境でも apt-get で erlang はすんなり入ったので、さくっと始められますよ。
というわけで、まずは試し。いちばん小さそうなサンプルをざざっとググって見つけた1章 「wxErlang」 - INAの日記 さんを参考にサンプルを書いて動かそうとしたところ、
-module(guitest). -compile(export_all). start() -> Wx = wx:new(), Frame = wxFrame:new(Wx, -1, "this is the title", [{size, {600, 800}}]), wxFrame:show(Frame), loop(Frame), wx:destroy(). loop(Frame) -> receive _ -> loop(Frame) end.
2> c(guitest). {ok,guitest} 3> guitest:start(). ** exception error: undefined function wx:new/0 in function guitest:start/0 (guitest.erl, line 5)
むっふぅ...。wx:new/0 がございませんか...。
Stack Overflow を見ると include 足りてねぇんじゃね、的な指摘があったので
6> code:lib_dir(wx). "/usr/lib/erlang/lib/wx-1.1.1"
で、パスを調べて
-include_lib("/usr/lib/erlang/lib/wx-1.1.1/include/wx.hrl").
を追加*1。
で、実行すると
14> guitest:start(). ** exception error: undefined function wx:new/0 in function guitest:start/0 (guitest.erl, line 6)
・・・むっふぅ、変わらにゅ。なにがおかしいのかしら。
Erlang のライブラリインポートの仕組みをイマイチ理解していないのだけれど、とりあえず解決すればいいや、的に、たとえば Getting Started with wxWidgets in Erlang を参考に、erlang-shell 側でincludeしてみるものの、
4> My_wx_dir = code:lib_dir(wx). "/usr/lib/erlang/lib/wx-1.1.1" 5> rr(My_wx_dir ++ "/include/wx.hrl"). [wx,wxAuiManager,wxAuiNotebook,wxCalendar,wxChildFocus, wxClipboardText,wxClose,wxColourPicker,wxCommand, wxContextMenu,wxDate,wxDisplayChanged,wxErase, wxFileDirPicker,wxFocus,wxFontPicker,wxGrid,wxHelp, wxHtmlLink,wxHtmlLinkInfo,wxIconize,wxIdle,wxJoystick,wxKey, wxList,wxMaximize,wxMenu,wxMouse,wxMouseCaptureChanged|...] 6> rr(My_wx_dir ++ "/src/wxe.hrl"). [wx_env,wx_mem,wx_ref]
しかし、やはりうまくいきません。
おかしいなー、
$ cd /usr/lib/erlang/lib/wx-1.1.1/src $ ll 合計 100 drwxr-xr-x 3 root root 4096 10月 5 00:46 ./ drwxr-xr-x 5 root root 4096 10月 5 00:46 ../ drwxr-xr-x 2 root root 16384 10月 5 00:46 gen/ -rw-r--r-- 1 root root 12091 8月 20 2014 wx.erl -rw-r--r-- 1 root root 21525 8月 20 2014 wx_object.erl -rw-r--r-- 1 root root 2180 8月 20 2014 wxe.hrl -rw-r--r-- 1 root root 8661 8月 20 2014 wxe_master.erl -rw-r--r-- 1 root root 14153 8月 20 2014 wxe_server.erl -rw-r--r-- 1 root root 6972 8月 20 2014 wxe_util.erl
をすると wx.erl といるし、その中にちゃんと
-module(wx). -export([parent_class/1, new/0, new/1, destroy/0, get_env/0,set_env/1, debug/1, batch/1,foreach/2,map/2,foldl/3,foldr/3, getObjectType/1, typeCast/2, null/0, is_null/1]). ・ ・ ・
とかあるのだけれどなぁ...と、調べつつ、ふと「あれ、これコンパイルされてるのかしら」とErlang クエックブック Beam ファイルのパスを取得する を参考に code:which/1 で探索すると
11> code:which(wx). non_existing
いないじゃーーーーん ...orz
なんかここらへんが原因っぽいなぁ。
自前ビルドする
これを後から何とかする自信が全然なかったので、やっぱり何もかも綺麗な環境からやり直したほうが良いでしょう、ということで、
$sudo aptitude purge erlang
して、http://erlang-users.jp/ の「GitHub レポジトリからビルドする」や
Erlang/OTP 18.1 をソースコードからインストールする | Qiitaを参考に自前ビルド。
現状のさいしんは 18.2.1 なので
$ git clone git://github.com/erlang/otp --bare erlang.otp.upstream $ git clone erlang.otp.upstream opt.18.2 $ cd opt.18.2/ $ git checkout -b 18.2.1 OTP-18.2.1Switched to a new branch '18.2.1'
とソースと作業ディレクトリを確保。
で、ビルドに必要なライブラリをインストール
$ sudo aptitude install build-essential libncurses5-dev libssl-dev systemtap-sdt-dev autoconf
あとは、こちらも*2。
$ sudo aptitude install libwxgtk3.0-dev libwxgtk3.0-0 libwxgtk3.0-0-dbg wx3.0-i18n libwxgtk-media3.0-dev libwxgtk-media3.0-0 libwxgtk-media3.0-0-dbg
で、wx関連も入れる(入れたつもり)。その後いつものconfigure
$ ./otp_build autoconf 2>&1 | tee ../erl_autoconf.log $ ./configure --disable-hipe --enable-dtrace --without-javac 2>&1 | tee ../erl_configure.log
で、メッセージを見てみると
・ ・ ・ ********************************************************************* ********************** APPLICATIONS DISABLED ********************** ********************************************************************* jinterface : Java compiler disabled by user odbc : ODBC library - link check failed ********************************************************************* ********************************************************************* ********************** APPLICATIONS INFORMATION ******************* ********************************************************************* wx : Can not link the wx driver, wx will NOT be useable ********************************************************************* ********************************************************************* ********************** DOCUMENTATION INFORMATION ****************** ********************************************************************* documentation : xsltproc is missing. fop is missing. xmllint is missing. The documentation can not be built. *********************************************************************
あうち。Java や ODBC は置いといて、問題は wx と documentation ね。特にwxはこれが使いたくって自前ビルドに走ったのですから。で、メッセージをみると、
configure: Checking for OpenGL headers in /usr/local checking GL/gl.h usability... no checking GL/gl.h presence... no checking for GL/gl.h... no configure: WARNING: No OpenGL headers found, wx will NOT be usable
と言っています。OpenGL が必要なんかー。というわけで、
$ sudo aptitude install freeglut3-dev libglew1.5-dev
も追加。したら、これで wx周りは解決しました。
あとはdocumentation の部分を解決するため
$ sudo aptitude install xsltproc fop libxml2-utils
も*3。なんか、やたらたくさん java 関連のパッケージが入ってストレージに乏しいChromebook ではヒヤヒヤ。MicroUSB上にchroot環境作っておけばよかったなぁ、とプチ後悔。
そして再び confiure して、
$ make 2>&1 | tee ../erl_make.log $ make install 2>&1 | tee ../erl_install.log
ちなみに make にかなーーーり時間がかかります。特に、wxWidgetsのビルドが長い(configureのときstatic library が見つからなかったので自前ビルドになる)です。
終わったら、早速 起動してみます。
$ erl Erlang/OTP 18 [erts-7.2.1] [source] [smp:4:4] [async-threads:10] [kernel-poll:false] Eshell V7.2.1 (abort with ^G) 1>
ちなみに、apt-get でいれた ときはこんな感じでした。
$ erl Erlang R16B03 (erts-5.10.4) [source] [smp:4:4] [async-threads:10] [kernel-poll:false] Eshell V5.10.4 (abort with ^G)
では、成果の程を見てみましょう。どきどき..
2> code:which(wx). "/usr/local/lib/erlang/lib/wx-1.6/ebin/wx.beam"
はふんっ、長かった!
で、サンプルを動かしてみれば、
はふー、やったよーー。(長かった....)
まぁ、タイトルバーのバッテンボタンを拾えてなかったりあやしいところもあるのですが*4、そこはおいおい。
それにしても、ARM というマイノリティ環境だと、自前ビルドは本当にうまく行くのかドキドキしますね*5。configure のオプションとかおっかなびっくりでした。
おまけ: Emacs の erlang-mode 設定
Erlang は Emacs びいきなので、普通にインストールするだけで、erlang-modeが追加されてます。なので、.emacs などに 記述を追加すれば OK です。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; erlang-mode (setq load-path (cons "/usr/local/lib/erlang/lib/tools-2.8.2/emacs" load-path)) (setq erlang-root-dir "/usr/local/otp") (setq exec-path (cons "/usr/local/otp/bin" exec-path)) (require 'erlang-start)
ちなみに、load-path のところの tools-x.x.x の部分は環境に合わせて変更してくださいまし。
*1:これはすごくダサいとおもうのですが、どうすればいいのでしょうかね...。せめて -include_lib(code:dir(wx) ++ "/include/wx.hrl") とか書けるとよいのですが
*2:実は最初は入れ忘れてて、configure のメッセージを見てから追加しました
*3:libxml2-util は xmllint のためですね
*4:追記: wxFrame:connect(Frame, close_window) し忘れてるだけですね(^^;
*5:そんなとき勇気をくれるのがArch Linux のページだったり。このページがあるというだけで、大丈夫という気がしてきます