Somewhat hacky script to automate building of Emac.app on macOS.
My personal hacked together script for building a completely self-contained Emacs.app application on macOS, from any git branch, tag, or ref.
Use this script at your own risk.
masterbranch. This script allows you to choose any branch, tag, or git ref you want.
As of writing (2021-01-15) it works for me on my machine. Your luck may vary.
I have successfully built:
emacs-27.1release git tag
masterbranch (Emacs 28.x)
feature/native-compbranch (Emacs 28.x)
For reference, my machine is:
The build produced does have some limitations:
Brewfile, which can all easily be installed by running:
ruby --version. If it's too old, you can install a newer version with:
brew install ruby
Usage: ./build-emacs-for-macos [options]
Branch, tag, and SHA are from the emacs-mirror/emacs/emacs Github repo, available here: https://github.com/emacs-mirror/emacs
Options: -j, --parallel COUNT Compile using COUNT parallel processes (detected: 8) --git-sha SHA Override detected git SHA of specified branch allowing builds of old commits --[no-]xwidgets Enable/disable XWidgets (default: enabled if supported) --[no-]native-comp Enable/disable native-comp (default: enabled if supported) --[no-]native-full-aot Enable/disable NATIVE_FULL_AOT / Ahead of Time compilation (default: disabled) --rsvg Enable SVG image support via librsvg, can yield a unstable build (default: disabled) --no-titlebar Apply no-titlebar patch (default: disabled) --no-frame-refocus Apply no-frame-refocus patch (default: disabled) --[no-]native-fast-boot DEPRECATED: use --[no-]native-full-aot instead --[no-]launcher DEPRECATED: Launcher script is no longer used.
Resulting applications are saved to the
buildsdirectory in a bzip2 compressed tarball.
If you don't want the build process to eat all your CPU cores, pass in a
-jvalue of how many CPU cores you want it to use.
Re-building the same Git SHA again can yield weird results unless you first trash the corresponding directory from the
To download a tarball of the
masterbranch (Emacs 28.x as of writing) and build Emacs.app from it:
To build the stable
emacs-27.1release git tag run:
All sources as downloaded as tarballs from the emacs-mirror GitHub repository. Hence to get a list of tags/branches available to install, simply check said repository.
As the application bundle is self-contained, the main executable needs to be run from within the application bundle. This means a simple symlink to
Emacs.app/Contents/MacOS/Emacswill not work. Instead the best approach is to create a shell alias called
emacspointing to the right place.
Personally I use something similar to this:
if [ -f "/Applications/Emacs.app/Contents/MacOS/Emacs" ]; then export EMACS="/Applications/Emacs.app/Contents/MacOS/Emacs" alias emacs="$EMACS -nw" fi
if [ -f "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient" ]; then alias emacsclient="/Applications/Emacs.app/Contents/MacOS/bin/emacsclient" fi
EMACSvariable to the binary path seems to be a good idea, as some tools seems to use it to figure out the path to Emacs' executable, including doom-emacs'
Building a Emacs.app with native-comp support (gccemacs) from the
feature/native-compbranch is now supported without much hassle thanks to the newly released
To build a Emacs.app with native compilation enabled, simply run:
NATIVE_FULL_AOTis disabled which ensures a fast build by native compiling as few lisp source files as possible to build the app. Any remaining lisp files will be dynamically compiled in the background the first time you use them. To enable native full AoT, pass in the
On my machine it takes around 10 minutes to build Emacs.app with
NATIVE_FULL_AOTdisabled. With it enabled it takes around 20-25 minutes.
Add the following near the top of your
(setq comp-speed 2)
By default natively compiled
*.elnfiles will be cached in
~/.emacs.d/eln-cache/. If you want to customize that, simply set a new path as the first element of the
comp-eln-load-pathvariable. The path string must end with a
Below is an example which stores all compiled
cache/eln-cachewithin your Emacs configuration directory:
(when (boundp 'comp-eln-load-path) (setcar comp-eln-load-path (expand-file-name "cache/eln-cache/" user-emacs-directory)))
A list of known "good" commits which produce working builds is tracked in: #6 Known good commits of feature/native-comp branch
feature/native-compbranch building on macOS:
The script downloads the source code as a gzipped tar archive from the GitHub mirror repository, as it makes it very easy to get a tarball of any given git reference.
It then runs
./configurewith a various options, including copying various dynamic libraries into the application itself. So the built application should in theory run on a macOS install that does not have Homebrew, or does not have the relevant Homebrew formulas installed.
Code quality of the script itself, is well, non-existent. The build script started life a super-quick hack back in 2013, and now it's even more of a dirty hack. I might clean it up and add unit tests if I end up relying on this script for a prolonged period of time. For now I plan to use it at least until native-comp lands in a stable Emacs release for macOS.