el-getをインストールしたので、Wanderlustをel-getでインストールしようとしたらエラーになりました。
次のエラーメッセージが出ました。(gnupack emacs-24.3-20130503 / el-get version 5.1.1dce781)
el-get install apel el-get: Package apel installed. el-get: git submodule update ok el-get: el-get-build apel: c:/app/emacs-24.3-20130503/bin/emacs -batch -q -no-site-file -l APEL-MK -f compile-apel prefix site-lisp site-lisp ok. el-get: el-get-build apel: c:/app/emacs-24.3-20130503/bin/emacs -batch -q -no-site-file -l APEL-MK -f install-apel prefix site-lisp site-lisp ok. apel failed to install: (error process byte-compile no longer connected to pipe; closed it) [2 times] el-get-installation-failed: process byte-compile no longer connected to pipe; closed it
(el-get 'sync 'wanderlust)を評価して同期でインストールしようとするとこのエラーは出ないようなので(別のエラーは出るw)、非同期の時だけの問題のようです。
原因
結論から言うと shell-file-name が "cmdproxy.exe" になっていないことが原因です。
el-getはwindows-ntで実行しているとき、shell-file-nameを強制的に "cmdproxy.exe" に変更してからプロセス呼び出しを行うようになっています。
ただ、この処理がel-get-build関数内にしかないのが問題です。
el-get-build関数は非同期の時、ビルドの完了を待たずに終了します。el-get-build関数内ででいくら
(let* (...略... (shell-file-name (or (and (eq system-type 'windows-nt) (executable-find "cmdproxy.exe")) shell-file-name)) ...略...) ...処理の本体...
のようなコードを書いても、非同期で実行される後続のプロセス呼び出しには適用されません。
shell-file-name が"cmdproxy.exe"でないと、 shell-quote-argument がWindowsのドライブレターを含むパスを正しくクォートできません。
"C:/home/hoge.el"みたいなパスを"C\:/home/hoge.el"のようにしてしまいます。
結果、サブプロセスで呼ばれるemacsは引数で渡されたファイル名を開けずに異常終了します。
そうすると、上のエラーのように、プロセスとパイプがつながらないよ!ということになります。
対策
el-getがサブプロセスを起動するときは必ず shell-file-name が"cmdproxy.exe"になるようにします。
まず、 el-get で使用する shell-file-name を次のようにして決めます。
;;; el-getが使用するshell-file-nameを決める。 ;;; el-get-build内(el-get version 5.1.1dce781)で似たような判定をしているが、 ;;; その関数内だけでは不十分。 (setq my-el-get-shell-file-name (or (and (eq system-type 'windows-nt) (executable-find "cmdproxy.exe")) shell-file-name))
そして、 el-get-start-process-list 関数を実行するときは、必ずその決めた shell-file-name を使うようにします。
;;; プロセスを呼び出す前に my-el-get-shell-file-name を適用する。 ;;; ;;; el-get-build内(el-get version 5.1.1dce781)で同じような処理をしているが、 ;;; それでは不十分。非同期インストールの時はel-get-build関数は処理の完了を ;;; 待たずに終わってしまうので。 (defadvice el-get-start-process-list (around my-el-get-start-process-list--modify-shell-file-name activate) (let ((shell-file-name my-el-get-shell-file-name)) ad-do-it))
el-get-start-process-list 関数内でコマンドライン引数に shell-quote-argument が適用されています。
shell-quote-argument は shell-file-name の値によって動作が変わるので、
この関数の中を実行しているときだけ shell-file-name が"cmdproxy.exe"になっていればOKです。
(setq el-get-verbose t)
で詳細を表示するようにして、 :args 部分のパスに問題が無ければOKです。