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