我可以避免过时的字节编译elisp文件吗?


27

有时,当我启动Emacs时,会收到类似的消息。

源文件`/home/USER/.emacs.d/elpa/....el'比字节编译文件新

另外,有时我会编辑正在开发的程序包,而忘记重新编译它。当我尝试加载新文件时,我花了一段时间才意识到Emacs仍在使用旧的编译文件。

有没有一种方法可以告诉Emacs完全避免早于其各自源文件的字节编译文件?

Answers:


35

Emacs 24.3或以下

没有内置的方法可以防止这些旧文件被加载,但是有一些简便的方法可以消除它们。

  • 您可以通过调用重新编译整个elpa目录
    M-x byte-recompile-directory RET ~/.emacs.d/elpa/
    这应该摆脱过时的文件。
  • 您可以使用 自动编译包并激活auto-compile-on-load-mode它,以便可以在加载文件之前对其进行编译。

埃马克斯24.4

是的,事实证明这很简单。该load-prefer-newer 变量正是服务于这一目的。

(setq load-prefer-newer t)

不幸的是,当某些代码专门针对.elc文件时,该功能将无法正常工作 (load "server.elc")。但是只要您使用requires或load不带后缀的调用就足够了,您应该这样做。

从文档:

load-prefer-newer是在lread.c中定义的变量。
它的值为零

文档:
非零表示加载倾向于使用文件的最新版本。
当未明确指定文件名后缀,并且负载正在尝试各种可能的后缀时,这适用(请参阅load-suffixes和load-file-rep-suffixes)。通常,它会在存在的第一个文件处停止,除非您明确指定一个或另一个。如果此选项为非nil,它将检查所有后缀并使用最新的文件。
请注意,如果您对此进行自定义,则显然不会影响在读取您的自定义之前加载的文件!


1
我敦促人们使用auto-compileEmacs 24.4+及以下版本中的(优秀!)库。这是一个真正的“一劳永逸”的解决方案。load-prefer-newer仅确保在编译后的代码过期后,您将继续运行慢速的未编译代码
菲尔2014年

1
@phils如今,由于渴望宏扩展,字节码已不比普通源代码快很多。
lunaryorn 2014年

重新启动后,我对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仍在使用旧的编译文件。

我可以建议在您的init文件中添加一个挂钩吗?

(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
哇,那会尝试对非省略缓冲区进行字节编译。不理想!强大的方法是使用自动编译包。
sanityinc 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.