Skip to content

Instantly share code, notes, and snippets.

@Eason0210
Forked from LdBeth/build.org
Created November 3, 2024 03:27
Show Gist options
  • Save Eason0210/f3e517a36c2d7adc77ea8e8d5c058dd2 to your computer and use it in GitHub Desktop.
Save Eason0210/f3e517a36c2d7adc77ea8e8d5c058dd2 to your computer and use it in GitHub Desktop.
Build Emacs 31 for Windows

Build Emacs with MSYS2

This document is an up-to-date guide on compile Emacs 31 on windows with MSYS2, and make a installation with native compile that can work without MSYS2.

The idea is after get a working Emacs, you may delete MSYS2 environment to save some disk space, and forget about rebuilding Emacs until the next time you feel need to, without need figuring out everything again.

Specially thanks to @include-yy on emacs-china.org for providing guides on UCRT64.

How to get MSYS2 (without installer)

Get from https://github.com/msys2/msys2-installer/releases/

You may use the 7zip SFX one.

Update MSYS2 base environment

We are using the UCRT64.

pacman -Syu

After complete, restart terminal, and run

pacman -Su

To install the required packages for building Emacs. (Maybe other people can came up with a better list)

pacman -Su \
  autoconf \
  autogen \
  automake \
  automake-wrapper \
  git \
  libidn-devel \
  libltdl \
  libnettle-devel \
  libopenssl \
  libp11-kit-devel \
  libtasn1-devel \
  libunistring \
  make \
  mingw-w64-ucrt-x86_64-toolchain \
  mingw-w64-ucrt-x86_64-bzip2 \
  mingw-w64-ucrt-x86_64-cairo \
  mingw-w64-ucrt-x86_64-crt-git \
  mingw-w64-ucrt-x86_64-expat \
  mingw-w64-ucrt-x86_64-fontconfig \
  mingw-w64-ucrt-x86_64-freetype \
  mingw-w64-ucrt-x86_64-gcc \
  mingw-w64-ucrt-x86_64-gcc-libs \
  mingw-w64-ucrt-x86_64-gdk-pixbuf2 \
  mingw-w64-ucrt-x86_64-gettext \
  mingw-w64-ucrt-x86_64-giflib \
  mingw-w64-ucrt-x86_64-glib2 \
  mingw-w64-ucrt-x86_64-gmp \
  mingw-w64-ucrt-x86_64-gnutls \
  mingw-w64-ucrt-x86_64-harfbuzz \
  mingw-w64-ucrt-x86_64-headers-git \
  mingw-w64-ucrt-x86_64-imagemagick \
  mingw-w64-ucrt-x86_64-jansson \
  mingw-w64-ucrt-x86_64-libgccjit \
  mingw-w64-ucrt-x86_64-libiconv \
  mingw-w64-ucrt-x86_64-libidn2 \
  mingw-w64-ucrt-x86_64-libjpeg-turbo \
  mingw-w64-ucrt-x86_64-libpng \
  mingw-w64-ucrt-x86_64-librsvg \
  mingw-w64-ucrt-x86_64-sqlite3 \
  mingw-w64-ucrt-x86_64-tree-sitter
  mingw-w64-ucrt-x86_64-libtiff \
  mingw-w64-ucrt-x86_64-libunistring \
  mingw-w64-ucrt-x86_64-libxml2 \
  mingw-w64-ucrt-x86_64-nettle \
  mingw-w64-ucrt-x86_64-p11-kit \
  mingw-w64-ucrt-x86_64-winpthreads \
  mingw-w64-ucrt-x86_64-xpm-nox \
  mingw-w64-ucrt-x86_64-xz \
  mingw-w64-ucrt-x86_64-zlib \
  mingw-w64-ucrt-x86_64-jbigkit \
  pkgconf \
  texinfo \

Fetch Emacs source

git config --global core.autocrlf false
git clone https://github.com/emacs-mirror/emacs --depth 1

Build Emacs

Configuration

It is important to --with-gnutls, because otherwise Emacs won’t even able to use ELPA outside MSYS2. Also, dbus is not useful for Emacs on Windows. You may change other flags as you see appropriate.

Set prefix to somewhere appropriate.

cd emacs
mkdir build
cd build
target=/g/emacs
../configure prefix=$target \
    --with-native-compilation=aot \
    --with-gnutls \
    --without-dbus \
    --without-pop \
    --with-xpm \
    --with-imagemagick \
    --with-tree-sitter

Check if the configure log is appropriate.

Building Emacs

Then make bootstrap it (for develop branch). After build complete, make install and open the $target directory.

Post building

DLL Hell

The easiest way is to copy all the dlls from /ucrt64/bin, and exploit the property that Windows won’t allow delete currently opened files to trim it. Still that doesn’t mean all the successfully deleted dlls are safe to purge. It is a good idea to check against the Windows binary distributed by GNU for DLL used by Emacs.

The good things is, even if you have found certain DLL is missing afterwards, you can still download the individual package without reinstall MSYS2.

XPM image

This requires libXpm-noX4.dll.

Treesitter

libtree-sitter.dll depended on wasmtime.dll.

GCCJIT

Additional works are required to make native compile work without complete MSYS2 environment.

cp /ucrt64/lib/{crtbegin,crtend,dllcrt2}.o $target/bin/
cp /ucrt64/lib/lib{advapi32,gcc_s,mingw32,msvcrt,shell32,kernel32,mingwex,pthread,user32}.a $target/bin/
# adjust path according to gcc version
cp /ucrt64/lib/gcc/x86_64-w64-mingw32/14.2.0/libgcc.a $target/bin/

Add the following to init.el

(setq native-comp-driver-options
      (list "-B" (expand-file-name invocation-directory)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment