このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

EmacsベースのErlang開発環境DistelをWindowsで使う

Distelは、EmacsErlangノード(分散ERTS)の通信を可能にするEmacs Lispライブラリです。Emacs LispErlangを使った分散プログラミングの基盤となります。また、このライブラリを使って作られたErlang開発ツールセットも提供されているので、Distelは“EmacsベースのErlang開発環境”と捉えることもできます。

現状のDistel配布は、Unix系OSをターゲットにしていますが、WindowsThinkpad X31 + Windows XP)とMeadowWindows上で動作するEmacs変種)に対してインストールしてみました。問題点は、場当たり的な対処で済ましているので、もっといい方法がありそうですが、とりあえず現状報告(書き留めておかないとスッパリ忘れそうだから)。

内容:

  1. 参考リンク集
  2. Erlang/OTPとMeadowのインストール時の注意
  3. erlang-modeのインストール
  4. Distelのダウンロード
  5. ホームディレクトリの問題
  6. ダイナミックTags機能
  7. makeは手動で行った
  8. ファイルのコピー
  9. Distelを使うための設定
  10. ダイナミックTagsの実行
  11. その他の注意や情報

Erlangノードに関しては、次を参照。

●参考リンク集

  1. Distelのホームページ - http://fresh.homeunix.net/~luke/distel/
  2. Distelの開発サイト(Google Code)- http://code.google.com/p/distel/
  3. Distel User Manual(PDF版) - http://fresh.homeunix.net/~luke/distel/distel-user-3.3.pdf
  4. 開発環境としてのDistelの紹介 - http://bc.tech.coop/blog/070528.html

Erlang/OTPとMeadowのインストール時の注意

Erlang/OTPの最新版はR11B-5(Jun 13, 2007)です。僕は、以前にインストールしたR11B-4(Mar 28, 2007)を使っています。Distelは、Erlang/OTP R8以降であれば動くようなので、Erlangのバージョンが最新である必要はありません。

Meadowの安定版はバージョン2.10です。Meadow 2.10は、GNU Emacs 21.4 ベースであり、DistelのターゲットもEmacs 21なので好都合です。

Meadowでは、「空白文字/日本語文字を含むパスにインストールしてはダメ」とインストール文書に書いてあります。しかしErlang/OTPは、デフォルトでC:\Program Files\の下にインストールされます。これだとDistelで不都合があるので、空白文字/日本語文字を含まないパスにインストールしてください。

以下の記述では、Erlang/OTPをインストールしたディレクトリをERLANG_HOME、MeadowをインストールしたディレクトリをMEADOW_HOMEとします。僕の場合は:

となっています。

なお、パスの表記を $ERLANG_HOME/lib/ とか ~/.emacs のようにも書きますが、すべてWindowsでの話です。PATH環境変数には、$ERLANG_HOME/binと$MEADOW_HOME/binが含まれているとします(そのように設定すること)。

erlang-modeのインストール

Distelは、Erlang/OTP付属のerlang-modeを拡張します。事前にerlang-modeをインストールしておく必要があります。$ERLANG_HOME/lib/tools-2.5.4/emacs/ に行ってください。ここにあるerlang.elとerlang-start.elをコンパイルしておきます。


>meadow.exe -batch -f batch-byte-compile erlang.el erlang-start.el

~/.emacsに次の記述を加えます。


;;; Erlang - basic erlang-mode
(setq erlang-root-dir "C:/Installed/erl5.5.4") ; この変数は設定しておく
(add-to-list 'load-path
(concat erlang-root-dir "/lib/tools-2.5.4/emacs"))
(add-to-list 'exec-path
(concat erlang-root-dir "/bin"))
(require 'erlang-start)
もちろん、実際のパスは各自の環境に合わせて書き換えます。拡張子が.erlであるファイルを開くと、バッファ・モードラインに、(Erlang)と表示され、メニューバーにErlangメニューが追加されていればOKです。

erlang-modeの使い方は次のmanページを見てください。

●Distelのダウンロード

Distelをダウンロードしておきましょう。

多くの文書で、Distelの開発サイトURLが http://distel.sourceforge.net/ となっていますが、現在はGoogle Codeに移っています。

現状では、ダウンロード用配布パッケージはないので、Subversionリポジトリからチェックアウトします。Windowsで動作するSubversionクライアント、例えばTortoiseSVNをインストールして、チェックアウトを実行します。(TortoiseSVNのインストールは、例えばhttp://90h.dip.jp/archives/2006/08/windowssubversion.htmlを参照)。

ファイルをチェックアウト(ダウンロード)したローカルディレクトリを、以下DISTEL_WORK_DIRとして参照します。

●ホームディレクトリの問題

僕の環境では、まずホームディレクトリの件で困ってしまいました。以下に説明しましょう。

ErlangMeadowもホームディレクトリの概念を持っていて、初期設定やマジッククッキーはホームディレクトリに置きます。ところが、ErlangMeadowでホームディレクトリの認識方法が違うのです。

  • Erlang:%HOMEDRIVE%%HOMEPATH% をホームとする*1
  • Meadow:%HOME% をホームとする。

%HOMEDRIVE%%HOMEPATH% と %HOME% が同じパスになるように設定してあれば問題はないのですが、食い違っていると面倒です。ファイルをコピー(同期)するなどして、食い違ったままで運用できなくもないでしょうが、トラブルの原因! 僕の場合、諸般の事情で現状を変えるのもイヤだったので、次のようなバッチファイルを作ってみました。


@echo off
REM meadow4erl.bat

setlocal
set MEADOW_HOME=C:\Installed\Meadow
set SHELL=%MEADOW_HOME%\bin\cmdproxy.exe
set TERM=CMD
REM ↓HOMEをErlangに合わせて書き換える.
set HOME=%HOMEDRIVE%%HOMEPATH%
start "Meadow" %MEADOW_HOME%\bin\Meadow.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
endlocal


@echo off
REM werl4meadow.bat

setlocal
REM ↓HOMEPATHをMeadowに合わせて書き換える.
set HOMEPATH=\Documents and Settings\Hiyama\Work
start werl -sname meadow
endlocal

どっちを使っても動くには動きますが、もっと運用上の工夫が必要そうです(いまんところ、何もやってない)。

●ダイナミックTags機能

開発環境としてのDistelのウリに、ダイナミックTags機能があります。これは、タグジャンプ、つまり関数名にカーソル*2が乗っている状態でM-.(通常は[ESC],[.])を押すと、関数定義に飛べる機能です。

オリジナルのerlang-modeでは、関数名とソースファイルの対応を記述したTAGSファイルを見てタグジャンプするのですが、DistelのダイナミックTagsでは、Erlangノード(分散ERTS)と通信してソースファイル(のパス)を問い合わせます。ERTSを一種のネームサーバー(関数名→ソースファイルパスと解決)として使うわけです。この方式だと、TAGSファイルをメンテナンスする必要もないし、ソース編集に伴う“ズレ”も少なくなります(皆無にはできない)。

実は、このダイナミックTags機能をMeadowで使えるようにすることを目的にしてDistelをインストールし始めたのでした。後でまたダイナミックTags機能に触れます。

●makeは手動で行った

Distelのセットアップは、基本的にmakeを使うようになっていて、Makefileが付属しています。MicrosoftのNMakeを使うとか、Cygwin上でGNU Makeを動かすとかの手段もあるでしょうが、Makefile自体の手直しが多そうなので、手作業でメイクすることにしました。やるべきなことは:

  1. Erlangソースのコンパイル(BEAMファイルの生成)
  2. Emacs Lispソースのコンパイル(elcファイルの生成)
  3. Texinfo文書のコンパイル(Infoファイルの生成)

Erlangソースのコンパイル

$DISTEL_WORK_DIRにおいて次のコマンドを実行します。


>erlc -W -o ebin +debug_info src/distel.erl src/distel_ie.erl src/fdoc.erl
若干の警告が出ますが、$DISTEL_WORK_DIR/ebinに*.beamができます。

Emacs Lispソースのコンパイル

コマンドラインからのコンパイルがうまくいかなかった*3ので、Meadowから対話的にコンパイルしました。

  1. *scratch*バッファで、(add-to-list 'load-path "DISTEL_WORK_DIR/elisp") としておく。(DISTEL_WORK_DIRは実際のパスに置き換える。)
  2. C-u M-x byte-recompile-directoryとする。ミニバッファに DISTEL_WORK_DIR/elisp/ と答える。
  3. y/n プロンプトにすべて y と答えていくと、12個のファイルがコンパイルされる。

Texinfo文書のコンパイル

$DISTEL_WORK_DIRにおいて次のコマンドを実行します。


>makeinfo -o doc/distel.info doc/distel.texi

なお、Distelのホームページから、PDF/PSの文書ファイルが手に入るので、TexinfoからPDF/PSを生成する必要はないでしょう。

●ファイルのコピー

生成されたファイルを適切な場所にコピーするのは、コマンドラインからでは間違いやすいので次のバッチファイルで行いました。


@echo off
REM install-distel.bat

setlocal
set ERLANG_HOME=C:\Installed\erl5.5.4
set MEADOW_HOME=C:\Installed\Meadow

set ERL_SRC_DIR=%ERLANG_HOME%\site-lib\distel\src
set ERL_EBIN_DIR=%ERLANG_HOME%\site-lib\distel\ebin
set ELISP_DIR=%MEADOW_HOME%\site-lisp\distel
set INFO_DIR=%MEADOW_HOME%\info

echo %ERL_SRC_DIR%
if not exist %ERL_SRC_DIR%\nul goto NoDir
echo OK
echo %ERL_EBIN_DIR%
if not exist %ERL_EBIN_DIR%\nul goto NoDir
echo OK
echo %ELISP_DIR%
if not exist %ELISP_DIR%\nul goto NoDir
echo OK
echo %INFO_DIR%
if not exist %INFO_DIR%\nul goto NoDir
echo OK

copy src\*.erl %ERL_SRC_DIR%
copy ebin\*.beam %ERL_EBIN_DIR%

copy elisp\*.el %ELISP_DIR%
copy elisp\*.elc %ELISP_DIR%

copy doc\distel.info %INFO_DIR%
install-info --info-dir=%INFO_DIR% --section Emacs %INFO_DIR%\distel.info

goto End

:NoDir
echo すぐ上に表示されているディレクトリが作成されていません。作成してください。
goto End

endlocal

:End

ERL_SRC_DIR、ERL_EBIN_DIR、ELISP_DIR、INFO_DIR は各自適切に設定します。

●Distelを使うための設定

なんらかの方法で、ErlangMeadowのホームディレクトリは一致させてあるとして、~/.erlangと~/.emacsを設定します。

まず、~/.erlangに次の1行を加えます。


code:add_pathz("C:/Installed/erl5.5.4/site-lib/distel/ebin").
設定しているパスは$ERL_EBIN_DIRです。~/.erlangが実行されているかどうかを確認するには、Erlangシェルから、

> code:which(distel).
として、distel.beamのパスが返るかどうか見てください。

~/.emacs には次のコードを加えます。


;;; Erlang - Distel extended erlang-mode
(let ((distel-dir "C:/Installed/Meadow/site-lisp/distel"))
(unless (member distel-dir load-path)
(add-to-list 'load-path distel-dir)))
(require 'distel)
(distel-setup)

これでerlang-modeが拡張されるので、拡張子が.erlであるファイルを開くと、バッファ・モードラインは(Erlang EXT)ErlangメニューにはDistel項目が増えています。

●ダイナミックTagsの実行

とりあえず僕は、ホームディレクトリを合わせるために、werl4meadow.batを使うことにしました。先に、werl4meadow.batを実行しておきます(~/.emacsでプロセス起動すればいいのかな?)。extended-erlang-modeで、M-. でタグジャンプしようとすると、最初は通信する相手のErlnagノードを聞かれます。meadowと答えます。

そしたら、


error in process filter: Symbol's function definition is void: member*
アレマッ。member*って名前の関数がないと文句言っている。関数member*は、$MEADOW_HOME/lisp/emacs-lisp/cl.elをロードすれば定義されるので、~/.emacs

(require 'cl)
を入れておくことにしました。

これで、M-. と M-,(戻る)が使えるようになりました。おー、快適快適。

●その他の注意や情報

なんだかよくわからないけど、


Invalid regexp: "Invalid back reference"
ってエラーが出るんですよ。"*derl Erlangノード名*"という名前のバッファを消すとエラーは出なくなりますが、不気味じゃ。[追記]←どうもこれは、檜山固有の問題で、Distelとは無関係なところに由来するようです。失礼しました。[/追記]

それはそうと、Distelの分散プログラミング・システムとしての側面は次の文書に紹介されています。

JavaとJInterfaceの関係が、Emacs LispとDistelの関係と同じだということがわかります。

Erlang統合開発環境としては、他に次のものがあります(僕は触ったことがありませんけど)。

  1. NetBeansベースのErlyBird - http://sourceforge.net/projects/erlybird
  2. EclipseベースのErlide - http://erlide.sourceforge.net/

*1:%HOMEDRIVE%%HOMEPATH%は、%PROFILE%と同じ値です。この値はまた、Windows APIのGetUserProfileDirectoryでも取れるようです。

*2:Emacs用語ではポイントと言うのが正確なようです。

*3:原因追及もせずにアッサリあきらめました。