dorapon2000’s diary

忘備録的な。CTFやってます。

emacs上とシェル上でのバイトコンパイルの結果が違う

前の記事で気づいたバイコンパイル時のエラーについて、同じように困ってる人の助けになればと思い残しておきます。


前提

  • mac OSX Yosemite 10.10.5
  • emacs 24.5
  • init-loader
  • packagesでパッケージ管理

フォルダ構成は前の記事で書きました。

発生したエラー

$ emacs -batch -f batch-byte-compile inits/*.el

In toplevel form:
inits/00-basic.el:22:7:Warning: assignment to free variable `show-paren-style'
inits/00-basic.el:64:7:Warning: assignment to free variable `c-default-style'
inits/00-basic.el:82:1:Warning: cl package required at runtime
Wrote /Users/dorapon2000/.emacs.d/inits/00-basic.elc

In end of data:
inits/10-anzu.el:8:1:Warning: the function `global-anzu-mode' is not known to be defined.
Wrote /Users/dorapon2000/.emacs.d/inits/10-anzu.elc

In toplevel form:
inits/10-auto-async-byte-compile.el:5:1:Error: Cannot open load file: No such file or directory, auto-async-byte-compile
Wrote /Users/dorapon2000/.emacs.d/inits/10-color-theme.elc
Wrote /Users/dorapon2000/.emacs.d/inits/10-elscreen-persist.elc

...

いつものようにinits以下の.elファイルをすべてバイコンパイルしようとすると、全体的に上記の様な警告とエラーが出ました。 種類としては3つ。

  1. Warning: assignment to free variable `show-paren-style'
  2. Warning: the function `global-anzu-mode' is not known to be defined.
  3. Error: Cannot open load file: No such file or directory, auto-async-byte-compile

特に3.が出るとそのファイルがコンパイルされないのでなんとかしたかったです。 1.は調べるとあまり気にしなくていい感じでした。 2.は3.と原因が同じという雰囲気をしてます。

2.と3.について同じように悩んでる人はいないものかと検索しても、原因はヒットしませんでした。 同じような環境の人はたくさんいるはずなのに、なぜ自分だけこの問題が発生するのか未だにわかりません。

解決法

初心に戻ってバイコンパイルについて調べていて、 Emacsで設定ファイルを初めてバイトコンパイルする方法とその後自動で更新する方法 にある方法でバイコンパイルしたら、警告もほぼ出ずにするっとコンパイルできました。 しかし、それを.elファイルに書いてシェル上で実行してみてもうまくいきませんでした。

# 全部は長いので10-auto-async-byte-compile.elだけをコンパイルさせる。残りはコンパイルをskip。

$ cat byte-compile.el
(byte-recompile-directory (expand-file-name "~/.emacs.d/inits") 0)

$ emacs --script byte-compile.el
Checking /Users/dorapon2000/.emacs.d/inits...
Compiling /Users/dorapon2000/.emacs.d/inits/10-auto-async-byte-compile.el...

In toplevel form:
10-auto-async-byte-compile.el:5:1:Error: Cannot open load file: No such file or directory, auto-async-byte-compile
Done (Total of 0 files compiled, 1 failed, 36 skipped)

ここで思い当たるのはload-pathです。 ロードパスの通った(設定が一度読み込まれた)emacs上だからうまくいき、シェル上ではロードパスが読み込めておらず2.や3.のエラーがでる。 そこで、$ emacs -qで設定ファイルを読み込まずに起動して、先ほどの方法でコンパイルすると案の定できませんでした。 次に、(package-initialize)(ロードパスを読み込む)を実行してから試すとコンパイルできました。

最終的には以下のようにすることで、シェル上からでも正常にバイコンパイルできるようになりました。 (2.と3.が解決できました)

$ cat byte-compile.el
(package-initialize)
(add-to-list 'load-path "~/.emacs.d/elisp/auto-complete")
(byte-recompile-directory (expand-file-name "~/.emacs.d/inits") 0)

$ emacs --script byte-compile.el
Checking /Users/dorapon2000/.emacs.d/inits...
Compiling /Users/dorapon2000/.emacs.d/inits/10-auto-async-byte-compile.el...
Wrote /Users/dorapon2000/.emacs.d/inits/10-auto-async-byte-compile.elc
Done (Total of 1 file compiled, 0 failed, 36 skipped)

(add-to-list 'load-path "~/.emacs.d/elisp/auto-complete")について。 auto-completeはpackagesで入れたパッケージではなく、野良lispのため、別にload-pathを通す必要があるようでした。 しかし自分自身よくわかっておらず、packagesにもあるパッケージだからとそちらで改めて落としたのに、この行がないとコンパイルできませんでした。 そもそも、(package-initialize)でelisp/auto-completeのパスは通っているはずなのに、やはり書かないといけませんでした。

なぜ自分だけこの問題が起きたのか。なぜ以前はできていたものが今はできないのか。エラーが出るものと出ないものの差はなんだったのか。 疑問は山積みですが、なにはともあれシェル上からコンパイルできるようになって満足とします。