2015年7月19日日曜日

[cygwin][haskell][emacs] MinGWでcygwinの"/cygdrive"パスにアクセスする裏技(cygwin環境のemacsでflycheckを動作させる方法)

haskell関連のコマンドはMinGW上でビルドされているため、cygwin環境の"/cygdrive"から始まるパスには対応していません。haskell-hlintから呼び出されるhlintも当然この問題の影響を受けておりemacs関連の設定が適切にされていたとしても、以下のようなエラーが表示されてしまいます。

ミニバッファに表示されるエラー詳細:

Suspicious state from syntax checker haskell-hlint: Checker haskell-hlint returned non-zero exit code 1, but no errors from output: hlint.exe: Couldn't find file: /cygdrive/c/Users/Hiroyuki/tmp/flycheck_hello.hs

MinGW関連コマンドで"/cygdrive"から始まるパスを解釈できない問題の回避方法:

"/cygdrive"から始まるパスをMinGWによってビルドされたバイナリ(hlint)からも解釈できるようになれば、この問題は回避できるのでは?と考え、mklinkを用いて以下の手順でシンボリックリンクを作ってみました。
C:\> cd \
C:\> mkdir cygdrive
C:\> cd cygdrive
C:\cygdrive> mklink /d C C:\
これが大成功!"C:\CYGDRIVE\C"に"C:\"へのシンボリックリンクを作っておくことでcygwin上の"/cygdrive/c/xxx/yyy"といったパスがMinGW上では"C:\xxx\yyy"として解釈される状態になります。
この環境ではemacs上でflycheckが正しく動作するようになりました。

この環境はMinGW関連コマンド全般に適用可能:

この裏技はMinGW/MSYSでビルドされた任意のコマンドに適用可能なはずです。cygwin環境とMinGW環境が混在していて、MinGW/MSYS関連コマンドの実行に弊害が出ている方は是非お試しいただければ、と思います。

余談:うまくいかなかった方法(cygwinのマウント機能の利用メモ):

cygwin環境において"C:"ドライブのルートを"/C"としてマウントする方法もありますが、MinGWは"/C/xxx/yyy"というパスは解釈できずNGでした。
% cd /
% mkdir c
% mount c: /c
"C:"を/C:"としてマウントできれば、と思ったのですが残念ながら以下のようなエラーになりました…。
% mkdir c:
% mount c: c:
mount: c:: Invalid argument

参考: