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 105 00:46 ./
drwxr-xr-x 5 root root  4096 105 00:46 ../
drwxr-xr-x 2 root root 16384 105 00:46 gen/
-rw-r--r-- 1 root root 12091  820  2014 wx.erl
-rw-r--r-- 1 root root 21525  820  2014 wx_object.erl
-rw-r--r-- 1 root root  2180  820  2014 wxe.hrl
-rw-r--r-- 1 root root  8661  820  2014 wxe_master.erl
-rw-r--r-- 1 root root 14153  820  2014 wxe_server.erl
-rw-r--r-- 1 root root  6972  820  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 のオプションとかおっかなびっくりでした。

おまけ: Emacserlang-mode 設定

ErlangEmacs びいきなので、普通にインストールするだけで、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 のページだったり。このページがあるというだけで、大丈夫という気がしてきます