前章で説明したバイトコンパイルに加え、Emacsではオプションで、Lispの関数定義をネイティブコードと呼ばれる真のコンパイル済みコードにコンパイルすることも可能です。この機能はGCCディストリビューションの一部であるlibgccjitライブラリを使用しており、Emacsがそのライブラリを利用できるようにビルドされている必要があります。また、Lispコードをネイティブコンパイルするには、システム上でGCCおよびBinutils(アセンブラとリンカー)が利用可能である必要があります。
現在のEmacsプロセスがネイティブコンパイルされたLispコードを生成・ロードできるかを確認するには、native-comp-available-pを呼び出します(ネイティブコンパイル関数を参照)。
バイトコンパイルされたコードとは異なり、ネイティブコンパイルされたLispコードはマシンのハードウェアで直接実行されるため、ホストCPUが提供できる最大限の速度で動作します。得られる高速化は一般的にLispコードの処理内容によって異なりますが、通常は対応するバイトコンパイル済みコードよりも2.5倍から5倍高速です。
ネイティブコードは一般にシステム間で互換性がないため、ネイティブコンパイルされたコードをあるマシンから別のマシンへ移植することはできません。利用できるのは、それが生成された同一マシン、あるいは非常に類似したマシン(同一のCPUおよびランタイムライブラリを搭載しているマシン)に限られます。ネイティブコンパイルされたコードの移植性は、共有ライブラリ(.soまたは.dllファイル)のそれと同様です。
ネイティブコンパイルされたコードのライブラリには、Emacs Lispのプリミティブ(関数とは何か?を参照)とその呼び出し規約に関する重要な依存関係が含まれています。そのため、通常、Emacsはそれより前の、あるいは後のバージョンのEmacsで生成されたネイティブコンパイル済みコードをロードしません。異なるバージョンのEmacsで同じLispコードをネイティブコンパイルすると、通常、そのバージョンのEmacsのみがロード可能な一意のファイル名を持つネイティブコンパイル済みライブラリが生成されます。しかし、一意のファイル名を使用することで、複数の異なるバージョンのEmacsでネイティブコンパイルされた同一のLispライブラリの複数のバージョンを、同じディレクトリ内に配置することが可能になります。
nil 以外のファイルローカル変数バインディングである no-byte-compile(バイトコンパイル
を参照)も、そのファイルのネイティブコンパイルを無効にします。さらに、同様の変数 no-native-compile は、そのファイルのネイティブコンパイルのみを無効にします。no-byte-compile と no-native-compile の両方が指定されている場合は、前者が優先されます。
ネイティブコンパイルの結果である *.eln ファイルを user-emacs-directory
のサブディレクトリに書き出さないようにする必要がある場合があります(Init ファイル を参照)。これは、native-comp-eln-load-path の値を変更するか(ネイティブコンパイル変数 を参照)、あるいは
HOME
環境変数を一時的に存在しないディレクトリに向けることで実現できます。なお、後者の手法でも、Emacs が トランポリン を生成する必要がある場合には、少数の *.eln
ファイルが生成される可能性があることに注意してください。トランポリンは、ネイティブコンパイル対象の Lisp コード内で Lisp
プリミティブが助言または再定義された際に使用されます。トランポリン を参照してください。あるいは、startup-redirect-eln-cache 関数を使用して、*.eln ファイルをデフォルト以外のディレクトリに書き出すよう指定することもできます。ネイティブコンパイル関数
を参照してください。