Álvaro Ramírez
Trying out gccemacs on macOS
Been wanting to try Andrea Corallo's gccemacs. Followed Allen Dang's handy instructions to build it on macOS.
Though not had much of a chance to play with the new install, here's what I did to get up and running…
Install gcc and libgccjit via homebrew
brew install gcc libgccjit
Save configure script
Create configure-gccemacs.sh
#!/bin/bash set -o nounset set -o errexit # Configures Emacs for building native comp support # http://akrl.sdf.org/gccemacs.html readonly GCC_DIR="$(realpath $(brew --prefix libgccjit))" [[ -d $GCC_DIR ]] || { echo "${GCC_DIR} not found"; exit 1; } readonly SED_DIR="$(realpath $(brew --prefix gnu-sed))" [[ -d $SED_DIR ]] || { echo "${SED_DIR} not found"; exit 1; } readonly GCC_INCLUDE_DIR=${GCC_DIR}/include [[ -d $GCC_INCLUDE_DIR ]] || { echo "${GCC_INCLUDE_DIR} not found"; exit 1; } readonly GCC_LIB_DIR=${GCC_DIR}/lib/gcc/10 [[ -d $GCC_LIB_DIR ]] || { echo "${GCC_LIB_DIR} not found"; exit 1; } export PATH="${SED_DIR}/libexec/gnubin:${PATH}" export CFLAGS="-O2 -I${GCC_INCLUDE_DIR}" export LDFLAGS="-L${GCC_LIB_DIR} -I${GCC_INCLUDE_DIR}" export LD_LIBRARY_PATH="${GCC_LIB_DIR}" export DYLD_FALLBACK_LIBRARY_PATH="${GCC_LIB_DIR}" echo "Environment" echo "-----------" echo PATH: $PATH echo CFLAGS: $CFLAGS echo LDFLAGS: $LDFLAGS echo DYLD_FALLBACK_LIBRARY_PATH: $DYLD_FALLBACK_LIBRARY_PATH echo "-----------" ./autogen.sh ./configure \ --prefix="$PWD/nextstep/Emacs.app/Contents/MacOS" \ --enable-locallisppath="${PWD}/nextstep/Emacs.app/Contents/MacOS" \ --with-mailutils \ --with-ns \ --with-imagemagick \ --with-cairo \ --with-modules \ --with-xml2 \ --with-gnutls \ --with-json \ --with-rsvg \ --with-nativecomp \ --disable-silent-rules \ --disable-ns-self-contained \ --without-dbus
Make it executable
chmod +x configure-gccemacs.sh
Clone Emacs source
git clone --branch feature/native-comp https://github.com/emacs-mirror/emacs emacs
Check out native-comp feature branch
cd gccemacs
git checkout feature/native-comp
Configure build
../configure-gccemacs.sh
Native lisp compiler found?
Verify native lisp compiler is found:
Does Emacs have native lisp compiler? yes
Build
Put those cores to use. Find out how many you got with:
sysctl hw.logicalcpu
hw.logicalcpu: 4
Ok so build with:
make -j4 NATIVE_FAST_BOOT=1
cp -r lisp nextstep/Emacs.app/Contents/Resources/
cp -r native-lisp nextstep/Emacs.app/Contents
make install
Note: Using NATIVE_FAST_BOOT=1 significantly improves build time (totalling between 20-30 mins, depending on your specs). Without it, the build can take hours.
The macOS app build (under nextstep/Emacs.app) is ready, but read on before launching.
Remove ~/emacs.d
You likely want to start with a clean install, byte-compiling all packages with the latest Emacs version. In any case, rename ~/emacs.d (for backup?) or remove ~/emacs.d.
init.el config
Ensure exec-path includes the script's "–prefix=" value, LIBRARY_PATH points to gcc's lib dir, and finally set comp-deferred-compilation. I wrapped the snippet in my exec-path-from-shell config, but setting early in init.el should be enough.
(use-package exec-path-from-shell :ensure t :config (exec-path-from-shell-initialize) (if (and (fboundp 'native-comp-available-p) (native-comp-available-p)) (progn (message "Native comp is available") ;; Using Emacs.app/Contents/MacOS/bin since it was compiled with ;; ./configure --prefix="$PWD/nextstep/Emacs.app/Contents/MacOS" (add-to-list 'exec-path (concat invocation-directory "bin") t) (setenv "LIBRARY_PATH" (concat (getenv "LIBRARY_PATH") (when (getenv "LIBRARY_PATH") ":") ;; This is where Homebrew puts gcc libraries. (car (file-expand-wildcards (expand-file-name "~/homebrew/opt/gcc/lib/gcc/*"))))) ;; Only set after LIBRARY_PATH can find gcc libraries. (setq comp-deferred-compilation t)) (message "Native comp is *not* available")))
Launch Emacs.app
You're good to go. Open Emacs.app via finder or shell:
open nextstep/Emacs.app
Deferred compilation logs
After setting comp-deferred-compilation (in init.el config section), .elc files should be asyncronously compiled. Function definition should be updated to native compiled equivalent.
Look out for an Async-native-compile-log buffer. Should have content like:
Compiling .emacs.d/elpa/moody-20200514.1946/moody.el... Compiling .emacs.d/elpa/minions-20200522.1052/minions.el... Compiling .emacs.d/elpa/persistent-scratch-20190922.1046/persistent-scratch.el... Compiling .emacs.d/elpa/which-key-20200721.1927/which-key.el... ...
Can also check for .eln files:
find ~/.emacs.d -iname *.eln | wc -l
149
UPDATE1: Added Symlink Emacs.app/Contents/eln-cache section for update 11.
UPDATE2: Noted using NATIVE_FAST_BOOT makes the build much faster.
UPDATE3: Removed symlinks and copied content instead. This simplifies things. Inspired by Ian Wahbe's build-emacs.sh.
UPDATE4: Removed homebrew recipe patching. Thanks to Dmitry Shishkin's instructions.