Braindump

Ubuntu 18.04.5 で Gcc Emacs をビルドする

August 5, 2021
emacs

ゴールは native compilation 機能を備えた Emacs,通称 Gcc Emacs を使えるようにすること.Gcc Emacs に関してはこちらの素晴らしい記事を参照されたい.

ビルドは Emacs Wiki の Gcc Emacs のページをよく読めばいいが,OS 毎の成功事例は多いに越したことはないと思うので,Ubuntu 18.04.5 におけるビルド手順をまとめておく.

tl;dr #

実行手順は以下のとおり

  • ビルドに必要なパッケージを入れる

  • ビルド

    $ git clone --single-branch --depth=1 https://github.com/emacs-mirror/emacs.git
    $ cd emacs/
    $ ./autogen.sh
    $ ./configure --with-json --with-modules --with-harfbuzz --with-compress-install \
      --with-threads --with-included-regex --with-zlib --with-cairo \
      --without-rsvg --without-sound --without-toolkit-scroll-bars \
      --without-gpm --without-dbus --without-pop \
      --without-mailutils --without-gsettings --without-x \
      --with-native-compilation \
      --prefix=$HOME/src/emacs-builds/
    $ make -j(nproc)
    $ make install
    

環境 #

  • Ubuntu 18.04.5 LTS
  • Emacs 28.0.50

準備 #

ビルド時の make コマンドは実行時間が長い.私の環境 (Intel Core i9-9980XE) では10分程度掛かった.スペックに依っては20-30分掛かる場合もある.

ビルドに失敗して実行を繰り返すのは辛いので,以降の準備を確認しながら着実に行うのが望ましい.

パッケージ関連 #

ビルドに必要なパッケージをインストールする.同じ OS でうまく行っている こちら を参考にした.

$ sudo add-apt-repository -y ppa:ubuntu-toolchain-r/ppa
$ sudo apt install -y autoconf make checkinstall texinfo libxpm-dev libjpeg-dev \
  libgif-dev libtiff-dev libpng-dev libgnutls28-dev libncurses5-dev \
  libjansson-dev libharfbuzz-dev libgccjit-11-dev gcc-11 g++-11

$ sudo apt update
$ sudo apt -y upgrade

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 11
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 11

ログの中にエラーが無いことを確認してから次に進む.

ビルド関連 #

Emacs のビルドが初めての場合はビルドに必要なソースコードをクローンしてくる.2回目以降の場合は git pull で最新版を落としてくれば良い.

$ git clone --single-branch --depth=1 https://github.com/emacs-mirror/emacs.git

以降の作業は落としてきたリポジトリ内で行う.

初回は次を実行して configure スクリプトを作る.

$ ./autogen.sh

./configure を実行する.native compile のためのオプション --with-native-compilation は忘れずに付ける.それ以外のオプションは環境に応じてセットする.

$ ./configure --with-json --with-modules --with-harfbuzz --with-compress-install \
  --with-threads --with-included-regex --with-zlib --with-cairo \
  --without-rsvg --without-sound --without-toolkit-scroll-bars \
  --without-gpm --without-dbus --without-pop \
  --without-mailutils --without-gsettings --without-x \
  --with-native-compilation \
  --prefix=$HOME/src/emacs-builds/

()
Does Emacs have threading support in lisp?              yes
Does Emacs support the portable dumper?                 yes
Does Emacs support legacy unexec dumping?               no
Which dumping strategy does Emacs use?                  pdumper
Does Emacs have native lisp compiler?                   yes
()

環境に依っては後々 sudo 権限が必要になる.私の環境では Emacs の立ち上げ時に毎回 sudo を付与する必要があり面倒だった.これを回避するにはオプション --prefix で展開先をローカルにセットすれば良い.

ログをよく見て,パッケージが無い系のエラーが出ていればパスの設定を見直す. Does Emacs have native lisp compiler?yes になっていれば取り敢えずは目標のビルドができるはず.

ビルド & インストール #

make する.

$ make NATIVE_FULL_AOT=1 -j(nproc)

NATIVE_FULL_AOT=1 を付けることでビルド時に Emacs のビルトインパッケージを native compile してくれる.付けなければ Emacs の初回起動時に compile が行われる.

-j(nproc) オプションを付けると全力でCPUを使用して高速に処理が行われる.他に作業をしていないのであれば付けたほうが良い.

ビルドが完了したらインストールする.

$ make install

最後に,ビルドした Emacs がデフォルトで使われるようにシンボリックリンクを貼る. ./configure 実行時にインストール先を指定していれば実行ファイルはその中の bin ディレクトリにある.

$ ln -s ~/src/emacs-builds/bin/emacs /usr/local/bin/emacs
$ ln -s ~/src/emacs-builds/bin/emacsclient /usr/local/bin/emacsclient

確認 #

native compile 機能が使えるかどうかは以下を評価することで分かる.

(describe-variable 'system-configuration-features)

NATIVE_COMP の文字があれば目標のビルドは達成できている.

system-configuration-features is a variable defined in 'C source code'.

Its value is
"GMP GNUTLS JSON LCMS2 LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER SECCOMP THREADS XIM ZLIB"

  Probably introduced at or before Emacs version 25.1.

String listing some of the main features this Emacs was compiled with.
An element of the form "FOO" generally means that HAVE_FOO was
defined during the build.

This is mainly intended for diagnostic purposes in bug reports.
Don't rely on it for testing whether a feature you want to use is available.

native compile のテストはこちらの記事が参考になる.

起動時に表示されるワーニングがうるさい場合は こちら の記事に従って下記の行を init.el の序盤に記述する.

(custom-set-variables '(warning-suppress-types '((comp))))