Last active
December 8, 2024 00:30
-
-
Save abougouffa/4bcccc6d7dc34cf52e2877ca34445bc3 to your computer and use it in GitHub Desktop.
A helper script to build Emacs from source on Debian/Ubuntu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# -*- sh-basic-offset: 2; tab-width: 2; -*- | |
# set -x | |
# Initially based on the emacs-git AUR package | |
## Build options | |
USE_CLANG= # Use Clang instead of GCC. | |
LINK_TIME_OPTIMIZATION="YES" # Enable link-time optimization. | |
AOT_ELISP= # Compile all elisp files provided by upstream. | |
MAKE_TRAMPOLINES= # Compile jitted Elisp files with trampolines. | |
ALSA= # Linux sound support. | |
MAKE_DOCS_HTML= # Generate and install html documentation. | |
MAKE_DOCS_PDF= # Generate and install pdf documentation. You need a TeX installation. | |
EMACS_BRANCH="emacs-30" # Emacs' branch to be built. | |
UI="GTK3" # GTK3, PGTK, LUCID | |
XWIDGETS= # XWidgets support | |
PERFORMANCE_TWEAKS="YES" # Apply some performance related tweaks | |
# =================================================================== | |
emacs_system_make_depends=( | |
'git' | |
'gcc' | |
'autoconf' | |
) | |
# Maybe not complete list | |
debian_system_depends=( | |
'libgnutls28-dev' 'libxml2-dev' 'libharfbuzz-dev' 'texinfo' 'libxi-dev' | |
'libjpeg-dev' 'libpng-dev' 'giflib-tools' 'libgif-dev' 'libwebp-dev' 'libtiff-dev' 'libxpm-dev' | |
'libjansson-dev' # Native JSON support for Emacs 29, not needed for 30+ | |
'libgccjit-12-dev' # Native compile (28+) | |
'tree-sitter-dev' # Treesitter (29+) | |
'libsqlite3-dev' # SQLite | |
'libgpm-dev' # GPM | |
'libcairo2-dev' # Cairo | |
) | |
src_dir=$PWD/emacs | |
# =================================================================== | |
if [[ "${USE_CLANG}" == "YES" ]]; then | |
export CC="/usr/bin/clang" | |
export CXX="/usr/bin/clang++" | |
export CPP="/usr/bin/clang -E" | |
export LD="/usr/bin/lld" | |
export AR="/usr/bin/llvm-ar" | |
export AS="/usr/bin/llvm-as" | |
export CCFLAGS+=' -fuse-ld=lld' | |
export CXXFLAGS+=' -fuse-ld=lld' | |
system_make_depends+=('clang' 'lld' 'llvm') | |
fi | |
if [[ "${UI}" == "LUCID" ]]; then | |
system_depends+=('dbus' 'hicolor-icon-theme' 'libxinerama-dev' 'libxfixes-dev' 'librsvg2-dev' 'xaw3dg-dev' 'libxrandr-dev' 'libxi-dev' 'libsm-dev' 'xcb' 'libxcb1-dev') | |
system_make_depends+=('x11proto-dev') | |
elif [[ "${UI}" == "GTK3" ]]; then | |
system_depends+=('libgtk-3-dev' 'libsm-dev' 'xcb' 'libxcb1-dev') | |
system_make_depends+=('x11proto-dev' 'libxi-dev') | |
elif [[ "${UI}" == "PGTK" ]]; then | |
system_depends+=('libgtk-3-dev' 'libsm-dev' 'xcb' 'libxcb1-dev') | |
system_make_depends+=('x11proto-dev' 'libxi-dev') | |
fi | |
if [[ "${XWIDGETS}" == "YES" ]]; then | |
system_make_depends+=('libwebkit2gtk-4.0-dev') | |
fi | |
if [[ "${ALSA}" == "YES" ]]; then | |
system_depends+=('alsa-lib') | |
fi | |
if [[ "${MAKE_DOCS_PDF}" == "YES" ]] && [[ ! -d '/usr/local/texlive' ]]; then | |
system_make_depends+=('texlive-core') | |
fi | |
emacs-install-dependencies() { | |
apt install "${debian_system_depends[@]}" "${emacs_system_make_depends[@]}" | |
} | |
proxy-enable() { | |
if ping -c3 -W2 1.1.1.1 | grep -q "0 received"; then | |
echo "Cannot ping WAN, setting proxies" | |
export https_proxy=http://SOME_LOCAL_PROXY:8080/ | |
export http_proxy=http://SOME_LOCAL_PROXY:8080/ | |
export ftp_proxy=http://SOME_LOCAL_PROXY:8080/ | |
export no_proxy=localhost,127.0.0.1,.local,.SOME_LOCAL_TLD | |
fi | |
} | |
# There is no need to run autogen.sh after first checkout. | |
# Doing so, breaks incremental compilation. | |
emacs-prepare() { | |
# proxy-enable | |
if [[ ! -d "${src_dir}" ]]; then | |
git clone https://github.com/emacs-mirror/emacs.git "${src_dir}" -b "${EMACS_BRANCH}" | |
else | |
cd "${src_dir}" || exit 1 | |
git stash --include-untracked | |
git pull origin | |
git checkout "${EMACS_BRANCH}" | |
fi | |
[[ -d "${src_dir}/build" ]] && rm -rf "${src_dir}/build" | |
[[ -x configure ]] || (./autogen.sh git && ./autogen.sh autoconf) | |
mkdir -p "${src_dir}/build" | |
} | |
emacs-check() { | |
cd "${src_dir}/build" || exit 1 | |
make check | |
} | |
emacs-build() { | |
cd "${src_dir}/build" || exit 1 | |
if [[ "${PERFORMANCE_TWEAKS}" == "YES" ]]; then | |
# This disables the GC mark trace buffer for about 5% better garbage collection performance | |
config_options+=('--disable-gc-mark-trace') | |
# Better compilation optimization | |
export CFLAGS+="-O2 -pipe -march=native -mtune=native -fomit-frame-pointer" | |
fi | |
local config_options=( | |
--prefix="$HOME/.local" | |
--sysconfdir=/etc | |
--libexecdir="$HOME/.local/lib" | |
--localstatedir="$HOME/.local/var" | |
--mandir="$HOME/.local/share/man" | |
--with-gnutls=ifavailable | |
--with-tree-sitter=ifavailable | |
--with-native-compilation # No need for this on Emacs 30, it is the default if libgccjit is available | |
--with-xinput2 | |
--without-compress-install | |
--with-modules | |
--without-libotf | |
--without-m17n-flt | |
# Beware https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25228 | |
# dconf and gconf break font settings you set in ~/.emacs. | |
# If you insist you'll need to read that bug report in *full*. | |
# Good luck! | |
--without-gconf | |
# ctags/etags may be provided by other packages, e.g, universal-ctags | |
--program-transform-name='s/\([ec]tags\)/\1.emacs/' | |
) | |
if [[ "${USE_CLANG}" == "YES" ]]; then | |
config_options+=('--enable-autodepend') | |
fi | |
if [[ "${LINK_TIME_OPTIMIZATION}" == "YES" ]]; then | |
config_options+=('--enable-link-time-optimization') | |
fi | |
if [[ "${AOT_ELISP}" == "YES" ]]; then | |
config_options+=('--with-native-compilation=aot') | |
fi | |
if [[ "${UI}" == "LUCID" ]]; then | |
config_options+=('--with-x-toolkit=lucid' '--with-xft' '--with-xaw3d' '--without-cairo') | |
elif [[ "${UI}" == "GTK3" ]]; then | |
config_options+=('--with-x-toolkit=gtk3' '--without-xaw3d') | |
elif [[ "${UI}" == "PGTK" ]]; then | |
config_options+=('--with-pgtk' '--without-xaw3d' '--without-gsettings') | |
fi | |
if [[ "${XWIDGETS}" == "YES" ]]; then | |
config_options+=('--with-xwidgets') | |
fi | |
if [[ "${ALSA}" == "YES" ]]; then | |
config_options+=('--with-sound=alsa') | |
else | |
config_options+=('--with-sound=no') | |
fi | |
# =================================================================== | |
../configure "${config_options[@]}" | |
make bootstrap | |
# ------------------------------------------------------------------- | |
# Or use "make" rather than "make bootstrap": | |
# > make | |
# Using "make" instead of "make bootstrap" enables incremental | |
# compiling. Less time recompiling. Yay! But you may | |
# need to use bootstrap sometimes to unbreak the build. | |
# Just add it to the command line. | |
# | |
# Please note that incremental compilation implies that you | |
# are reusing your src directory! | |
# | |
# You may need to run this if 'loaddefs.el' files become corrupt. | |
# cd "${src_dir}/lisp" | |
# make autoloads | |
# cd ../build | |
# ------------------------------------------------------------------- | |
if [[ "${MAKE_TRAMPOLINES}" == "YES" ]]; then | |
make trampolines | |
fi | |
# Optional documentation formats. | |
if [[ "${MAKE_DOCS_HTML}" == "YES" ]]; then | |
make html | |
fi | |
if [[ "${MAKE_DOCS_PDF}" == "YES" ]]; then | |
make pdf | |
fi | |
} | |
emacs-install() { | |
cd "${src_dir}/build" || exit 1 | |
make PREFIX="${HOME}/.local/" install | |
# Install Emacs terminal command | |
if [[ ! -f "${HOME}/.local/bin/nemacs" ]]; then | |
printf '#!/usr/bin/bash -e\n\n[[ -x $HOME/.local/bin/emacs ]] && $HOME/.local/bin/emacs -nw $*' >"${HOME}/.local/bin/nemacs" | |
chmod a+x "${HOME}/.local/bin/nemacs" | |
fi | |
# Install optional documentation formats | |
if [[ $MAKE_DOCS_HTML == "YES" ]]; then make PREFIX="${HOME}/.local/" install-html; fi | |
if [[ $MAKE_DOCS_PDF == "YES" ]]; then make PREFIX="${HOME}/.local/" install-pdf; fi | |
} | |
emacs-build-and-install() { | |
echo "Preparing the build" | |
emacs-prepare | |
echo "Building Emacs" | |
emacs-build | |
echo "Installing Emacs" | |
emacs-install | |
} | |
emacs-build-and-install |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment