UP | HOME

Updating Emacs with bash functions
#emacs#bash

Table of Contents

Sometimes it's nice to have the latest Emacs features but it's also good to have a stable build ready to fall back on in case of emergency. This bash function updates multiple versions of emacs at once. Use it like update-emacs 28-gcc 27 in order to update the native-compilation build of emacs-28 and the latest emacs-27 build.

Variables

Add these to your .bash_aliases or .zshrc file:

export EMACS_SRC=~/src/emacs
export EMACS_BINS=~/bin
export EMACS_VERSIONS=("master" "28-gcc" "stable" "27" "all")

EMACS_SRC is the path to the emacs git repository. EMACS_BINS is the output directory to place emacs binary files. Each version of emacs will be a subfolder in the EMACS_BINS folder. EMACS_VERSIONS is a list of versions that can be built.

Load these variables by running the command . ~/.bashrc for bash or . ~/.zshrc for zsh.

System setup

Clone the repository and add branches

Clone the Emacs repository into the EMACS_SRC folder:

git clone --depth 1 git://git.sv.gnu.org/emacs.git $EMACS_SRC

Next, add the branches you would like to build from and perform a shallow fetch:

cd $EMACS_SRC
git remote set-branches origin 'emacs-27' 'emacs-28' 'master'
git fetch --depth 1

Install required software

Debian/Ubuntu

sudo apt install -y \
     autoconf \
     gcc-10 g++-10 \
     libgccjit0 libgccjit-10-dev \
     libjansson4 libjansson-dev \
     libwebkit2gtk-4.0-dev \
     libgnutls28-dev \
     libncurses-dev \
     libxpm-dev \
     libjpeg62-turbo-dev \
     libgif-dev libtiff5-dev \
     librsvg2-dev \
     libgpm-dev \
     libm17n-dev \
     libsystemd-dev \
     libotf-dev \
     libtiff5-dev \
     libxcb-xinput-dev \
     texinfo;

Fedora

sudo dnf install \
     autoconf \
     gnutls-devel \
     ncurses-devel \
     libXpm-devel \
     libjpeg-turbo-devel \
     giflib-devel \
     gcc libgccjit \
     jansson-devel \
     webkit2gtk3-devel \
     librsvg2-devel \
     gpm-devel \
     m17n-lib-devel \
     systemd-devel \
     xinput \
     texinfo;

Update Emacs function

Add this function to your ~/.bash_aliases or ~/.zshrc file:

function update-emacs() {
    if [[ ! " $EMACS_VERSIONS[*] " =~ " $1 " ]]; then
        echo "Usage: $0 <$EMACS_VERSIONS>";
        return 1;
    fi

    cur_dir=$(pwd)

    cd $EMACS_SRC;

    if [[ " master all " =~ " $1 " ]]; then
        echo "Building emacs master. Press return to continue...";
        [[ $YES ]] || read;
        git checkout master;
        git pull --ff-only;
        make extraclean;
        ./autogen.sh;
        ./configure \
            --prefix=$EMACS_BINS/emacs-master \
            --with-mailutils \
            --with-native-compilation\
            --with-json \
            --with-xwidgets \
            --with-xinput2 \
            CFLAGS="-O2 -pipe -march=native -fomit-frame-pointer";
        echo "Check configuration output for emacs MASTER then press return to continue...";
        [[ $YES ]] || read;
        make -j $(nproc);
        make install;
        echo "Finished building emacs master";
    fi
    if [[ " 28-gcc all " =~ " $1 " ]]; then
        echo "Building emacs 28-gcc. Press return to continue...";
        [[ $YES ]] || read;
        git checkout emacs-28;
        git pull --ff-only;
        make extraclean;
        ./autogen.sh;
        ./configure \
            --prefix=$EMACS_BINS/emacs-28-gcc \
            --with-mailutils \
            --with-native-compilation \
            --with-json \
            --with-xwidgets \
            CFLAGS="-O2 -pipe -march=native -fomit-frame-pointer";
        echo "Check configuration output for emacs 28-GCC then press return to continue...";
        [[ $YES ]] || read;
        make -j $(nproc);
        make install;
        echo "Finished building emacs 28-gcc";
    fi
    if [[ " stable all " =~ " $1 " ]]; then
        echo "Building emacs stable. Press return to continue...";
        [[ $YES ]] || read;
        git checkout emacs-28;
        git pull --ff-only;
        make extraclean;
        ./autogen.sh;
        ./configure \
            --prefix=$EMACS_BINS/emacs-stable \
            --with-mailutils \
            --with-json \
            --with-xwidgets \
            CFLAGS="-O2 -pipe -fomit-frame-pointer";
        echo "Check configuration output for emacs STABLE then press return to continue...";
        [[ $YES ]] || read;
        make -j $(nproc);
        make install;
        echo "Finished building emacs stable";
    fi
    if [[ " 27 all " =~ " $1 " ]]; then
        echo "Building emacs 27. Press return to continue...";
        [[ $YES ]] || read;
        git checkout emacs-27;
        git pull --ff-only;
        make extraclean;
        ./autogen.sh;
        ./configure \
            --prefix=$EMACS_BINS/emacs-27 \
            --with-mailutils \
            --with-json \
            --with-xwidgets \
            CFLAGS="-O2 -pipe -fomit-frame-pointer";
        echo "Check configuration output for emacs 27 then press return to continue...";
        [[ $YES ]] || read;
        make -j $(nproc);
        make install;
        echo "Finished building emacs 27";
    fi

    cd $cur_dir;
}

To make this function available in the terminal, either kill the current session and start a new one or run . ~/.bashrc for bash or . ~/.zshrc for zsh.

Use this function to build each version of emacs. To update all versions without any prompts, use YES=t update-emacs all.