CompiledFile

Most EmacsLisp libraries run faster when byte-compiled, so you’ll usually want to ensure that the libraries you use are byte-compiled. The EmacsLispIntro has this to say on ByteCompilation:

As a practical matter, for most things you might do to customize or extend Emacs, you do not need to byte compile. See 'Byte Compilation' in the GNU Emacs Lisp Reference Manual, for a full description.

The ElispManual says little on being earnest about byte compilation. If you are an EmacsNewbie, then these are good rules of thumb:

You can byte-compile any EmacsLisp source file using the command ‘byte-compile-file’. For example with Emacs-Lisp you do:

  (byte-compile-file "foo.el")

EmacsLisp source files have extension `.el’. Byte-compiled files have extension `.elc’. If both source and byte-compiled files are present for the same library at the same place in your ‘load-path’, Emacs will load the byte-compiled file, not the source file.

This can be a source of confusion. If you change a source file, but don’t remember to byte-compile it again, then Emacs might load the out-of-date byte-compiled file instead of the newer source file. Emacs warns you about this, but you might miss the warning message.

A good way to prevent this is to get in the habit of using command ‘byte-recompile-directory’ to byte-compile all source files that are newer than their byte-compiled versions. This command will only byte-compile files that already have a byte-compiled version unless you provide it with the flag 0.

Here it is an example of Emacs-Lisp code using such a function:

  ;; compile all the files .elc files which has a corresponding newer .el file 
  (byte-recompile-directory ".")
  ;; like before, but in this case force the byte-compilation of an .el file when the corresponding
  ;; .elc file doesn't exist
  (byte-recompile-directory "." 0)

AutoAsyncByteCompile compiles modified *.el with batch-byte-compile automatically.

If you want to know whether a function call will be replaced by something different in byte-compiled files, you can use ‘M-x apropos’ – for example, ‘M-x apropos mapcar’. One of the results returned will be ‘mapcar’ itself. You’ll see that it has a ‘Plist’ (property list) with an entry ‘byte-compile’. The information stored in that entry is used by the byte-compiler.

For a way to make Emacs byte-compile and load updated `.el’ files automatically , see AutoRecompile.

Emacs and XEmacs

Emacs and XEmacs (GnuEmacs, XEmacs) may barf on byte-compiled files that they didn’t byte-compile themselves. You need to store the compiled files in two different directories, and then you need to add to appropriate directory to your load-path (LoadPath) depending on which emacsen you are running.

Example: Compile files with Emacs and put the .elc files in ~/elisp/compiled-emacs, compile with XEmacs and put the .elc files in ~/elisp/compiled-xemacs, then add to your init file (if you share it):

 (if (featurep 'xemacs)
     (add-to-list 'load-path "~/elisp/compiled-xemacs")
   (add-to-list 'load-path "~/elisp/compiled-emacs"))

You might be wondering how to “put the .elc files in …”. Try redefining byte-compile-dest-file in bytecomp.el.

Discussion

Debian has a pretty elaborate infrastructure for this. Essentially, you have a site_start.el which modifies the load-path depending on what flavor of Emacs you are starting up. – EraEriksson

Hmm… if you do it with load-path, then when you save a . el from emacs, compile it, then run xemacs, you will load an older, incompatible xemacs .elc. 😟

IMHO load, load-library, and require need to be modified to check for .el newer than .elc, even if they are in different directories. (The best solution is to do optional compilation during loading, not after saving.) Unless I am mistaken, this does not happen even in debian. --wayestuncool@yahoo

Discussion on WishList

This was discussion originally on WishList.

Stack traces and compiled files

If you are running code from .elc files and you get an error, the backtrace will show byte-compiled code. You might see strange control codes like:

Debugger entered--Lisp error: (scan-error "Unbalanced parentheses" 1 2)
  scan-lists(1 1 -1)
  down-list(1)
  byte-code("\300\301\302!\210\207" [t down-list 1] 3)
  pp-buffer()
  pp-to-string(t)
  pp(t)
...

In order to get better stack traces and provide useful information to developers, try to reproduce the same error using only the .el file. Then you will see more function calls in place of the strange codes.

TODO: how can you tell Emacs to always prefer loading .el files over loading .elc? I expected a command line flag to do that. – DanielClemente

Bug #2061 (EmacsBugs) was filed about that; thanks.


CategoryCode ComparativeEmacsology