Harry R. Schwartz

Code writer, sometime Internet enthusiast, attractive nuisance.

Vancouver

British Columbia

Canada

vegan


How I Build Emacs From Source on Debian

hrs

Published .
Tags: emacs, unix.

I recompile Emacs from source every few months to play with the latest bugs features, which is just enough time for me to forget how to do it. I’ve had a how-to guide I wrote for myself sitting on my hard drive forever, and only today realized that I could just clean it up and publish it. It’s clearly been a while since I’ve blogged.

These instructions provide me with a build capable of doing all kinds of fun things:

  • Native JSON serialization for faster communication with e.g. LSP,
  • native JIT compilation of Emacs Lisp code for better all-around performance,
  • viewing and dynamically resizing images in Emacs with imagemagick,
  • incrementally parsing code with tree-sitter, and even
  • opening xwidgets (including the webkit browser!) in Emacs buffers.

Note, of course, that the latest version of Emacs isn’t necessarily stable! You’re likely to run into the occasional bug, and you might need to revert to earlier versions. If you’re not interested in putting up with that sort of nonsense, you might want to stick with, say, the package from the testing branch from apt, which usually isn’t too far behind.

Note also that I’m still using regular ol’ X Windows, not Wayland. If you’re compiling for Wayland, I believe you’ll need to configure the build with the --with-pgtk flag, but don’t quote me on that.

Fetch the code

First, clone the repository locally from the official GNU repo.

$ git clone git://git.savannah.gnu.org/emacs.git

Personally, I like having the whole repository available so I can pull new changes, browse commit history, and revert to previous versions, but it’s kinda big (around 600 MB), so if you only want the most recent changes you can save a bit of space by instead running:

$ git clone --depth=1 git://git.savannah.gnu.org/emacs.git

Install the required dependencies

These are necessary for the basic installation, so you’ll want them all.

$ sudo apt install \
  build-essential \
  libgtk-3-dev \
  libgnutls28-dev \
  libtiff5-dev \
  libgif-dev \
  libjpeg-dev \
  libpng-dev \
  libxpm-dev \
  libncurses-dev \
  texinfo

Native JSON support

Emacs implemented native JSON serialization using the jansson library back in 27.1. Since LSP communicates through JSON, that native serialization significantly speeds up LSP interaction! You’ll probably want that.

$ sudo apt install libjansson4 libjansson-dev

Native JIT compilation support

Version 28 of Emacs added a native JIT compiler for Emacs Lisp, which relies on the libgccjit library. Machine code can be something like 2–5 times faster, so I’d definitely recommend this.

However, be warned: the first time you run your new version of Emacs it’ll byte-compile all your installed packages, aggressively popping open all kinds of compilation buffers and deprecation warnings and generally making an ass of itself. Once it’s finished, though, I think the performance improvement is worth it.

$ sudo apt install \
  libgccjit0 \
  libgccjit-10-dev \
  gcc-10 \
  g++-10

Dynamic image resizing

I regularly view images in Emacs, whether that’s opening a photo through dired or viewing an image inline in an Org document. That often involves implicitly resizing the images to fit the buffer, and Emacs uses imagemagick under the hood to accomplish that.

$ sudo apt install libmagickcore-dev libmagick++-dev

Incremental parsing

The tree-sitter library is a general-purpose parsing system supporting incremental parsing and error recovery. Once all the major modes use it we’ll have a much more robust mechanism for syntax highlighting, code navigation, and refactoring.

Not all major modes do use it yet, but quite a few do and more will in the future, so it’s a nice thing to have available.

$ sudo apt install libtree-sitter-dev

Build and install

Once all the dependencies are installed we’ll cd into the directory and build everything.

The configuration flags set here should provide you with the features listed above, but you can also check out the other available flags with ./configure --help.

The make step might take a while, especially the first time. The --jobs=$(nproc) flag tells it to build in parallel on all available cores. You can also set a specific number (like --jobs=2) or omit it entirely if you’d prefer.

$ cd emacs
$ export CC=/usr/bin/gcc-10 CXX=/usr/bin/gcc-10
$ ./autogen.sh
$ ./configure \
    --with-native-compilation \
    --with-json \
    --with-tree-sitter \
    --with-imagemagick \
    --with-xwidgets
$ make --jobs=$(nproc)
$ sudo make install

Congratulations! You should now have the latest (and, presumably, greatest) version of Emacs installed, probably at /usr/local/bin/emacs. Happy hacking!


You might like these textually similar articles: