你可以使用 byte-compile 函数对单个函数或宏定义进行字节编译。
使用 byte-compile-file 可以编译整个文件,
使用 byte-recompile-directory 或 batch-byte-compile
可以编译多个文件。
有时,字节编译器会产生警告和/或错误信息
(详情参见see 编译器错误)。这些信息通常
记录在名为 *Compile-Log* 的缓冲区中,
该缓冲区使用编译模式。
See Compilation Mode in The GNU Emacs Manual。
但是,如果变量 byte-compile-debug 非nil,
错误信息会以 Lisp 错误的形式抛出
(see 错误)。
在打算进行字节编译的文件中编写宏调用时要格外小心。
由于宏调用在编译时展开,因此宏必须已经加载到 Emacs 中,
否则字节编译器无法正确处理。
通常的处理方式是使用 require 表达式,
指定包含所需宏定义的文件(参见see 功能)。
一般情况下,字节编译器不会对正在编译的代码求值,
但它会特殊处理 require 表达式,加载指定的库。
为了避免在用户 运行 编译后的程序时加载宏定义文件,
可以在 require 调用外层使用 eval-when-compile
(参见see 编译时求值)。
更多细节参见see 宏与字节编译。
内联(defsubst)函数则问题较少;
如果你在尚未知晓其定义时就编译对该函数的调用,
调用仍然可以正常工作,只是运行速度会慢一些。
该函数对 symbol 的函数定义进行字节编译,
并用编译后的定义替换原有定义。
symbol 的函数定义必须是函数的实际代码;
byte-compile 不处理函数间接引用。
返回值是字节码函数对象,即 symbol 编译后的定义
(see 闭包函数对象)。
(defun factorial (integer)
"Compute factorial of INTEGER."
(if (= 1 integer) 1
(* integer (factorial (1- integer)))))
⇒ factorial
(byte-compile 'factorial) ⇒ #[257 "\211\300U\203^H^@\300\207\211\301^BS!_\207" [1 factorial] 4 "Compute factorial of INTEGER.\n\n(fn INTEGER)"]
如果 symbol 的定义已经是字节码函数对象,
byte-compile 不做任何操作并返回 nil。
它不会再次编译该符号的定义,因为原始
(未编译)代码已经被字节编译代码替换到符号的函数单元中。
byte-compile 的参数也可以是 lambda 表达式。
此时函数返回对应的编译代码,但不会将其保存到任何地方。
该命令读取光标所在的 defun 形式,对其编译,并对结果求值。 如果你对实际是函数定义的 defun 使用该命令, 效果是安装该函数的编译版本。
compile-defun 通常在回显区显示求值结果,
但如果 arg 非nil,它会将结果
插入到当前缓冲区中被编译形式的后面。
该函数将名为 filename 的 Lisp 代码文件编译为 字节码文件。输出文件名通过将后缀 ‘.el’ 改为 ‘.elc’ 得到; 如果 filename 不以 ‘.el’ 结尾, 则在末尾添加 ‘.elc’。
编译过程是每次读取输入文件中的一个形式。 如果是函数或宏定义,则写入编译后的函数或宏定义。 其他形式会被分批处理,然后每一批被编译并写入, 使得编译后的代码在文件被加载时执行。 读取输入文件时所有注释都会被丢弃。
如果没有错误,该命令返回 t,否则返回 nil。
交互调用时,它会提示输入文件名。
$ ls -l push* -rw-r--r-- 1 lewis lewis 791 Oct 5 20:31 push.el
(byte-compile-file "~/emacs/push.el")
⇒ t
$ ls -l push* -rw-r--r-- 1 lewis lewis 791 Oct 5 20:31 push.el -rw-rw-rw- 1 lewis lewis 638 Oct 8 20:25 push.elc
该命令重新编译 directory(或其子目录)中 所有需要重新编译的 ‘.el’ 文件。 如果存在 ‘.elc’ 文件但比对应的 ‘.el’ 文件旧, 则该文件需要重新编译。
当某个 ‘.el’ 文件没有对应的 ‘.elc’ 文件时,
flag 决定如何处理。
如果为 nil,该命令忽略这些文件。
如果为 0,则编译它们。
如果既不是 nil 也不是 0,
则询问用户是否编译每个此类文件,
并对每个子目录也进行询问。
交互使用时,byte-recompile-directory 会提示输入目录,
flag 为前缀参数。
如果 force 非nil,
该命令会重新编译所有存在 ‘.elc’ 文件的 ‘.el’ 文件。
该命令通常不会编译符号链接指向的 ‘.el’ 文件。
如果可选参数 follow-symlinks 非nil,
则符号链接的 ‘.el’ 文件也会被编译。
返回值不可预测。
该函数对命令行指定的文件运行 byte-compile-file。
该函数只能在 Emacs 的批处理执行中使用,
因为它在完成后会退出 Emacs。
某个文件中的错误不会阻止后续文件的处理,
但该文件不会生成输出文件,
且 Emacs 进程会以非零状态码退出。
如果 noforce 非nil,
该函数不会重新编译那些 ‘.elc’ 文件已是最新的文件。
$ emacs -batch -f batch-byte-compile *.el