build-emacs-for-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.

Why?

  • To use new features available from master or branches, which have not made it into a official stable release yet.
  • Homebrew builds of Emacs are not self-contained applications, making it very difficult when doing HEAD builds and you need to rollback to a earlier version.
  • Both Homebrew HEAD builds, and nightly builds from emacsformacosx.com are built from the master branch. This script allows you to choose any branch, tag, or git ref you want.

Status

As of writing (2020-08-18) it works for me on my machine. Your luck may vary.

I have successfully built:

  • emacs-27.1 release git tag
  • master branch (Emacs 28.x)
  • feature/native-comp branch (Emacs 28.x)

For reference, my machine is:

  • 13-inch MacBook Pro (2020)
  • 10th Gen i7, 2.3 GHz 4-core/8-thread CPU
  • macOS 10.15.6 (19G2021)
  • Xcode 11.6

Limitations

The build produced does have some limitations:

  • It is not a universal application. The CPU architecture of the built application will be that of the machine it was built on.
  • The minimum required macOS version of the built application will be the same as that of the machine it was built on.
  • The application is not signed, so running it on machines other than the one that built the application will yield warnings. If you want to make a signed Emacs.app, google is you friend for finding signing instructions.

Requirements

  • Xcode
  • Homebrew
  • All Homebrew formula listed in the Brewfile, which can all easily be installed by running:
    brew bundle
    

Usage

Usage: ./build-emacs-for-macos [options] <branch/tag/sha>

Branch, tag, and SHA are from the mirrors/emacs Github repo,
available here: https://github.com/mirrors/emacs
    -j, --parallel PROCS             Compile in parallel using PROCS processes
    -x, --xwidgets                   Apply XWidgets patch for Emacs 27
        --native-comp                Enable native-comp
        --native-fast-boot           Only relevant with --native-comp

Resulting applications are saved to the builds directory in a bzip2 compressed tarball.

I would typically recommend to pass a -j value equal to the number of CPU threads your machine has to ensure a fast build. In the below examples I'll be using -j 4.

Examples

To download a tarball of the master branch (Emacs 28.x), build Emacs.app from it:

./build-emacs-for-macos -j 4

To build the stable emacs-27.1 release git tag, with XWidgets support, run:

./build-emacs-for-macos -j 4 --xwidgets emacs-27.1

Native-Comp

To build a Emacs.app with native-comp support (gccemacs) from the feature/native-comp branch, you will need to install a patched version of Homebrew's gcc formula, which is included in Forumlas/gcc.rb. This can easily be installed by running:

./install-patched-gcc

This requires installing and compiling GCC from source, and take anywhere between 30-60 minutes or more depending on your machine.

Then to build a Emacs.app with native compilation enabled, run:

./build-emacs-for-macos -j 4 --native-comp feature/native-comp

On my machine with -j 8 this takes around 20-25 minutes. The increased build time is cause all lisp files in the app are compiled to native *.eln files.

The build time can be sped up by using --native-fast-boot, which compiles a minimal required set of lisp files to native code during build, and will compile the rest dynamically in the background as they get loaded while you're using Emacs.

Credits

  • I've borrowed some ideas and in general used David Caldwell's excellent build-emacs project, which produces all builds for emacsformacosx.com.
  • Patches applied are pulled from emacs-plus, which is an excellent Homebrew formula with lots of options not available elsewhere.

Internals

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 ./configure with 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.

License

CC0 1.0 Universal

Description
Somewhat hacky script to automate building of Emac.app on macOS.
Readme 2.5 MiB
Languages
Go 63.1%
Ruby 33.4%
Makefile 1.8%
Nix 1.4%
Shell 0.2%
Other 0.1%