本セクションでは、ネイティブコンパイルを制御する変数について解説します。
この変数は、ネイティブコンパイルの最適化レベルを指定します。値は −1 から 3 までの数値である必要があります。0 から 3
の値は、コンパイラの対応するコマンドラインオプション -O0、-O1 などと同等の最適化レベルを指定します。値 −1
はネイティブコンパイルを無効にすることを意味し、関数とファイルはバイトコンパイルのみが行われます。ただし、*.eln ファイルは引き続き生成され、そこにはバイトコード形式のコンパイル済みコードが含まれます。(これは
(declare (speed -1))
形式を使用することで関数単位で実現可能です。declare 形式 を参照してください。)デフォルト値は 2 です。
この変数は、出力されるネイティブコードに使用するセキュリティレベルを指定します。値は0または1の数値とし、それぞれ以下の意味を持ちます。
関数の宣言でその関数が何を行うか、あるいはどのように呼び出されるかが正しく記述されておらず、かつその関数がネイティブコンパイルされている場合、生成されたコードが予期せぬ動作をしたり(最悪の場合、Emacsがクラッシュしたりすることさえあります)。
発行されるコードは、関数の宣言に誤りがある場合でも、安全な方法で生成されなければならない。
これは、safety declare
形式を用いることで、関数レベルでも制御可能です。declare 形式を参照してください。
この変数は、ネイティブコンパイルによって生成されるデバッグ情報のレベルを指定します。その値は0から3までの数値とし、以下の意味を持ちます。
デバッグ出力なし。これがデフォルトです。
ネイティブコードと共にデバッグシンボルを出力します。これにより、gdbなどのデバッガを用いてネイティブコードをより容易にデバッグできるようになります。
1のように、加えて擬似Cコードをダンプする。
2と同様に、さらにGCCの中間パスとlibgccjitログファイルをダンプする。
生成時、擬似Cコードは対応する.elnファイルと同じディレクトリに配置されます。
この変数は、ネイティブコンパイルによって出力されるログメッセージの一部または全部を抑制することで、その出力量を制御します。値がデフォルトの0の場合、すべてのログメッセージが抑制されます。1から3までの値を設定すると、その値を上回るレベルのメッセージがログに出力されます。各値の意味は以下の通りです。
ログ出力なし。これがデフォルトです。
コードの最終的なLIMPLE表現をログに出力してください。
LAP、最終的なLIMPLE、および追加のパス情報をログに記録してください。
最大詳細度:すべてをログに記録。
この変数は、同時に起動されるネイティブコンパイル用サブプロセスの最大数を決定します。値は0以上の数値である必要があります。デフォルト値は0で、これはCPU実行ユニット数の半分を使用することを意味します。ただし、CPUの実行ユニットが1つしかない場合は1となります。
この変数の値が nil
以外の場合、非同期のネイティブコンパイルサブプロセスからの警告やエラーが、メインの Emacs セッション内の *Warnings* という名前のバッファに報告されます。デフォルト値の t は、結果として生成されたバッファを表示することを意味します。*Warnings* バッファを表示せずに警告をログに記録するには、この変数を silent に設定してください。
非同期ネイティブコンパイルで警告が発生する一般的な原因は、必要な機能の require
が一部欠落しているファイルをコンパイルすることです。その機能はメインのEmacsにはロードされているかもしれませんが、ネイティブコンパイルは常にクリーンな環境を持つサブプロセスから開始されるため、サブプロセス側では必ずしもそうとは限りません。
この変数の値が nil 以外の場合、Emacs
は終了時に、まだ実行中の非同期ネイティブコンパイルサブプロセスを終了・強制終了させるかどうかを確認し、これにより対応する .eln ファイルの書き込みを防ぎます。値がデフォルトの nil の場合、Emacs は確認を行わずにこれらのサブプロセスを強制終了します。
変数 native-comp-eln-load-path には、Emacs が *.eln ファイルを検索するディレクトリのリストが格納されています(ライブラリ検索 を参照)。この役割において、この変数は *.el および *.elc ファイルの検索に使用される
load-path
と同等です。また、このリストに含まれるディレクトリは、非同期ネイティブコンパイルによって生成される *.eln ファイルの書き込みにも使用されます。具体的には、Emacs
はこれらのファイルをリスト内の最初の書き込み可能なディレクトリに書き込みます。したがって、この変数の値を変更することで、ネイティブコンパイルが結果を保存する場所を制御できます。
この変数が nil 以外の場合、Emacs がロードする *.elc ファイルのうち、対応する *.eln
ファイルがまだ存在しないものに対して、非同期(別名 ジャストインタイム、または JIT)ネイティブコンパイルが有効になります。この JIT コンパイルでは、native-comp-async-jobs-number の値に応じて、バッチモードで動作する個別の
Emacs サブプロセスが使用されます。Lisp ファイルの JIT コンパイルが正常に完了すると、生成された .eln ファイルがロードされ、そのコードが .elc
ファイルで提供されている関数の定義を置き換えます。
native-comp-jit-compilation の値を nil
に設定すると、JITネイティブコンパイルが無効になります。ただし、JITネイティブコンパイルが無効な場合でも、Emacs は トランポリン
を生成するために、非同期のネイティブコンパイルサブプロセスを起動する必要がある場合があります。これを制御するには、後述する別の変数を使用してください。
この変数はトランポリンの生成を制御します。トランポリンとは、native-comp-speed を
2 以上に設定してネイティブコンパイルされた Lisp コードから、アドバイズまたは再定義された Lisp
プリミティブを呼び出すために必要となる、小さなネイティブコード片のことです。Emacs は生成されたトランポリンを個別の *.eln ファイルに保存します。デフォルトでは、この変数の値は t となっており、これによりトランポリンファイルの生成が有効になります。値を nil
に設定すると、トランポリンの生成が無効になります。なお、プリミティブのアドバイズや再定義に必要なトランポリンが存在せず、生成できない場合、ネイティブコンパイルされた
Lisp からそのプリミティブを呼び出すと、再定義やアドバイズは無視され、あたかも C
から直接プリミティブを呼び出したかのように動作します。したがって、Lisp プログラムに必要なすべてのトランポリンが既にコンパイルされ、Emacs
からアクセス可能であることが分かっている場合を除き、トランポリンの生成を無効にすることは推奨しません。
この変数の値には文字列を指定することもでき、その場合は、native-comp-eln-load-path のディレクトリを上書きして、生成されたトランポリン
*.eln
ファイルを保存するディレクトリ名を指定します。これは、トランポリンを必要に応じて生成したいが、ユーザーの HOME ディレクトリや、*.eln
ファイルが格納されている他の公開ディレクトリに保存したくない場合に便利です。ただし、native-comp-eln-load-path
のディレクトリとは異なり、トランポリンはバージョン固有のサブディレクトリではなく、この変数の値で指定されたディレクトリに保存されます。このディレクトリ名が絶対パスでない場合は、invocation-directory を基準として解釈されます(オペレーティングシステム環境 を参照)。
この変数が nil 以外であり、Emacs
がトランポリンを生成する必要があるものの、それを格納するための書き込み可能なディレクトリが見つからない場合、temporary-file-directory 内に格納されます(一意なファイル名の生成 を参照)。
格納先となる書き込み可能なディレクトリが見つからない場合、あるいはこの変数が文字列である場合に生成されるトランポリンは、現在のEmacsセッション期間中のみ利用可能となります。これは、Emacsがこれらいずれの場所においてもトランポリンを探さないためです。