古いバイトコンパイルされたelispファイルを回避できますか?


27

時々、Emacsを起動すると、次のようなメッセージが表示されます。

ソースファイル `/home/USER/.emacs.d/elpa/....el 'はバイトコンパイルされたファイルよりも新しい

また、開発中のパッケージを編集して、再コンパイルするのを忘れることもあります。新しいファイルをロードしようとすると、Emacsがまだ古いコンパイル済みファイルを使用していることに気付くのに時間がかかります。

Emacsに、それぞれのソースファイルよりも古いバイトコンパイルされたファイルを完全に回避するように指示できる方法はありますか?

回答:


35

Emacs 24.3以前

これらの古いファイルがロードされるのを防ぐ組み込みの方法はありませんが、それらを取り除く簡単な方法があります。

  • 次を呼び出して、elpaディレクトリ全体を再コンパイルできます
    M-x byte-recompile-directory RET ~/.emacs.d/elpa/
    これにより、古いファイルが削除されます。
  • 自動コンパイルパッケージを使用して、 auto-compile-on-load-modeファイルをロードする前にファイルをコンパイルできるようにアクティブ化できます。

Emacs 24.4

はい、それはかなり単純であることが判明しました。load-prefer-newer 変数は、まさにこの目的を果たします。

(setq load-prefer-newer t)

残念ながら、一部のコードがのように特定の.elcファイルをターゲットにしている場合は機能しません (load "server.elc")。ただし、requires を使用している場合、またはloadサフィックスなしで呼び出している場合は、これで十分です。

ドキュメントから:

load-prefer-newerは、lread.cで定義されている変数です。
その値はnilです

ドキュメント:
非nilは、loadがファイルの最新バージョンを優先することを意味します。
これは、ファイル名の接尾辞が明示的に指定されておらず、ロードがさまざまな可能な接尾辞を試行している場合に適用されます(load-suffixesおよびload-file-rep-suffixesを参照)。通常、どちらか一方を明示的に指定しない限り、最初に存在するファイルで停止します。このオプションが非nilの場合、すべてのサフィックスをチェックし、最新のファイルを使用します。
これをカスタマイズする場合、カスタマイズが読み込まれる前にロードされるファイルには明らかに影響しないことに注意してください!


1
auto-compile以下に加えて、Emacs 24.4+の(素晴らしい!)ライブラリを使用するよう人々に促します。それは本当の設定と忘れの解決策です。コンパイルされたコードが古くなった後でも、遅いコンパイルされていないコードを実行し続けるload-prefer-newerことを保証するだけです。
phils 14

1
@phils最近のバイトコードは、熱心なマクロ展開のおかげで、プレーンソースコードよりも高速ではありません。
lunaryorn 14

org-agenda-sorting-strategy(org-agenda.el内)に加えた変更は再起動後に反映されませんでしたが、回答で説明されているように.elcファイルを再コンパイルすると問題が解決しました。
Earlio

17

load-prefer-newer(使用可能な場合のみ)設定すると、正しいコードがロードされますが、バイトコンパイルされていない可能性があるため、パフォーマンスが若干低下する可能性があります。

Jonas Bernoulliの優れた自動コンパイルライブラリを使用して、この問題が発生しないようにすることができます。特に、auto-compile-on-load-mode古い.elcファイルをロードする前に再コンパイルします。


3

私はずっと前にインターネットでこれに会った:

;; If you're saving an elisp file, likely the .elc is no longer valid:
(add-hook 'emacs-lisp-mode-hook 'esk-remove-elc-on-save)
(defun esk-remove-elc-on-save ()
  "If you're saving an elisp file, likely the .elc is no longer valid."
  (make-local-variable 'after-save-hook)
  (add-hook 'after-save-hook
            (lambda ()
              (if (file-exists-p (concat buffer-file-name "c"))
                  (delete-file (concat buffer-file-name "c"))))))

FILEemacs-lisp-modeで作業して保存すると、上記のコードFILEcが存在する場合は削除されます。


0

また、開発中のパッケージを編集して、再コンパイルするのを忘れることもあります。新しいファイルをロードしようとすると、Emacsがまだ古いコンパイル済みファイルを使用していることに気付くのに時間がかかります。

初期化ファイルにフックを追加することをお勧めしますか?

(add-hook 'after-save-hook 'byte-compile-current-buffer)

または、elファイルにのみフックを適用する場合:

(add-hook 'emacs-lisp-mode-hook (lambda () (add-hook 'after-save-hook 'byte-compile-current-buffer nil t)))

9
おっと、それは非elispバッファでもバイトコンパイルを試みるでしょう。理想的ではありません!これを行うための堅牢な方法は、自動コンパイルパッケージを使用することです。
sanityinc 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.