How I Build Emacs From Source on Debian
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 thewebkit
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: