installing emacs on macOS

installing emacs on macOS


As alluded about software freedom, there are essentially three approaches to installing a program like emacs.

A precompiled version of emacs is available from Emacs For Mac OS X. It does have gnutls for secure web browsing, however, no SVG support and so eww chokes on the GNU website sometimes. Save a copy for reinstalling, or for use on another computer.

Get either a stable release of emacs, or the latest development from its repository at savannah.gnu.org. Optionally configure it with the desired abilities: gnutls for secure communications (+3 other libraries), mailutils for email, and image support. So, only one package for emacs, and maybe a half dozen more for additional abilities. Make and install everything into the home directory of the login account, then tar and compress the installation as a backup, and for copying to another computer when needed.

Another option is to find a "package manager", download it, and install it. Then read the manual of the package manager to figure out how to install emacs, how to install other libraries and programs with the package manager in a manner that emacs will find, and how to update each and everything with the package manager. And how to update the package manager itself. Make notes on how to use the package manager, then later update the notes when the package manager changes how it does things. Then curse the package manager when its changes prevent or obscure installing some desired abilities for emacs. Overall, the package manager will probably install 50+ packages in order to provide emacs as a program, not including all the packages the package manager needs for itself. Oh, it will likely install everything system-wide, thereby making backing up the install or copying to another computer pretty much impossible. But that's okay, because it is a package manager, so just install it again and then install everything else again...Except that it needs to be connected to the Internet to install itself, and to get the latest packages, and to send back analytical information to its organization so they can improve the package manager. So, there has to be additional time to wait for downloading packages again, and the installation of the downloaded packages that only the package manager knows how to do but is unable to do by itself, etc.

# building programs on macOS

On macOS, use xcode-select install and a dialog will appear requesting permission to automatically download and install the developer tools. During that moment, there will likely also be a need to fiddle with a notification in the upper right corner of the screen, and with "Software Update" in "System Preferences", too. Eventually, the developer tools (from the fruitcake computer company that made its computers purposely unusable without the company's operating system, both by its "Terms of Use" contract and obfuscation) will probably be installed.

Review basic software freedom: the means for accessing sources for software, the build environment settings, and an approach of a basic build. Much of the software is on the GNU Software listing.

On macOS 10.15 (Catatonia), the curl command is available for downloading from the command line, if desired (or when nothing else immediately available, like wget). Use curl -O and then the URL to the source file, optionally with -R for original date-time, too.

On macOS 10.15 (Catatonia), tar is version bsd 3.3.2 (libarchive), which figures out and handles various types of compression based on the filename suffix. Therefore, simply use tar xf with the downloaded source to extract its files, regardless of ".bz2", ".gz", ".lz", and ".xz", even without their utils (as Catatonia is without xz).

downloads/> tar xf source.tar.gz

The xz utils might make it simpler for editing ".xz" and "tar.xz" compressed files within emacs, such as from dired mode. Or without xz, simply issue !tar xf on the file to decompress (with the tar of Catatonia), and then Z on the decompressed results for compressing into ".gz" or "tar.gz" (automatically as needed).

Downloading from Emacs For Mac OS X seems to be inaccessible with the curl of Catatonia, though downloading does work with eww in emacs. Use hdiutil attach for mounting a DMG file, and it appears in "/Volumes/" as expected. Can use the detach option for unmounting it in "/Volumes/", but diskutil eject is the general command for a volume of any type.

Use cp -X to copy without extended attributes or resource forks, especially to remove the mark as an untrusted downloaded file.

For tidiness's sake keep the emacs "init.el" file in ".emacs.d/".

Applications started in macOS with the pointer-using-interface (PUI) obviously will miss out on shell environment variables. Start emacs from Terminal.app so the shell environment variables will be gained by emacs, perhaps in the background. Optionally, immediately type disown to disassociate that process from that shell, so the terminal can be closed without affecting the emacs process. (Right?)

> emacs&
> disown

Using emacs within the terminal (f.e. emacs -nw or built without --with-ns) rather than as an application prevents viewing of images seemingly because the terminal is text only.

Substitutions for a few libraries are available, with some functions overridden within copies of the original lisp files. The overridden functions are preceded with a comment stating so and then simply quoted, a mere apostrophe before its list. This maintains the original context with the original functions for easily comparing with a new version of emacs. Search for comments ";Override" and ";Emerged" to find the differences, or use = (command: ESC x dired-diff) within dired.

# prerequisites for everything

Documentation is commonly crafted with Texinfo. Configuration of sources is often aided by pkg-config. In this case, emacs expects makeinfo (from Texinfo) and gnutls needs pkg-config, and their other prerequisites benefit, too.

Begin with sources within the repository of incoming compilables "~/elec/tric/", and install each into the esoteric libraries and exoteric commands directory "~/elec/". Confirm the necessary environment variables within the shell: PATH, CPATH, LIBRARY_PATH, PKG_CONFIG_PATH.

pkg-config
Version 0.29.2 last used.

Untar pkg-config and cd into its source directory. Configure using --with-internal-glib, and declare the default paths for ".pc" files using --with-pc-path.

pkg-config-src/> ./configure \
> --prefix=$HOME/elec \
> --with-internal-glib \
> --with-pc-path\
> =$HOME/elec/lib/pkgconfig\
> :/usr/local/lib/pkgconfig\
> :/usr/lib/pkgconfig
pkg-config-src/> make
pkg-config-src/> make check
[...]
../pkg-config --cflags system :
'' != '-I/usr/include'
FAIL: check-system-flags
====================
1 of 30 tests failed
Please report to ...
[...]
pkg-config-src/> make install

Installation of pkg-config added files: "bin/", "share/".

Texinfo
Version 6.7 last used.

Untar texinfo and cd into its source directory. Basic build. Over 12,000 tests, but rather quick ones.

texinfo-src/> ./configure \
> --prefix=$HOME/elec
texinfo-src/> make
texinfo-src/> make check
texinfo-src/> make install

Installation of Texinfo added files: "bin/", "share/".

# emacs and mailutils: prerequisites

Reviewing the ./configure --help for each of emacs, mailutils, and gnutls reveals prerequisites in common: pkg-config (part of prerequisities for everything), libunistring, readline.

Begin with sources within the repository of incoming compilables "~/elec/tric/", and install each into the esoteric libraries and exoteric commands directory "~/elec/". Confirm the necessary environment variables within the shell: PATH, CPATH, LIBRARY_PATH, PKG_CONFIG_PATH.

  1. libunistring. Version 0.9.10 last used.

    Untar libunistring and cd into its source directory. Basic build. Slow on the check.

    unistring-src/> ./configure \
    > --prefix=$HOME/elec
    unistring-src/> make
    unistring-src/> make check
    unistring-src/> make install

    Installation of libunistring added files: "include/", "lib/", "share/".

  2. readline. Version 8.0 last used.

    Untar readline and cd into its source directory. Basic build.

    readline-src/> ./configure \
    > --prefix=$HOME/elec
    readline-src/> make
    readline-src/> make check
    make: Nothing to be done for `check'.'
    readline-src/> make install

    Installation of readline added files: "bin/", "include/", "lib/", "lib/pkgconfig/", "share/".

# build gnutls

The gnutls library is for secure communications, such as visiting websites with eww or using ssh.

It requires pkg-config (part of prerequisites for everything), libunistring (part of prerequisites for emacs and mailutils), and libtasn1 (included with gnutls). It also requires nettle, which itself requires gmp.

Begin with sources within the repository of incoming compilables "~/elec/tric/", and install each into the esoteric libraries and exoteric commands directory "~/elec/". Confirm the necessary environment variables within the shell: PATH, CPATH, LIBRARY_PATH, PKG_CONFIG_PATH.

  1. gmp
    Version 6.1.2 last used.

    Untar gmp and cd into its source directory. Basic build.

    gmp-src/> ./configure \
    > --prefix=$HOME/elec
    gmp-src/> make
    gmp-src/> make check
    gmp-src/> make install

    Installation of gmp added files: "include/", "lib/", "share/".

  2. nettle
    Version 3.5.1 last used.

    Untar nettle and cd into its source directory. Configure using --disable-openssl, because of the licensing for OpenSSL. Contrarily, check fails before installation, so install first and then check.

    nettle-src/> ./configure \
    > --prefix=$HOME/elec \
    > --disable-openssl
    nettle-src/> make
    nettle-src/> make install
    nettle-src/> make check
    [ ... ]
    dlopen failed: dlopen(../libnettle.so, 2): image not found
    [ ... ]
    FAIL: dlopen
    ====================
    1 of 99 tests failed
    ====================
    

    One test will still fail because the ".so" file actually exists as ".dylib". If desired, fix the test.

    nettle-src/> nano testsuite/dlopen-test.c
    [ use Controlw to find "libnettle.so" ]
    [ change ".so" to have ".dylib" ]
    nettle-src/> make check

    Installation of nettle added files: "bin/", "include/", "lib/", "share/".

  3. gnutls
    Version 3.6.11.1 last used.

    Untar gnutls and cd into its source directory. Special configuration for using included packages and excluding additional packages.

    gnutls will want libtasn1 and libunistring, but both are included within the gnutls package. It will want libunbound, but without insistence. It will peculiarly insist on having p11-kit, though it is optional.

    gnutls-src/> ./configure \
    > --prefix=$HOME/elec \
    > --with-included-libtasn1 \
    > --without-p11-kit
    gnutls-src/> make
    gnutls-src/> make check
    [...some tests fail...]
    gnutls-src/> make install

    Unfortunately, four tests will fail: ftell, ftell2, ftello, ftello2. Install anyway.

    Installation of gnutls added files: "bin/", "include/", "lib/", "share/".

# build mailutils

Using the POPS and IMAPS protocols witin emacs requires movemail from mailutils, which itself requires a couple libraries.

It requires readline, but the version of readline in macOS 10.15 (Catatonia) is incompatible, hence recommended as a common prerequisite for emacs and mailutils. Similarly, libunistring is also in common.

Install the gnutls library for secure communications, particularly for POPS and IMAPS rather than only POP or IMAP. Otherwise, configure mailutils using --without-gnutls.

Begin with sources within the repository of incoming compilables "~/elec/tric/", and install each into the esoteric libraries and exoteric commands directory "~/elec/". Confirm the necessary environment variables within the shell: PATH, CPATH, LIBRARY_PATH, PKG_CONFIG_PATH.

Untar mailutils and cd into its source directory. Basic build; but can optionally disable mh, maildir, dotmail, and python.

mailutils-src/> ./configure \
> --prefix=$HOME/elec \
> --disable-mh \
> --disable-maildir \
> --disable-dotmail \
> --disable-python
mailutils-src/> make
mailutils-src/> make check
[...one test fails...]
mailutils-src/> make install

One test fails for mimeview, "9: regex". Install anyway.

Installation of mailutils added files: "bin/", "include/", "lib/", "libexec/", "sbin/", "share/".

# build emacs

Retrieve the source for a stable release of emacs, or the latest development from its repository at savannah.gnu.org. The repository can be copied with git, which creates a new "emacs/" directory and downloads the source into it.

software-dir/> git clone -b master git://git.sv.gnu.org/emacs.git

Refer to the "INSTALL.REPO" document, too, when it is from the repository rather than a release.

Either way, see the "INSTALL" document in the "nextstep" directory. It states that by default on macOS a fully self-contained application will be installed into that directory. So look there after the doing the installation, and move the application anywhere desired.

Begin with sources within the repository of incoming compilables "~/elec/tric/", and install each into the esoteric libraries and exoteric commands directory "~/elec/". Confirm the necessary environment variables within the shell: PATH, CPATH, LIBRARY_PATH, PKG_CONFIG_PATH.

The only actual prerequisite for emacs is autoconf if the source is from the repository (rather than source for a stable release), because that enables "autogen.sh" to create the "configure" script. Version 2.69 last used. Over 500 tests, and they seem slower than in other packages.

autoconf-src/> ./configure \
> --prefix=$HOME/elec
autoconf-src/> make
autoconf-src/> make check
autoconf-src/> make install
autoconf-src/> cd ../emacs-src
emacs-src/> ./autogen.sh

The default configuration for emacs will insist on having the gnutls library, however it can be skipped by using --without-gnutls. It will also insist on having makeinfo for creating its documentation (from Texinfo, part of prerequisites for everything), but that can be skipped by using --without-makeinfo.

Optionally, install mailutils to have email protocols for rmail other than just POP3, especially with gnutls for POPS and IMAPS.

[ Some sort of image support will likely be desired for emacs when using eww, such as for SVG (librsvg-2). Need to research more... ]

After configuring and making emacs, on macOS 10.15 (Catatonia) there might be a dialog asking permission for internet access during the check phase. Be prepared to approve it, or else there will be a stack of the dialogs. Regardless of that, there were six "unexpected results" from the check (version 27.0.50), but they seemed innocuous.

emacs-src/> ./configure \
> --prefix=$HOME/elec
emacs-src/> make
emacs-src/> make check
[Security dialogs might popup.]
[Six "unexpected results".]
emacs-src/> make install

A fully self-contained application is installed into the "nextstep" directory of the source directory when compiled on macOS.

# substitute libraries for emacs

A library of lisp functions can be found from the help documentation for one of its functions, t.i. Controlh f and one of the function names. Activating the link in the help documentation opens the file, so invoke dired with ESC x dired-jump (shortcut: Controlx Controlj) to show the directory listing with it.

As for replacement of the original files, simply put a substitute file into the "site-lisp" directory listing within the emacs installation directory. In other words, leave the original as is, because the modified copy in the "site-lisp" directory will be used instead.

Byte compile the substitution lisp file with Shiftb (command: ESC x dired-do-byte-compile) within dired mode.

# substitutions for dired mode and ls-lisp

A few differences for dired's use of ls-lisp are in this ls-lisp.el.gz library and this dired.el.gz library (emacs 27.0.50), notably:

Must also load "ls-lisp.el.gz" in the init file in order for it to be used by dired within restored buffers: (require'ls-lisp nil t). Requires the nu_base.el.gz library for sexagesimal notation (though very rough, could use a major rewrite; but it seems to work).

Notably, the formatting of the entries is rather sloppy: interdependent regexps; functions for skipping text when matching; various exceptions to formatting. As such, there might still be more to do to ensure formatting is correct, especially because of the removal of the space after the mark. A rewrite of default formatting done by dired seems ideal, if time permits.

ls-lisp-format-time

Sexagesimal notation for date/time. Only two characters needed for years 60–3599, and one character for anything else. Seven characters total, including seconds: yymdhms. No more 6 month rule. Compatible with leap seconds.

ls-lisp-links-fmt (emerged)
ls-lisp-format
ls-lisp-insert-directory

Like other fields, determines text width for largest number of links for a file or directory in the listing, therefore minimal width while also fitting when >999 links. Also in sexagesimal for compactness.

Attribute string converted from "drwxrwxrwx" to "d7777": entry type, numeric set-id, and then numeric perms for ugo. For example, "-rw-r--r--" is equivalent to "-0644", and "drwxr-xr-t" is equivalent to "d1755". See manual for ls(1) in its "The Long Format" section, and manual for chmod(1) in its "Modes" section.

ls-lisp-format-file-size

Undocumented function used by function ls-lisp-format. Converts file size to base 60, except with -h switch (t.i. when with units).

dired-re-maybe-mark
dired-subdir-regexp
dired-re-perms

Some regexps have been modified to account for the removal of the space after the mark. Also updated the regexp for matching permissions by number rather than drwxrwxrwx.

dired-insert-directory

No longer indents everything with two spaces. Instead, function ls-lisp-format adds the initial space for an entry, which is later replaced with a mark.

dired-build-subdir-alist

Updated matching of lines without a space after the mark. Crucial function; dired fails to list anything unless this succeeds.

# substitutions for rmail mode

In emacs 27.0.50 the rmail library uses the variable rmail-remote-password for supporting the retrieval of email from only one email server (or many if they all use the same password), though it does support multiple file sources.

This rmail.el.gz library supports multiple email accounts from multiple email servers by using auth-source for credentials or prompts when unavailable (some prompts not yet tested).

In other words, add machine, port, login, and password for each email account into the auth-source file, typically ".authinfo" or ".authinfo.gpg" file (or whatever is set in the auth-sources variable). The login and machine (f.e. login@machine.domain.tld) for each account in rmail-primary-inbox-list will be matched to the info in the auth-source file.

No new variables to set, no new commands to use; the variable rmail-remote-password will be ignored.

rmail-parse-url

Allows for optional account name. Ignores rmail-remote-password. Therefore, it supports multiple remote hosts in rmail-primary-inbox-list because it no longer attempts using same password for all remote hosts.

rmail-get-remote-account (emerged)

Uses auth-source. Otherwise, prompts for account name for host.

rmail-get-remote-password

Uses auth-source. Otherwise, prompts informatively with "account@host" when querying for each remote host, rather than with merely the protocol. No longer saves any password in rmail-remote-password.

# substitutions for smtpmail

In emacs 27.0.50 the smtpmail library uses 5 variables for supporting the use of only one email address: user-mail-address, smtpmail-smtp-user, smtpmail-smtp-server, smtpmail-smtp-service, and smtpmail-stream-type.

This smtpmail.el.gz library supports multiple SMTP email accounts by using auth-source for credentials or prompts when unavailable (some prompts not yet tested).

In other words, add machine, port, login, and password for each email account into the auth-source file, typically ".authinfo" or ".authinfo.gpg" file (or whatever is set in the auth-sources variable). When sending a message, it automatically matches the email address in the "From:" field of the message and one of the typical port numbers for an SMTP machine (25, 465, or 587) with the credentials in the auth-source file.

No new variables to set, no new commands to use. Those other variables are used only as fallbacks and should be considered obsoleted.

smtpmail-try-auth-methods

Override for undocumented non-public function. Optional USER for account name, potentially obsoleting smtpmail-smtp-user. Used by smtpmail-via-smtp.

smtpmail-via-smtp

Override for undocumented non-public function. Use "From:" field with auth-source for determining server and credentials. Fallback to user-mail-address, smtpmail-smtp-server, smtpmail-smtp-service, and smtpmail-stream-type, but all of these should be considered obsoleted.

When using auth-source with movemail of mailutils, need to use "%40" instead of "@" when it is part of the login for receiving email, such as when the email address is the login.

machine imap.domain.tld port 993 login name%40domain.tld password abc123

Also allows for new aliases key in auth-source entries, a parenthesized list of quoted addresses. Most relevant when sending email. For example:

# Remember, an entry is all on one line only.
machine smtp.domain.tld port 465 aliases ("alias@domain.tld""another@domain.tld") login name@domain.tld password abc123

Note there are no spaces between the quoted aliases, because the auth-source records have space-delimited fields. Unless a sender is matched with a login, the sender is then compared to the aliases list. A mail server might require the real login name rather than an alias, therefore aliases merely supplements login instead of replacing it. Specifically, the login value is used for the authentication rather than an alias.

[ Unfortunately, a mail server might add headers to an email revealing the authentication account, thereby devaluing the use of the aliases or "forward-only" addresses provided by its mail host. ]


More in:
software freedom: compilable
ls-lisp.el.gz (substitution)
nu_base.el.gz (sexagesmial notation system)
rmail.el.gz (substitution)
smtpmail.el.gz (substitution)
email in emacs
editing commands
begin