日本時間の2021年4月26日午前3時6分、Emacsのmasterブランチにfeature/native-compブランチがマージされました(コミット:Merge branch ‘feature/native-comp’ into into trunk)。これにより、HEADのEmacsをビルドすると、Native compilation機能を兼ね備えたネイティブコンパイルEmacs、通称Gcc Emacsが使えるようになりました。
ネイティブコンパイルEmacsの機能 # ネイティブコンパイルEmacs(以下、Gcc Emacsと呼びます)は、Andrea Corallo、Luca Nassi、Nicola Mancaの3名によるBringing GNU Emacs to Native Code
という論文で詳細が説明されています。
簡単に説明すると、これまでのEmacsは、Elispの読み込みを早くするため*.elファイルをバイトコンパイルして*.elcというバイトコードファイルを作成して読み込んでいましたが、Gcc Emacsでは*.elファイルをGCCを使ってコンパイル(これの工程をバイトコンパイルに対してネイティブコンパイルと呼んでいます)して*.elnというバイナリファイルを作成して読み込むことで、バイトコードと比べて2.3倍から42倍ほど高速化させたという話です。
ネイティブコンパイルされたElispファイルをEmacsで開いてみると、上図のようにバイナリファイルになっていることがわかります。
Emacsが早くなるという話であれば、飛び付かないわけにはいきません。そこで、早速試しにビルドしてみました。
macOSにおけるGcc Emacsのビルド # それでは、macOSでGcc Emacsをビルドしてみたいと思います。まずは、必要なライブラリをインストールしてビルド環境を整えましょう。
Windows on WSLの人はEmacsに来たnative compileを試す - ぐるっとぐりっどの記事を参考にしてみてください。
GCCでlibgccjitを使用する # Gcc EmacsはGCCとEmacsとのインターフェイスにlibgccjitを利用しています。そのため、Gcc Emacsをビルドするにはlibgccjitのインストールが必要です。僕はHomebrewでインストールしました。
$ brew install libgccjit libgccjitをインストールしたら、libgccjitを利用したコードをビルドできるか確認してみましょう。
Tutorial part 1: “Hello world”に書かれている通りにコードをビルドしてみます。
$ touch tut01-hello-world.c $ pbpaste > tut01-hello-world.c # ブラウザでコピーして、pbpasteでファイルに書き込む $ gcc tut01-hello-world.c -o tut01-hello-world -lgccjit ld: library not found for -lgccjit clang: error: linker command failed with exit code 1 (use -v to see invocation) 僕の環境では、libgccjitのライブラリが見つけられず、上記のエラーが表示されてしまいました。