UbuntuとEmacsでF#

意外と簡単に環境つくれました。Ubuntu は 10.04 LTS です。

♯Monoインストール

Ubuntu の apt で入れました。というか入れてありました。version は 2.10.5 なので F# 入れるには十分新しいようです。

♯make ツール

autoreconf をしたら libtoolize が無いと怒られたので

$ sudo aptitude install libtool

で入れました。automake autoconf も必要なのでなければ入れます。もちろん make も必要です。

♯F# 本体の make と install

$ cd ~/download
$ git clone git://github.com/fsharp/fsharp
$ cd fsharp
$ autoreconf
$ ./configure --prefix=$HOME/local/mono
$ make
$ make install

prefix はインストールパス指定。私はシステムを汚したくないので $HOME/local に色々入れてます。好みで適当な場所指定しとけばよいです。prefix を省略すると /usr/local にインストールされるようです。
make には結構時間がかかります。

環境変数設定

このままでは mono が F# のアセンブリを認識しないので環境変数を設定します。*1
~/.bashrc に、

export MONO_PATH=$HOME/local/mono/lib/mono/4.0

と書いて、一旦ログアウト & 再ログインで F# アセンブリが利用可能になります。

♯ここまでの確認

terminal で、interactive を動かしてみます。

~$ ~/local/mono/bin/fsharpi

Microsoft (R) F# 2.0 Interactive build (private)
Copyright (c) 2002-2010 Microsoft Corporation. All Rights Reserved.

For help type #help;;

> open System;;
> Console.WriteLine "Hello, F#";;
Hello, F#
val it : unit = ()
> #q;;
- Exit... 

mono の F# では、インストールディレクトリ直下の bin の中に 4つの実行ファイルがあります。

$ cd ~/local/mono
$ find ./bin | sort
./bin
./bin/fsharpc
./bin/fsharpc2
./bin/fsharpi
./bin/fsharpi2

fsharpi が interactive で、 fsharpc がコンパイラ。 2 がついてるのはよく分りませんが version が微妙に違うようです。ここでは無印の方を使うことにします。
コンパイルもしてみましょう。

$ cd ~/workspace
$ echo 'System.Console.WriteLine "Hello, F#"' > hello.fs
$ cat hello.fs
System.Console.WriteLine "Hello, F#"
$ ~/local/mono/bin/fsharpc hello.fs 
Microsoft (R) F# 2.0 Compiler build (private)
Copyright (c) 2002-2010 Microsoft Corporation. All Rights Reserved.
$ ls
hello.exe  hello.fs
$ ./hello.exe 
Hello, F#

環境変数 MONO_PATH が設定されていないと、./hello.exe 実行時に例外がスローされます。

$ ./hello.exe 
Missing method .ctor in assembly /home/USERNAME/workspace/fsharp/hello.exe, type Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute
Can't find custom attr constructor image: /home/USERNAME/workspace/fsharp/hello.exe mtoken: 0x0a000001

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'FSharp.Core, Version=4.0.0.0, ... (以下略)

Emacs設定

fsharp-mode を入れます

cd ~/download
git clone https://github.com/emacsmirror/fsharp-mode.git
cp -r fsharp-mode ~/.emacs.d/site-lisp/fsharp-mode

~/.emacs.d/init.el 等に例えばこんな感じで設定を書きます。*2

(setenv "MONO_PATH" (expand-file-name "~/local/mono/lib/mono/4.0"))
(add-to-list 'load-path "~/.emacs.d/site-lisp/fsharp-mode")
(add-to-list 'auto-mode-alist '("\\.fs[iylx]?$" . fsharp-mode))
(autoload 'fsharp-mode "fsharp" "Major mode for editing F# code." t)
(autoload 'run-fsharp "inf-fsharp" "Run an inferior F# process." t)

(let* ((fsharp-bin "~/local/mono/bin/")
       (fsi-command (concat fsharp-bin "fsharpi --readline-"))
       (fsc-command (concat fsharp-bin "fsharpc")))
  (setq inferior-fsharp-program fsi-command)
  (setq fsharp-compiler fsc-command))

Emacsでの開発

拡張子 .fs のファイルを開くと fsharp-mode になります。
fsharp-mode で C-c C-s とすると、inferior-fsharp-program がミニバッファに表示され、Enter で interactive が起動します。
ソースコードのバッファで C-c C-r がリージョンの評価、 C-c C-e は fsharp-eval-phrase だそうですが、いまいち評価される範囲が分らない。
便利なのは、C-c C-c でコンパイルして、 C-c x でコンパイルした実行ファイルを実行とか。コンパイルエラーがあれば、 C-x ` でエラー行へ飛びます。

♯その他ライブラリのインストール

ちょっと乱暴だけど、とりあえず MONO_PATH に設定したディレクトリに dll を放り込めばライブラリも使えるようです。PowerPack も FParsec もそれでいけました。
FParsec は Windows でビルドしたアセンブリをコピーしてきたもので動作確認とれました。
やっぱこれじゃダメかも。あとで確認します。

♯確認した

外部アセンブリを認識させるには elisp を書く必要がありそうです。別エントリで晒してます。
Mono用 fsharp-mode 補助スクリプト

*1:もしかしたら ./configure でインストール先(prefix) がデフォルトのままならば MONO_PATH 設定は不要かもしれませんが未確認です。

*2:fsharp-mode の README に書いてあるものを若干アレンジしてあります。