How do I automatically (re)compile ELPA packages?

compilation, elisp, elpa, emacs

Solution

package.el actually uses exactly the same method, it's just recompiling on startup makes the errors more noticable.

The function used is `package--make-autoloads-and-compile`, which calls:

(byte-recompile-directory pkg-dir 0 t)

So the original code in the question is correct. However, to recompile a directory that isn't yet compiled, you can do the following:

(require 'dash)
(require 'f)

(defun was-compiled-p (path)
  "Does the directory at PATH contain any .elc files?"
  (--any-p (f-ext? it "elc") (f-files path)))

(defun ensure-packages-compiled ()
  "If any packages installed with package.el aren't compiled yet, compile them."
  (--each (f-directories package-user-dir)
    (unless (was-compiled-p it)
      (byte-recompile-directory it 0))))

(ensure-packages-compiled)

Problem

I'm now installing as much as I can through MELPA and Marmalade, and I manage my ~/.emacs.d using git. However, I have git ignore *.elc files. This means that when I install a package on one system and then start using another system, `git pull` only gives me the *.el files. Using these files is often slower than using *.elc. I tried adding the following to ~/.emacs.d/init.el: ``` ;; load the packages we've installed. Note that package-install ;; byte-compiles the packages, but .elc is ignored by git so we force recompilation here (byte-recompile-directory (expand-file-name "~/.emacs.d/elpa") 0) (package-initialize) ``` Unfortunately, this isn't equivalent to the compilation done by package.el. For example, if I install emacs-eclim, package.el doesn't compile emacs-eclim/company-emacs-eclim.el, and I get the following error: ``` Leaving directory `/home/wilfred/.emacs.d/elpa' Compiling file /home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/company-emacs-eclim.el at Mon Mar 11 15:40:01 2013 Entering directory `/home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/' company-emacs-eclim.el:35:1:Error: Cannot open load file: eclim Warning: reference to free variable `multiple-cursors-mode' Warning: reference to free variable `mc--read-char' Warning: assignment to free variable `mc--read-char' Warning: reference to free variable `multiple-cursors-mode' Warning: reference to free variable `mc--read-quoted-char' Warning: assignment to free variable `mc--read-quoted-char' Warning: reference to free variable `rectangular-region-mode' Warning: reference to free variable `rectangular-region-mode' ``` How do I make Emacs byte-compile only the same files as package.el would?

Original source