Building Emacs
If installing on macOS, install emacs-app or
emacs-mac-app from MacPorts. The latter version is the Yamamoto
Mitsuharu version which provides native GUI support for macOS.
However, since Emacs 23, native GUI support is now included in the
standard GNU distribution (MacPorts emacs-app), but
emacs-mac-app has additional
enhancements for the Mac.
However, it can be useful to have an independently built version for
those occasions when a MacPorts upgrade fails, leaving a broken
environment where Emacs may not run. Fortunately there’s always
vi or vim to fallback on, but if you prefer to
use Emacs, you can create a minimal Emacs on macOS without installing
many library dependencies, build from source with:
Installing GNU Emacs:
Download the latest Emacs version.
The configure options provide a working Emacs with
minimal effort.
$ cd /usr/local/src
$ tar -xf ../emacs-29.4.tar.xz
$ cd emacs-29.4
$ ./configure --without-makeinfo --with-gnutls=ifavailable
$ make
$ ./src/emacs
With Emacs 29.4 the --without-makeinfo option no longer
exists. Worse it fails to build if makeinfo command does
not exist. Install the texinfo package.
Download texinfo-7.2.tar.gz, extract and build:
$ cd /usr/local/src
$ tar -xf ../texinfo-7.2.tar.gz
$ ./configure
$ make
$ sudo make install
See the excellent documentation in the root of the Emacs source, particularly the INSTALL and README files for more information.
You can also run make install (which installs under
./nextstep without using root/sudo) and then copy
./nextstep/Emacs.app to the /Applications
folder and run it from there. However, Due to the extra security on
newer versions of macOS you probably won’t be able to run it as
Emacs.App and will need to execute emacs from
the command line in the source folder as above. If you have an Apple
developer account, see the ‘Code Signing’ section below.
See https://www.emacswiki.org/emacs/EmacsForMacOS for further details.
To configure the Emacs build to include GNU Mailutils;
first, build mailutils with the following arguments:
$ ./configure --disable-cxx --disable-python --disable-build-servers \
--without-readline
Build GnuTLS as described in the ‘Building GnuTLS’ section below, then configure Emacs with:
$ ./configure --with-gnutls --with-mailutils
Note: To rebuild a package using the same command
line options as last passed to the ./configure command, run
./config.status --recheck. See makefile
- How do you “echo” the last configure/make build –options within a
source directory? - Stack Overflow.
You can also see how Emacs was built in a running Emacs with
C-h v system-configuration-options.
See also self-contained portable emacs on stackoverflow
Code Signing
After building Emacs and running making install (without
sudo):
# Display your signing keys
security find-identity -p codesigning -v \
| awk '{ if (match($0, "\".*\"")) print substr($0, RSTART, RLENGTH); }'
cd nextstep
# Attempt to sign with the developer key using the developer ID from the
# awk output
codesign --force -s "Apple Development: Foo Bar (XXXXXXXXXX)" Emacs.app
# Response shows first subcomponent that also needs signing
Emacs.app: replacing existing signature
Emacs.app: code object is not signed at all
In subcomponent: /usr/local/src/emacs-29.4/nextstep/Emacs.app/Contents/MacOS/libexec/Emacs.pdmp
# Sign all the components in the `libexec` folder
codesign --force -s "Apple Development: Foo Bar (XXXXXXXXXX)" Emacs.app/Contents/MacOS/libexec/*
# Repeat the top level signing
codesign --force -s "Apple Development: Foo Bar (XXXXXXXXXX)" Emacs.app
# Optionally verify the signatures
codesign --verify --verbose Emacs.app/Contents/MacOS/libexec/Emacs.pdmp
codesign --verify --verbose Emacs.app/Contents/MacOS/libexec/rcs2log
codesign --verify --verbose Emacs.app
# Copy to the Applications folder:
cp -a Emacs.app /Applications/
Try opening the application using Finder. It may take multiple attempts before macOS will allow the application to run. Thereafter it should be launchable as normal.
Building GnuTLS
Building GnuTLS is a non-trivial task on macOS. There are a number of
nested dependencies and one or two traps along the way. You need to read
the INSTALL.md distributed with GnuTLS at the very
least.
Below are some of the solutions I found to succeed in a build. I cannot vouch for how appropriate or correct these solutions are.
If you have any problems, I would recommend examining the Portfiles for each of the MacPort installers, to assist in determining where to download packages from on the Internet, which versions may be appropriate and any patches that may need to be applied.
https://github.com/macports/macports-ports
Notes for packages which need to be built with specific
./configure options are listed in the following
sub-sections.
– Frank Dean - 12 Feb 2025
libiconv
https://ftp.gnu.org/pub/gnu/libiconv/
./configure
pkgconfig
https://pkgconfig.freedesktop.org/releases/
It’s good to build pkgconfig early on as other artifact
builds use it. pkgconfig has a circular dependency with
glib. You get around it by building with its own internal version of
glib.
./configure --with-internal-glib 'CFLAGS=-Wno-int-conversion'
Version 0.29.2 may need patching. See MacPorts Portfile.
After install glib2, pkgconfig can be rebuilt using
./configure without any parameters.
gmp
https://gmplib.org/download/gmp/
./configure
ncurses
Optional dependency.
https://invisible-island.net/ncurses/ncurses.html
./configure --enable-widec --disable-lib-suffixes --enable-overwrite \
--with-shared --with-cxx-shared --without-debug --without-ada \
--with-manpage-format=normal --enable-pc-files --disable-mixed-case
gettext
https://ftp.gnu.org/pub/gnu/gettext/
./configure
coreutils
https://ftp.gnu.org/gnu/coreutils/
Optionally, so as to distinguish GNU coreutils from the BSD commands
of the same name, prefix all the commands with g:
./configure --program-prefix=g
sed
Optionally, so as to distinguish the GNU sed command
from the BSD sed command, prefix the command with
g:
./configure --program-prefix=g
bzip2
Optional dependency.
https://sourceware.org/bzip2/downloads.html
make
sudo make install
There doesn’t appear to be an uninstall script for bzip2.
libedit
Optional dependency.
./configure
zlib
Optional dependency.
./configure
pcre2
https://github.com/PCRE2Project/pcre2/releases
./configure
glib2
https://gitlab.gnome.org/GNOME/glib/-/releases
Glib now needs Meson
to build. See INSTALL.md in the root of the Glib
source.
Download ninja-mac.zip Ninja which
Meson depends on. Unzip the file and place the executable on your path.
You’ll need to open the executable using finder to override system
security before it can be used by Meson.
pip3 install --user meson
export PATH="$PATH:$HOME/Library/Python/3.9/bin"
meson setup _build
meson compile -C _build
sudo meson install -C _build
Uninstall with:
export PATH="$PATH:$HOME/Library/Python/3.9/bin"
sudo meson uninstall
Uninstall meson with:
pip3 uninstall meson
openssl
https://github.com/openssl/openssl/releases
./Configure
make
sudo make install
nettle
https://www.lysator.liu.se/~nisse/nettle/
Nettle must be compiled with GMP support to provide Libhogweed (nettle’s companion library).
./configure
libtasn1
https://www.gnu.org/software/libtasn1/
./configure
libxslt
Optional dependency.
https://download.gnome.org/sources/libxslt/
./configure --without-python --without-crypto
p11-kit
https://github.com/p11-glue/p11-kit/releases
./configure --without-trust-paths
expat
https://github.com/libexpat/libexpat/releases
./configure
flex
Optional dependency.
https://github.com/westes/flex/releases
./configure
libsodium
Optional dependency.
https://github.com/jedisct1/libsodium/releases
./configure
unbound
https://nlnetlabs.nl/downloads/unbound/
./configure
After building and installing:
sudo /usr/local/sbin/unbound-anchor -a /usr/local/etc/unbound/root.key
brotli
Optional dependency.
https://github.com/google/brotli
zstd
Optional dependency.
https://github.com/facebook/zstd/releases
gnutls
https://www.gnupg.org/ftp/gcrypt/gnutls/
./configure --with-included-unistring --with-unbound-root-key-file=/usr/local/etc/unbound/root.key
jansson
Optional dependency.
https://github.com/akheron/jansson/releases
./configure
xz
Optional dependency of libxml2.
https://github.com/tukaani-project/xz/releases
./configure
libxml2
Optional dependency.
https://download.gnome.org/sources/libxml2/
./configure --enable-static --with-ftp --with-http --with-icu \
--with-lzma --with-zlib --without-python
sqlite3
Optional dependency.
https://www.sqlite.org/download.html
After downloading and extracting the autoconf version
e.g. sqlite-autoconf-3480000.tar.gz, check the SAH3-256
hash with:
openssl sha3-256 sqlite3.c
./configure --enable-threadsafe --enable-dynamic-extensions \
--disable-readline --enable-editline AWK=/usr/bin/awk
webp
Optional dependency.
emacs
./configure \
--without-dbus --without-gconf --with-libgmp --with-gnutls \
--with-json=ifavailable --with-xml2 --with-modules
– Frank Dean - 12 Feb 2025
Related Topics: EmacsTips