Haskell を cygwin 上で動かすのに苦労した話
概要
Haskell の動作環境を用意する。cygwin上で動かそうとすると少し苦労したのでメモ。
インストーラのダウンロード
以下をURLから、Windows版のHaskell Platform のインストーラのうち環境に適したものをダウンロード。
Download Haskell Platform
なお、私がダウンロードしたのは、Full(64bit)版。
インストール
指示に従っていけば特に問題なし。パスもインストーラが作成してくれる。
Cygwin で ghci 起動
cygwin を起動して、ghci(対話モードのインタプリタ)を起動してみると・・。
$ ghci WARNING: GHCi invoked via 'ghci.exe' in *nix-like shells (cygwin-bash, in particular) doesn't handle Ctrl-C well; use the 'ghcii.sh' shell wrapper instead GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help Prelude>
こんなメッセージが表示される。
警告に書いてある通り、Ctrl + C を用いると、プロンプトは出てくれるのだがそこから何も入力できなくなる。
関連プロセス(ghc.exe)はなぜか生存中。このプロセスをタスクマネージャから強制終了すると入力ができるようになる。
これを防ぐために、ghciコマンドで起動している「ghci.exe」ではなく、「ghcii.sh」が起動するように変更する。
このファイルは「(プログラムフォルダ)\Haskell Platform\8.0.1\bin」に存在ある。
「ghcii.sh」→「ghci」にリネームする。そうすると、「ghci.exe」より優先度が高くなり、シェルの方を呼び出してくれる。
変更すると以下のようになる。
$ ghci GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help Prelude>
ghc でコンパイルできなかった
Haskell のソースファイルをghcを使ってバイナリにコンパイルするときに、私の環境では失敗した。
$ ghc fizzbuzz.hs -o fizzbuzz Linking fizzbuzz.exe ... fd:5: hGetContents: invalid argument (invalid byte sequence) ghc.exe: fd:5: hGetContents: invalid argument (invalid byte sequence)
もう一回起動してみると、なぜかメッセージが変わった。
$ ghc fizzbuzz.hs -o fizzbuzz Linking fizzbuzz.exe ... realgcc.exe: error: s\Java\▒▒▒K: No such file or directory P:\Program Files\Haskell Platform\8.0.1\lib/../mingw/bin/windres.exe: "P:\Program Files\Haskell Platform\8.0.1\lib/../mingw/bin/gcc.exe ▒̓X▒e▒[▒^▒X 1 ▒ŏI▒▒▒▒▒܂▒▒▒ `windres.exe' failed in phase `Windres'. (Exit code: 1)
今度は文字化けが発生。
エラーメッセージを調べていたら、
「LANG=C.utf-8 stack build works as intended.」(stack build は環境変数 LANGがC.utf-8だったら意図したとおりに動いてるよ)
とかあったので、文字化けも考慮して、LANGを確認。
$ echo $LANG ja_JP.UTF-8
C.UTF-8に変更。
$ export LANG='C.UTF-8' $ echo $LANG C.UTF-8 $ ghc fizzbuzz.hs -o fizzbuzz Linking fizzbuzz.exe ... $ ./fizzbuzz 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz (省略)
動いた!...でも。これが本当に原因か分からないので、動作検証。元に戻してみる。
$ export LANG='ja_JP.UTF-8' $ echo $LANG ja_JP.UTF-8 $ touch fizzbuzz.hs $ ghc fizzbuzz.hs -o fizzbuzz [1 of 1] Compiling Main ( fizzbuzz.hs, fizzbuzz.o ) Linking fizzbuzz.exe ... realgcc.exe: error: icrosoftw▒E ▒▒: Invalid argument P:\Program Files\Haskell Platform\8.0.1\lib/../mingw/bin/windres.exe: "P:\Program Files\Haskell Platform\8.0.1\lib/../mingw/bin/gcc.exe ▒̓X▒e▒[▒^▒X 1 ▒ŏI▒▒▒▒▒܂▒▒▒ `windres.exe' failed in phase `Windres'. (Exit code: 1)
・・・ってことで、これが原因らしい。
なお、touchコマンド使っているのは、ghc は内部でソースファイル、オブジェクトファイルの更新時間を見てるようで、
タイムスタンプ更新しないとコンパイルしてくれないため。