emacs 30.1リリースのニュースを見かけて 久しぶりに emacsを使ってみようかなと。
方針とか
インストーラを使わない様にしたいので、emacsは Zipから展開します。
native compileを有効にして使ってみたいのですが、MSYS2をインストールしたくありません。
このため、MSYS2のパッケージのうち native compile に必要なものだけを emacs環境専用に手動展開します。
環境と必要なもの
- Windows11 x86_64
- zip/tar.zstの展開ツール(私は7z.exeを利用しました)
ダウンロードと展開
ダウンロードしたファイルは %HOME%\.local\emacs
へ展開することにしました。
emacs本体
emacs公式 から 近くのミラー で emacs-30.1.zip
をダウンロードします。
これは普通に展開するだけでOKです。
gccの入手と展開
Native Compileには gcc が必要なのですが、公式のアーカイブには
必要なコンパイラ、ライブラリが含まれていないため追加します。
このページの File: の欄にある…
をダウンロードします。
Emacs本体とは違い、MSYS2向けのパッケージです。
基本ダウンロードしたパッケージの mingw64 以下を Emacsと同じ場所へ展開します。
gccの依存パッケージの入手
gcc と同様に以下のパッケージもEmacsと同じ場所へ展開します。
私には、どこまで必要なのかが判断付きませんでしたので、gccが依存するパッケージは全部追加しています。
ただ、.elnファイルは基本的なライブラリ以外に依存していないように見えます。
Lispの Native Compileだけを目的とした場合かなり(ほとんど?)ダイエットできると思います。
gcc の依存関係には、以下も含まれているが これらはなくても .eln が生成されたので多分問題なさそうです。気になる方は合わせて入れても良いかと思います。
また、binutilsはさらに以下のパッケージにも依存しています。こちらも気になる方は合わせて入れてください。
- https://packages.msys2.org/base/mingw-w64-gettext
- https://packages.msys2.org/packages/mingw-w64-x86_64-iconv
- https://packages.msys2.org/packages/mingw-w64-x86_64-libiconv
なお、windows-default-manifestがあれば、普通に .c をコンパイルして .exe が作れます。Headersがあれば、普通に使える GCC環境になるかと思いますが、セキュリティ上は無い方が良いかなと思っています1。
mingw-w64-x86_64-gcc-libsは dllしか含まず、Emacs本体が必要とする dllファイルは emacs本体に含まれています。パッケージには追加で以下のdllが含まれています。
- gcc-libs
- libatomic-1.dll
- libgomp-1.dll
- libquadmath-0.dll
Emacs本体に含まれないという意味ではgmpにも追加のdllが存在します。
- gmp
- libgmpxx-4.dll
crtの入手についての注意
crt-gitパッケージは 4.5MBほどで 1000ファイル弱含まれています。
私の環境では、このファイルを Microsoft Defenderでスキャンすると、なぜか無限ループに陥ってスキャン済みファイル数が増え続けました。MS Defenderを使っている方は注意してください。ブラウザを使ったダウンロードもダウンロード後にScanが終わるまで完了としないので、永遠に終わりません。
curl で取得後に展開し、それを MS Defenderでスキャンする等すればよいかと思います。
libgccjitの入手
Native Compileはさらに libgccjit を必要とします。
これまでと同じように パッケージをダウンロードして展開します。
全部のファイルをダウンロードするバッチファイル
2025/03/01 時点
curl -LOJR http://ftpmirror.gnu.org/emacs/windows/emacs-30/emacs-30.1.zip
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-14.2.0-3-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-binutils-2.44-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-crt-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libs-14.2.0-3-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gmp-6.3.0-2-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-isl-0.27-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpc-1.3.1-2-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpfr-4.2.1-2-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-winpthreads-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libwinpthread-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-zlib-1.3.1-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-zstd-1.5.7-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-headers-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-windows-default-manifest-6.4-4-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gettext-libtextstyle-0.24-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gettext-runtime-0.24-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gettext-tools-0.24-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-iconv-1.18-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libiconv-1.18-1-any.pkg.tar.zst
curl -LOJR https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libgccjit-14.2.0-3-any.pkg.tar.zst
全部のファイルを展開するバッチファイル
emacs-30.1.zip
に付属された dllが更新されてしまうのを防ぎたい場合、最後にemacs-30.1.zipを解凍するとよいかと思います。
MKDIR mingw64
7z x -omingw64 emacs-30.1.zip
REM extract all .tar.zst files
FOR /R %%F IN (*.zst) DO 7z x %%F
FOR /R %%F IN (*.tar) DO 7z x -y %%F
REN mingw64 emacs
中間ファイル等の削除はしませんので適宜削除してください。
解凍されたemacsフォルダを 設置場所に移動して使います
emacs起動用バッチファイルの作成
この記事で作っている emacs環境は、libgccjit以外に mingw64の gcc/binutilsを追加しています。
以下の起動バッチファイルでは emacs 環境に向けたPATHを最優先(先頭)で追加しています。このため、既存で他にgcc等が存在する場合、emacs環境から呼び出したプロセスの gccの実行等に影響を与えます。
少し試してみたところ emacs.exe のある場所に pathを通さないでも一通りファイルがあれば、 Native Compileは正常に動作しました。gccを定常的に使う環境だったり*nix系のコマンドを追加している場合、このバッチファイルは使わない方がよいでしょう。
私は以下のバッチファイルで emacsを起動するようにしています。
@ECHO OFF
SETLOCAL
SET EMACS_HOME=%USERPROFILE%\.local\emacs
SET EMACS_BIN=%EMACS_HOME%\bin
SET PATH=%EMACS_BIN%;%PATH%
START "" "%EMACS_BIN%\runemacs.exe" %*
ENDLOCAL
emacsフォルダを7zで圧縮したところ151MiBのサイズになりました。
他の環境で使うときにはこのファイルを持ち運ぶのが楽に思います。ただ展開すると1GiB超えます。
確認
dir %APPDATA%\.emacs.d\eln-cache\
で コンパイルされた eln ファイルを確認できます。
objdump -x
等でNativeコンパイルされていることが確認できるかと思います。
C:\Users\username\AppData\Roaming\.emacs.d\eln-cache\30.1-50a58833\japanese-0ff63ea1-0f77ab2c.eln: file format pei-x86-64
C:\Users\username\AppData\Roaming\.emacs.d\eln-cache\30.1-50a58833\japanese-0ff63ea1-0f77ab2c.eln
architecture: i386:x86-64, flags 0x0000013b:
HAS_RELOC, EXEC_P, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x0000000361d41320
Characteristics 0x2026
executable
line numbers stripped
large address aware
DLL
いろいろ
まだ全然使っていないのですが、安定して使えるといいなー。
emacs使いだったのですが、Windowsで IMEを使ったときに、たまにハングしてしまうので emacs利用は諦めてNeoVimに移行した過去があります。
あと、デフォルトでは .emacs.d\eln-cache
が %APPDATA%
配下なので、Roaming 対象になります。
このため、Roaming User Profile が有効な環境で x86_64 と armな Windows使うと混乱するんじゃ……?なんて思いました。
-
これ言ったら Native Compile 自体をセキュリティ上避けるべき話な気もします。 ↩