#!/usr/bin/env bash ## Author: Abidán Brito ## This script builds GNU Emacs 29 with support for native elisp compilation, ## libjansson (C JSON library), pure GTK and mailutils. # Exit on error and print out commands before executing them. set -euxo pipefail # Let's set the number of jobs to something reasonable; keep 2 cores # free to avoid choking the computer during compilation. JOBS=`nproc --ignore=2` # Clone repo locally and get into it. git clone --depth 1 --branch emacs-29 git://git.savannah.gnu.org/emacs.git pushd emacs # Get essential dependencies. sudo apt install -y build-essential \ texinfo \ libgnutls28-dev \ libjpeg-dev \ libpng-dev \ libtiff5-dev \ libgif-dev \ libxpm-dev \ libncurses-dev \ #libncurses5-dev \ libgtk-3-dev \ libtree-sitter-dev \ libmagick++-dev \ #libwebkit2gtk-4.0-dev \ # Get dependencies for gcc-10 and the build process. sudo apt update -y sudo apt install -y gcc-10 \ g++-10 \ libgccjit0 \ libgccjit-10-dev \ autoconf \ # Get dependencies for fast JSON. sudo apt install -y libjansson4 libjansson-dev # Get GNU Mailutils (protocol-independent mail framework). sudo apt install -y mailutils # Enable source packages and get dependencies for whatever # Emacs version Ubuntu supports by default. # # Taken from here: # https://www.masteringemacs.org/article/speed-up-emacs-libjansson-native-elisp-compilation #sudo sed -i 's/# deb-src/deb-src/' /etc/apt/sources.list \ # && apt update \ # && apt build-dep -y emacs # Stop debconf from complaining about postfix nonsense. DEBIAN_FRONTEND=noninteractive # Needed for compiling libgccjit or we'll get cryptic error messages. export CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 # Configure and run. # # Compiler flags: # -O2 -> Turn on a bunch of optimization flags. There's also -O3, but it increases # the instruction cache footprint, which may end up reducing performance. # -pipe -> Reduce temporary files to the minimum. # -mtune=native -> Optimize code for the local machine (under ISA constraints). # -march=native -> Enable all instruction subsets supported by the local machine. # -fomit-frame-pointer -> Small functions don't need a frame pointer (optimization). # https://lemire.me/blog/2018/07/25/it-is-more-complicated-than-i-thought-mtune-march-in-gcc/ # # NOTE(abi): binaries should go to /usr/local/bin by default. ./autogen.sh \ && ./configure \ --with-native-compilation \ # use the libgccjit native compiler --with-pgtk \ # better font rendering --with-x-toolkit=gtk3 \ # widgets toolkit --with-tree-sitter \ # syntax parsing --with-wide-int \ # larger file size limit --with-json \ # fast JSON --with-gnutls \ # TLS/SSL --with-mailutils \ # e-mail --without-pop \ # no pop3 (insecure channels) --with-cairo \ # vector graphics backend --with-imagemagick \ # raster images backend CFLAGS="-O2 -pipe -mtune=native -march=native -fomit-frame-pointer" # Other interesting compilation options: # #--prefix="" # output binaries location #--with-x-toolkit=lucid # supposedly more stable #--with-xwidgets #--with-modules #--without-dbus # Build. # # NOTE(abi): NATIVE_FULL_AOT=1 ensures native compilation ahead-of-time for all # elisp files included in the distribution. make -j${JOBS} NATIVE_FULL_AOT=1 \ && sudo make install # Return to the original path. popd