========================
== Experimental Emacs ==
========================
Corwin's Emacs Blog

Packaging Emacs for Windows

GNU provides binary releases of Emacs. This post describes how to follow the process used to make such releases for Windows.

I've published some binaries created using this process to a repo at Sourcehut.

https://git.sr.ht/~mplscorwin/emacs-w64

Prefer those from the with-native-compilation folder; I'm no longer updating the versions compiled without support for that feature.

To use native compilation (available starting with Emacs 28), you must ensure bin folder of your MSYS installation is present in the PATH of the windows environment when starting Emacs. You do not need to change your windows path to create binary releases when following the processes described below.

Prerequisites

You must create the build directories manually. See: admin/nt/dist-build/README-scripts

  mkdir -p ~/emacs-build/deps
  mkdir ~/emacs-build/git
  mkdir ~/emacs-upload

You must also have a working MSYS/MINGW64 installation on your build environment.

Creating a Release

These instructions assume the current release branch/tag is emacs-28 and that we are building a pre-release of Emacs version 20.0.91.

Instances of emacs-28 in the commands from steps 1 and 2 will require adjustment for later versions of Emacs. They should work equally well for releases as pre-releases. You should not have to make changes related to minor version updates, for example once GNU releases Emacs 28, this same process will "just work" to create Emacs 28.1 binaries.

The scripts we use are those used to crate official Emacs releases, most recently by Phillip Lord (who also authored these scripts). Thanks Phil.

Bootstrap

Begin by cloning the release branch from GNU Savannah from the MINGW64 shell. You should only need to perform this step once, the first time you use follow process on a given environment/workstation.

Note: the release tag (emacs-28) appears twice in the command below.

From a MSYS or MINGW64 shell:

  git clone \
      -b emacs-28 \
      https://git.savannah.gnu.org/git/emacs.git \
      ~/emacs-build/emacs-28

Clone the target repository

From MSYS shell:

  cd ~/emacs-build/git/emacs-28/admin/nt/dist-build/
  ./build-zips.sh -g

ERROR: '../emacs-28.0.91' already exists'

If you receive an error indicating that the release branch already exists locally, simply update it, for example:

  git pull origin emacs-28

Create dependency archives

These commands create zip-files of dependencies and of their sources. The build-dep-zips.py script contains (toward the top) two dependency lists.

The first PKG_REQ provides the full MSYS package names. You must take care to install each of these, for example using: packman -S <dep-name>. The second, DLL_REQ lists libraries to bundle with the installer and zip version of the full release.

If you do plan to share your binary releases of Emacs, take care that all items in the second list appear also in the first. In order to remain compliant with the terms of the GNU Public License, you must ensure that you provide sources for each dependency. You may remove items from the second list to create smaller distributables, but you should not include packages in the second list without also including them in the first.

Execute the following from a MSYS shell:

Move to the deps folder

  cd ~/emacs-build/deps

Clean up the deps folder

  ../git/emacs-28.0.91/admin/nt/dist-build/build-dep-zips.py -c

Bundle dependencies

  ../git/emacs-28.0.91/admin/nt/dist-build/build-dep-zips.py 2>&1 \
      | tee ~/emacs-build/dep.log

Build and Package Emacs

The build-zips.sh script can build Emacs and create binary releases for windows in multiple forms, including a windows installer (EXE) and ZIP archives with and with-out the optional dependency libraries, (DLL files). When running under windows Emacs treats these dependencies as optional during the run-time, meaning that Emacs will work fine when installed from "no-deps" zip files produced by this process (albeit with some capabilities disabled).

Execute the following from a MINGW64 shell:

Move to the dist-build folder

   cd ~/emacs-build/git/emacs-28.0.91/admin/nt/dist-build

Create release packages

   ./build-zips.sh 2>&1 \
     | tee ~/emacs-build/zip.log

Creating a Snapshot

Snapshot builds come from the main Emacs development branch, called "master". The process is nearly identical save that we must add the -s option to build-dep-zips.py during the Bundle dependencies step and to build-zips.sh during the Create release packages step.

Here are the alternate version of each command:

Bundle snapshot dependencies

  ../git/emacs-28.0.91/admin/nt/dist-build/build-dep-zips.py -s 2>&1 \
      | tee ~/emacs-build/snap-dep.log

Create snapshot release packages

   ./build-zips.sh -s 2>&1 \
     | tee ~/emacs-build/snap-zip.log

Problems Bundling Dependencies

You may encounter errors during the Bundle dependencies step related to missing dependancies in your MSYS instalation. You can review the PGG_REQ list in the build-dep-zips.py script to find a list of packages to install.

Alternately to research an error of this sort, find a string from the error message that appears to identify the missing package, and plug it into a search of the msys2 package archive using a command like:

  pacman -Ss <string>

Once you find the missing (x86_64) package, install it, e.g.:

  pacman -S mingw-w64-x86_64-<something>

Distributing Emacs Sources

GNU provides Emacs under the terms of the GNU Public License.

According to these terms, binary releases must be accompanied by the sources used to create them. The process described above handles this respect to the source code for dependencies of Emacs but do not create any archive of the sources for Emacs, itself.

This is because the scripts used are generally used by Emacs developers to create official binary release of Emacs for Window. GNU distributes these from GNUs offical FTP site ftp.gnu.org (or, in the case of pre-releases, alpha.gnu.org), which also provide the source code for GNU packages, such as Emacs.

If you plan to share your own binary distributions of Emacs, however, you must take care to also provide Emacs sources to comply with the terms of the GPL. Given you follow the process described above, you can create an archive of the Emacs sources used with one of these commands:

Archive Emacs Sources

  cd ~/emacs-build/git/emacs-28.0.91
  git clean -xdf
  zip -9r ~/emacs-upload/emacs-28.0.91-src.zip \
      ~/emacs-build/git/emacs-28.0.91 2>&1 \
      | tee ~/emacs-build/src.log

Archive Emacs Snapshot Sources

  cd ~/emacs-build/git/master
  git clean -xdf
  zip -9r ~/emacs-upload/emacs-29-$(date +%Y-%m-%d)-src.zip \
      ~/emacs-build/git/master 2>&1 \
      | tee ~/emacs-build/snap-src.log

Signing

To create signatures (.asm files) for the release artifacts I use GPG, which I've installed for windows and placed on the windows PATH. Here's the commands I use:

  cd ~/emacs-upload
  for f in *.zip *.exe ; do gpg --batch --yes -b $f ; done