feat(emacs): add hacky evm (Emacs Version Manager) script for Linux

This commit is contained in:
2022-02-22 19:17:19 +00:00
parent 30f0a7d953
commit 2f62811220
2 changed files with 317 additions and 0 deletions

312
bin/evm Executable file
View File

@@ -0,0 +1,312 @@
#! /usr/bin/env bash
set -e
show-help() {
echo 'usage: evm <command>'
echo ''
echo 'Commands:'
echo ' help - Show this message'
echo ' info - Show evm configuration details.'
echo ' list - List installed versions.'
echo ' use <version> - Activate specified version.'
echo ' install <git-ref> - Download, compile and install Emacs.'
echo ' build-deps - Install build dependencies for Emacs.'
}
main() {
local command="$1"
shift 1
check-os
if [ -z "$command" ]; then
show-help 1>&2
exit 1
fi
case "$command" in
build-deps | deps)
install-deps "$@"
;;
info)
info
;;
install)
install "$@"
;;
use | switch | activate)
activate-version "$@"
;;
list | ls | versions)
versions "$@"
;;
*)
show-help
;;
esac
}
check-os() {
if [[ "$OSTYPE" != "linux"* ]]; then
echo "Only Linux-based operating systems are supported" 1>&2
exit 2
fi
}
check-write-op() {
if conf-root-mode && [ "$UID" != "0" ]; then
echo "ERROR: evm must be run as root when" \
"EVM_MODE is not empty or \"user\"." 1>&2
exit 1
fi
}
trim() {
local string="$*"
string="${string#"${string%%[![:space:]]*}"}"
string="${string%"${string##*[![:space:]]}"}"
echo -n "$string"
}
conf-emacs-src-repo() {
echo "${EVM_EMACS_SRC_REPO:-emacs-mirror/emacs}"
}
conf-mode() {
if [ "${EVM_MODE:-user}" == "user" ]; then
echo "user"
else
echo "root"
fi
}
conf-root-mode() {
if [ "$(conf-mode)" != "root" ]; then
return 1
fi
}
default-root-dir() {
if conf-root-mode; then
echo "/opt/evm"
else
echo "$HOME/.evm"
fi
}
default-shims-dir() {
if conf-root-mode; then
echo "$(conf-root-dir)/bin"
else
echo "$(conf-root-dir)/shims"
fi
}
conf-root-dir() {
echo "${EVM_ROOT_DIR:-$(default-root-dir)}"
}
conf-shims-dir() {
echo "${EVM_VERSIONS_DIR:-$(default-shims-dir)}"
}
conf-versions-dir() {
echo "${EVM_VERSIONS_DIR:-$(conf-root-dir)/versions}"
}
conf-sources-dir() {
echo "${EVM_SOURCES_DIR:-$(conf-root-dir)/sources}"
}
conf-native-full-aot() {
echo "${EVM_NATIVE_FULL_AOT:-1}"
}
info() {
echo "---"
echo "# evm information"
echo "evm:"
echo " mode: $(conf-mode)"
echo " paths:"
echo " root: $(conf-root-dir)"
echo " shims: $(conf-shims-dir)"
echo " versions: $(conf-versions-dir)"
echo " sources: $(conf-sources-dir)"
echo " building:"
echo " native_full_aot: $(conf-native-full-aot)"
}
install() {
local ref="$1"
local version
local workdir
local dir
local file
local prefix
check-write-op
if [ -z "$ref" ]; then
echo "ERROR: git ref to install must be specified" 1>&2
exit 1
fi
version="${ref//\//-}_$(date +"%Y-%m-%d")"
workdir="$(conf-sources-dir)"
prefix="$(conf-versions-dir)/${version}"
file="emacs-${version}.tar.gz"
dir="emacs-${version}"
if [ -d "$prefix" ]; then
echo "target $prefix directory exists, remove to force-install" 1>&2
exit 1
fi
mkdir -p "$workdir"
cd "$workdir"
if [ ! -d "$dir" ]; then
if [ ! -f "$file" ]; then
curl -L "https://github.com/$(conf-emacs-src-repo)/tarball/${ref}" > \
"$file"
else
echo "source tarball ${workdir}/${file} exists, reusing..." 1>&2
fi
mkdir "$dir"
tar -C "$dir" --strip-components 1 -zxf "$file"
else
echo "source directory ${workdir}/${dir} exists, reusing..." 1>&2
fi
cd "$dir"
if [ -f "autogen/copy_autogen" ]; then
./autogen/copy_autogen
fi
if [ -f "autogen.sh" ]; then
./autogen.sh
fi
export CFLAGS="-O2"
export CC=/usr/bin/gcc-10 CXX=/usr/bin/gcc-10
./configure \
--prefix="$prefix" \
--with-json \
--with-modules \
--with-native-compilation \
--with-pgtk \
--with-xinput2 \
--with-xwidgets
make -j "$(nproc)" NATIVE_FULL_AOT="$(conf-native-full-aot)"
make install
}
install-deps() {
sudo apt-get update
sudo apt-get install -y \
build-essential \
g++-10 \
gcc-10 \
libcairo2-dev \
libgccjit-10-dev \
libgccjit0 \
libgconf2-dev \
libgif-dev \
libgnutls28-dev \
libgpm-dev \
libgtk-3-dev \
libharfbuzz-dev \
libjansson-dev \
libjansson4 \
libjpeg-dev \
libjpeg-dev \
libm17n-dev \
libmagick++-dev \
libmagickcore-dev \
libmailutils-dev \
libncurses-dev \
libotf-dev \
libpng-dev \
librsvg2-dev \
libtiff-dev \
libwebp-dev \
libx11-dev \
libxft-dev \
libxml2-dev \
libxpm-dev \
texinfo \
xaw3dg-dev
}
current-version() {
trim "$(cat "$(conf-root-dir)/current" 2> /dev/null)"
}
activate-version() {
local version="$1"
local dir
local target
local base
check-write-op
if [ -z "$version" ]; then
echo "ERROR: version be specified" 1>&2
exit 1
fi
dir="$(conf-versions-dir)/${version}"
if [ ! -d "$dir" ]; then
echo "ERROR: version ${version} is not installed" 1>&2
exit 1
fi
mkdir -p "$(conf-shims-dir)"
# Remove old symlinks.
find "$(conf-shims-dir)" -maxdepth 1 -mindepth 1 -type l -delete
# Create new symlinks.
find "${dir}/bin" -type f -perm -a=x -exec ln -s "{}" "$(conf-shims-dir)/" \;
# Create symlink to `emacs` in case it is a symlink itself.
if [ -L "${dir}/bin/emacs" ]; then
ln -s "${dir}/bin/emacs" "$(conf-shims-dir)/"
fi
echo "$(trim "$version")" > "$(conf-root-dir)/current"
}
versions() {
local version_dirs
local version_dir
local version
version_dirs="$(find "$(conf-versions-dir)" -maxdepth 1 -mindepth 1 -type d \
-exec basename "{}" \;)"
while read -r version_dir; do
version="$(basename "$version_dir")"
if [ "$(trim "$version")" == "$(trim "$(current-version)")" ]; then
echo "* ${version}"
else
echo " ${version}"
fi
done < <(echo "$version_dirs")
}
print-version() {
local version_dir="$1"
local version
version="$(basename "$version_dir")"
if [ "$(trim "$version")" == "$(trim "$(current-version)")" ]; then
echo "* ${version}"
else
echo " ${version}"
fi
}
main "$@"

5
zshenv
View File

@@ -150,6 +150,11 @@ fi
# Use custom emacs install if available
path_prepend "/opt/emacs/bin"
# evm setup.
export EVM_MODE=user
export EVM_NATIVE_FULL_AOT=1
path_prepend "$HOME/.evm/shims"
# Set Emacs-related environment variables
export EMACS="emacs"
export EMACSCLIENT="emacsclient"