Compiling Emacs From Source

You can find Emacs executables for Windows online, and there are plenty of packages available in various package managers for Linux and Mac.

However, if you want to take advantage of the machine code compilation capability integrated into Emacs 29, you will need to compile a version of Emacs for each computer you want to use it on.

Machine code compilation ('native compilation') ensures files shipped with Emacs are compiled to machine code (not just byte-compiled elisp), and includes an elisp compiler that automatically compiles all byte-compiled files into machine-code compiled files.

So all packages you install, that are compiled, and all your byte-compiled .emacs files, get automatically compiled into machine-code.

The point is to speed up Emacs, and I found native compilation speeds up Emacs usage.

Having said that, my start-up time with Emacs 28 averaged under 2.5 seconds; in Emacs 29 my timer registers an average of .3 seconds, but it still takes 2 - 3 seconds to load packages because in my case minibuffer is still printing start-up messages and I have Emacs configured to retrieve news.

Anyway, you should get those gains in your day to day Emacs operations, and if you're doing some other fixes (I was overhauling Windows Linux Subsystem (WSL)), it might be time to get that upgrade in.

By the way, for those of you who want to wade into higher-level details on native compilation in Emacs, here is the source paper by Andrea Corallo, Luca Nassi, and Nicola Manca.

More Notes on Compiling Your Own Emacs

Last time I compiled Emacs for Windows, I used GCC programs directly from WSL and that worked fine.

This time, for no reason other than that last time I documented the WSL compilation but not the Windows side compilation (I compiled Emacs 28 for both Windows and WSL), I installed MSYS2 installation using the Chocolatey GUI.

Yes, I use Chocolatey GUI rather than Chocolatey on Powershell. Sometimes on Linux I use the GUI package manager also instead of the Advanced Package Tool (APT), but not on WSL, of course.

Chocolately makes it easy to update programs and adds them to the Windows path automatically while extending Windows path size limit.

Chocolately suggestion: note the location of every program you install with Chocolately. Chocolately doesn't tell you where it is instructed to install programs. Keep a copy of the Chocolatey XML config export in your re-install notes, as a reference.

Also, last time I compiled Emacs 28 with Image Magick support and PDF TOOLS in Windows and they both worked (you need the image-magick libraries to use PDF TOOLS). Unfortunately, this time PDF TOOLS did not work.

Sure, you can likely get PDF TOOLS working, but I recommend just skipping them. Emacs 29 has image support baked into it - you just need to be sure you have the appropriate libraries in the bin on Windows. Also, you can direct Emacs to an external Image Magick installation, if you still want to use Image Magick for various operations in dired mode with images, as I do.

Just use Doc View when you're viewing PDFs in a buffer.

Step 1

Install MSYS2 with Chocolatey (or however).

Step 2

Ensure your system has the GCC libraries needed to make programs. MSYS2 uses Pacman Package Manager, not the Advanced Package Tool (APT) programs.

You want to do these installations in the MSYS2 shell, not other bash-ish shells you have on your system [oh-my-zish].

pacman -Sy --needed filesystem msys2-runtime bash libreadline libiconv libarchive libgpgme libcurl pacman ncurses libintl

Step 3

Close bash, restart, and run Pacman again.

pacman -Su

Step 4

Install the libraries you need to make Emacs-29. This list may have some extras, 'dbus' and 'image-magick,' for example, but with these libraries you should be good. Note: mingw-w64-x86_64-libgccjit, which gives you native compilation capability.

pacman -Su autoconf autogen automake automake-wrapper diffutils git guile libgc libguile libltdl libunistring  make mingw-w64-x86_64-binutils mingw-w64-x86_64-bzip2 mingw-w64-x86_64-cairo mingw-w64-x86_64-cloog mingw-w64-x86_64-crt-git mingw-w64-x86_64-dbus mingw-w64-x86_64-expat mingw-w64-x86_64-fontconfig mingw-w64-x86_64-freetype mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-libs mingw-w64-x86_64-gdk-pixbuf2 mingw-w64-x86_64-gettext mingw-w64-x86_64-giflib mingw-w64-x86_64-glib2 mingw-w64-x86_64-gmp mingw-w64-x86_64-gnutls mingw-w64-x86_64-harfbuzz mingw-w64-x86_64-headers-git mingw-w64-x86_64-imagemagick mingw-w64-x86_64-isl mingw-w64-x86_64-libcroco mingw-w64-x86_64-libffi mingw-w64-x86_64-libgccjit mingw-w64-x86_64-libiconv  mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libpng mingw-w64-x86_64-librsvg mingw-w64-x86_64-libtiff mingw-w64-x86_64-libwinpthread-git mingw-w64-x86_64-libxml2 mingw-w64-x86_64-mpc mingw-w64-x86_64-mpfr mingw-w64-x86_64-pango mingw-w64-x86_64-pixman mingw-w64-x86_64-winpthreads mingw-w64-x86_64-xpm-nox mingw-w64-x86_64-lcms2 mingw-w64-x86_64-xz mingw-w64-x86_64-zlib tar wget

Step 5

Use whatever GIT program you want to clone Emacs 29 into whatever repo you want to build Emacs in. I build it off E:/emacs-29/, but you could put it in programs or somewhere off your user directory. Of course you create that directory and navigate to it in the shell you will call GIT from.

git clone emacs-29

Step 6

Because you used GIT to clone the repo, you better disable that autocrlf program or it may mess with your GCC configure file!

git config core.autocrlf false

Step 7

If you are not building from a release source tarball, i.e. if you followed the directions above, run autogen to generate the configure script (in your Emacs-29 root directory!).

Note: run the next code and the code after it in the MSYS2 shell, not any other shell you used to clone Emacs.


Step 8

The shell should say, "you may now run configure." If it doesn't, figure out why and get back to this spot.

Step 9

Run configure. Be sure to set the prefix directory to the root directory you are making into. Also, note arguments: --with-native-compilation, --without-dbus, --with-imagemagick, --without-pop.

Note the image-magick library is included here. You can test your program with Image Magick and PDF TOOLS and see if it works for you. You can't use, however, DBUS on Windows, and if you ever want to use a non-secure POP3 mail system, you better get rid of that POP library!

./configure --prefix=/c/emacs-29 --with-native-compilation --with-gnutls --with-jpeg --with-png --with-rsvg --with-tiff --with-wide-int --with-xft --with-xml2 --with-xpm --without-dbus --with-imagemagick --without-pop

Step 10

Time to make your Emacs executable. But first, better get the number of cores on your computer. I think you can run 'nproc' in Windows or Bash.

After 'nproc' lists your computer's cores, use the '-jx' argument to make your program, where x equals double your number of cores.


./make -j16

The above command makes Emacs 29 into ./src directory in the make directory, our root directory.

Step 11

Now install Emacs 29. 'make install' puts executables into the root directory you're working in. 'make install --prefix=/c/somewhere' can put it somewhere else; if, for example, you want it in programs or something.

make install

Step 12

You need to put some libraries in the bin of your installed Emacs 29 directory. Find and download them on the internet and paste them in there. I used the libraries listed below.

Obviously, make install will have put Emacs executables in the bin also, so I show those.



Step 13

Now you can set up a shortcut to runemacs.exe or emacsclientw.exe. The server, or 'daemon,' runs in the background. The client connects to the server eliminating load time.

If you will run Emacs as a server on start-up, create scheduled tasks to start the daemon and the client in the task manager. Set the daemon to start on launch and create a desktop shortcut to start the client.

Daemon schedule task runs on Windows start-up

start a programc:\emacs-29\bin\runemacs.exe –daemon

Emacs client is configured through scheduler also

Create a scheduled task to launch the client to connect to the daemon. This way it launches with an elisp function when the clients starts. You can test combining this step and the next step into just one shortcut.

This part is tricky, because the Emacs daemon on Windows launches in a shell, with no GUI, and keys in Emacs can only be bound when Emacs starts with a GUI.

Since playing Emacs like a custom built piano is one of the major reasons you use it, you will want to create a function in your .emacs files to bind all the key bindings that need binding when you start emacs from a daemon.

Keep an eye on Reading World Magazine Emacs posts to find an example of that function. In the future, you may need to use the search function to find our Emacs posts.

start a programc:\emacs-29\bin\emacsclientw.exe -n -c -a "" -e “(client-rebind-keys)”

Start-emacs-client runs when shortcut clicked

Now create a shortcut on the desktop and set the target to start the scheduled task above. The final argument in quotations is the name of the scheduled task.

desktop shortcutC:\Windows\System32\schtasks.exe /run /tn “start-emacs-client”

An easy alternative

You might find it easier to launch Emacs from a desktop shortcut that starts Emacs when clicked and directs it to load your initial init.el. Your init.el will then start the process of managing your tangled org-babel code.

desktop shortcutC:\emacs-29\bin\runemacs.exe -q –load “C:\emacs-29\init.el”

Step 14

Install your usual Emacs libraries from list-packages (or with use-package :ensure t argument) and get back to your workflow.

If you've done this before, it might take you the day (or two with any relevant additional research).

But if you're entirely new to Emacs, I highly recommend getting some decent advice.

Like a lot of tech consulting, a good Emacs consultation can save you years.

Closing Notes

This post is the result of a resuable research pipeline, but there is a lot of value here.

If you've gained from this, pay it forward.

Donate to save the Dolphins.

And/or, if you'd like to reward me personally for helping you out, hire me or send me a referral through Build Hello

Finally, you're always welcome to

That’s all for now…