成功倒是成功了,不过算是比较 hack,毕竟 Emacs 没有专门提供 Windows 上的 clang 编译支持:
和 ucrt64 和 mingw64 相比,基础步骤没区别:
pacman -Syu
pacman -S git
pacman -S texinfo
git config --global core.autocrlf false
git clone https://github.com/emacs-mirror/emacs --depth 1
安装软件时要装 clang 和 ncurses:
pacman -S "${MINGW_PACKAGE_PREFIX}-autotools"
pacman -S "${MINGW_PACKAGE_PREFIX}-clang"
pacman -S "${MINGW_PACKAGE_PREFIX}-gnutls"
pacman -S "${MINGW_PACKAGE_PREFIX}-make"
pacman -S "${MINGW_PACKAGE_PREFIX}-ncurses"
配置步骤也有些变化,需要指定编译器和 host:
./autogen.sh
./configure --with-native-compilation=no --host=x86_64-w64-mingw32 CC=clang
make -j20
到了这一步编译时,会出现如下错误(照理说 Mingw-w64 是实现了 nanosleep 的):
一种解决方法是注释掉 nt/gnulib-cfg.mk
里面的这两行:
然后编译就可以成功了:
但这个解决办法挺抽象的,应该有更好的方法,而且我也不知道实际用起来怎么样。(sys_select 在 w32proc.c 里面实现了,但不注释掉 sys_select 那一行会编译失败)
更新 ,在 ucrt64 环境下安装 pacman -S mingw-w64-ucrt-x86_64-clang
然后:
./configure --with-native-compilation=no CC=clang
make -j20
能够直接成功,没有 CLANG64 中出现的错误,这可能是因为只用了编译器,库环境还是 ucrt64:
* While there also exists a Clang package in the MINGW environments, that one still uses the GNU linker and the GNU C++ library. In some cases Clang is used to build packages as well there, in case upstream prefers Clang over GCC for example.
Environments - MSYS2
同样是 ucrt64 环境,gcc 和 clang 编译最后得到的 emacs.exe 体积差距似乎有点大…
拿 GNU ELPA - elisp-benchmarks 试了一下,似乎是没什么区别:
测试方法是下载 elisp-benchmarks,解压然后添加路径到 load-path 里面,然后执行以下命令:
(setq gc-cons-threshold (* 1024 1024)) ;; 1MB
(elisp-benchmarks-run nil nil)
CPU: AMD Ryzen 5 7640HS, RAM: 32GB
OS: Windows 11 23H2 22631.4037
emacs-mirror/emacs@4f1987c
gcc.exe (Rev1, Built by MSYS2 project) 14.2.0
“GNU Emacs 31.0.50 (build 1, x86_64-w64-mingw32) of 2024-08-18”
UCRT 环境编译的 Emacs 得到如下结果:
* Results
| test | non-gc avg (s) | gc avg (s) | gcs avg | tot avg (s) | tot avg err (s) |
|--------------------+----------------+------------+---------+-------------+-----------------|
| bubble | 3.13 | 6.00 | 426 | 9.13 | 0.08 |
| bubble-no-cons | 8.46 | 0.05 | 3 | 8.51 | 0.03 |
| bytecomp | 2.81 | 1.99 | 127 | 4.80 | 0.04 |
| dhrystone | 3.37 | 0.00 | 0 | 3.37 | 0.11 |
| eieio | 1.49 | 2.36 | 161 | 3.85 | 0.12 |
| fibn | 2.09 | 0.00 | 0 | 2.09 | 0.03 |
| fibn-named-let | 2.58 | 0.00 | 0 | 2.58 | 0.10 |
| fibn-rec | 2.78 | 0.00 | 0 | 2.78 | 0.12 |
| fibn-tc | 2.62 | 0.00 | 0 | 2.62 | 0.03 |
| flet | 6.78 | 0.00 | 0 | 6.78 | 0.02 |
| font-lock | 0.63 | 0.44 | 29 | 1.06 | 0.03 |
| inclist | 10.67 | 0.00 | 0 | 10.67 | 0.11 |
| inclist-type-hints | 10.70 | 0.00 | 0 | 10.70 | 0.09 |
| listlen-tc | 2.61 | 0.00 | 0 | 2.61 | 0.03 |
| map-closure | 5.53 | 0.00 | 0 | 5.53 | 0.03 |
| nbody | 2.42 | 10.91 | 768 | 13.33 | 0.04 |
| pack-unpack | 0.34 | 0.61 | 42 | 0.95 | 0.01 |
| pack-unpack-old | 1.02 | 1.12 | 78 | 2.14 | 0.02 |
| pcase | 5.58 | 0.00 | 0 | 5.58 | 0.15 |
| pidigits | 4.65 | 7.67 | 390 | 12.32 | 0.55 |
| scroll | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| smie | 1.32 | 0.74 | 45 | 2.06 | 0.04 |
|--------------------+----------------+------------+---------+-------------+-----------------|
| total | 81.57 | 31.88 | 2070 | 113.44 | 0.65 |
MINGW64 环境编译的 Emacs 得到如下结果:
* Results
| test | non-gc avg (s) | gc avg (s) | gcs avg | tot avg (s) | tot avg err (s) |
|--------------------+----------------+------------+---------+-------------+-----------------|
| bubble | 3.08 | 5.41 | 368 | 8.49 | 0.17 |
| bubble-no-cons | 8.44 | 0.05 | 3 | 8.49 | 0.16 |
| bytecomp | 2.77 | 1.83 | 113 | 4.60 | 0.08 |
| dhrystone | 3.40 | 0.00 | 0 | 3.40 | 0.13 |
| eieio | 1.44 | 2.11 | 144 | 3.56 | 0.04 |
| fibn | 2.10 | 0.00 | 0 | 2.10 | 0.14 |
| fibn-named-let | 2.54 | 0.00 | 0 | 2.54 | 0.14 |
| fibn-rec | 2.83 | 0.00 | 0 | 2.83 | 0.03 |
| fibn-tc | 2.64 | 0.00 | 0 | 2.64 | 0.01 |
| flet | 6.92 | 0.00 | 0 | 6.92 | 0.02 |
| font-lock | 0.64 | 0.42 | 27 | 1.06 | 0.01 |
| inclist | 10.76 | 0.00 | 0 | 10.76 | 0.22 |
| inclist-type-hints | 10.61 | 0.00 | 0 | 10.61 | 0.08 |
| listlen-tc | 2.61 | 0.00 | 0 | 2.61 | 0.03 |
| map-closure | 5.56 | 0.00 | 0 | 5.56 | 0.08 |
| nbody | 2.50 | 10.16 | 686 | 12.66 | 0.08 |
| pack-unpack | 0.34 | 0.56 | 37 | 0.90 | 0.01 |
| pack-unpack-old | 1.03 | 1.07 | 70 | 2.10 | 0.01 |
| pcase | 5.61 | 0.00 | 0 | 5.61 | 0.16 |
| pidigits | 5.02 | 7.29 | 348 | 12.31 | 1.11 |
| scroll | 0.00 | 0.00 | 0 | 0.00 | 0.00 |
| smie | 1.48 | 0.74 | 41 | 2.22 | 0.04 |
|--------------------+----------------+------------+---------+-------------+-----------------|
| total | 82.32 | 29.64 | 1837 | 111.96 | 1.20 |
关键的统计数据就是最后的两行
;; UCRT
| total | 81.57 | 31.88 | 2070 | 113.44 | 0.65 |
;; MSVCRT
| total | 82.32 | 29.64 | 1837 | 111.96 | 1.20 |
可能就性能测试上来说,UCRT 和 MSVCRT 没什么太大的区别…
另外,我顺便测了下 29.2 和 31.0.50 的 fib,Emacs 30 的 GC 似乎提升不少,但是解释性能似乎不如 29(不过这个测试并没什么说服力,太简单了)
(progn
(defun fib (n)
(pcase n
(0 0)
(1 1)
(_ (+ (fib (1- n)) (fib (- n 2))))))
(setq gc-cons-threshold (* 1024 1024))
(let ((res))
(push (benchmark-run 100 (fib 25)) res)
(byte-compile 'fib)
(push (benchmark-run 1000 (fib 25)) res)
(reverse res)))
在 29.2 和 31.0.50 下分别有如下结果:
;; 29.2
((15.779528 145 9.951868000000005) (6.902092000000001 0 0.0))
;; 31.0.50
((12.034346 741 6.412244000000001) (8.215974000000001 0 0.0))
(注:如果要用 elisp-benchmarks
测的话,最好每跑一次就重启一下 runemacs.exe -Q)
这个提升应该就是 30 的 GC 改进带来的,从上面的测试来看,同样的代码,GC 的次数变多但是总时间下降了,和运行时的改变没太大关系。
2 个赞
LdBeth
2024 年8 月 19 日 09:25
23
include-yy:
ncurses
为啥要这个,不用终端版本可以不装么?
性能差不多我估计是因为跑字节码没有多少系统调用,比不出来很正常
在 clang64 环境下,没有装似乎没办法通过编译。
可以试试不装这个,然后根据 configure 的输出装其他的。
LdBeth
2024 年8 月 20 日 02:57
25
编译了一份 ucrt+native comp 出来,体感确实比 29.2 好不少
4 个赞
ltylty
2024 年8 月 20 日 05:46
26
今天重新体验了一下,是要快一些。
用scoop安装,不要装emacs-k,emacs-k安装到C:\Program Files\WindowsApps目录。
建议装emacs-kl,emacs-kl安装在scoop目录下。速度比emacs-k更快,我也不知道为啥。
scoop install emacs-kl
对,但全面的测试有点难搞,我就借 native-comp 作者的 benchmark 随便跑跑了。
Windows app是运行在受控环境中,性能会差些,安全性更好。emacs-kl 就是原生exe,性能更好。
1 个赞
这个我之前看日本有些博客折腾过,是可以的,只不过比较麻烦。让官方编译的 Windows 版 Emacs 29.2 的 native-comp 特性生效
这个得像官方提供的预编译版本一样,把 Emacs.exe 要用到的 dll 库全都放到 Emacs 安装(也就是 make install 的那个目录)目录的 bin
下,也得一个一个弄很麻烦。
Windows Defender 算是 Emacs 在 Windows 上慢的一个很大原因,不管是编译还是运行。
0af
2024 年8 月 21 日 05:05
31
看来得写一个辅助工具,递归检查 exe 和 dll 依赖的 dll 了。
没办法,Windows 不装杀毒软件就等于给黑客当筛子。
kiennq最近编译出来emacs.exe真是小呀
1 个赞
这个问题讨论得很多嘛。随便说几个,一,大部分 linux 软件是从可信任的包管理器安装的,而 Windows 软件不是。二,linux 软件大多都是开源的,开源多少能增加软件代码被人审查的机会。三,不像 Windows 软件大多拥有全盘的访问权限,linux 有手段可以严格限制一个软件访问哪些目录。还有很多原因,也有一些是劣势。其中最关键的大概是很少有不安全源下载的软件这一点了。
2 个赞
linug入手门槛比windows高,并且linux大多数情况下都是使用包管理器安装,windows用户更倾向于去网站下载exe,另外就是系统文件权限的问题,windows下的管理员权限被滥用也不是一天两天的了
好奇怪啊,上面的那个构建我使用就莫名其妙的高CPU,用你说的这个就正常,而且速度确实提升不少
主要原因还是因为 linux 的用户水平大部分都比较高,不会像小白那样随便找个 exe 不管三七二十一直接双击运行。要是 linux 成了主流的桌面系统,然后到处都是闭源野包不知道哪里来的 deb 满天飞,那一样安全性是个问题。
没那么麻烦,用 Process Explorer - Sysinternals 很容易就能找到 EXE 加载了什么 dll:
打开 Process Explorer 之后可以打开 Lower Pane(菜单 View → Show Lower Pane 或者 Ctrl + L),然后在上面选中 Emacs.exe 即可。或者使用菜单里面的 Find 然后搜索 emacs。
3 个赞
0af
2024 年8 月 22 日 09:37
39
这个是检查正在运行的 Process,看起来应该比 ldd
效果更好。
我找找它有没有 CLI 接口,如果有的话就可以方便地集成进打包脚本和 CI/CD 里了。
找到了:
P.S. 这个工具的作者好像现在是 Azure 的 CTO 吧?
title: Process Explorer
description: Find out what files, registry keys and other objects processes have open, which DLLs they have loaded, and more.
ms:assetid: '32cbeee6-4335-44d5-b94b-160612b99738'
ms:mtpsurl: 'https://technet.microsoft.com/Bb896653(v=MSDN.10)'
ms.date: 05/28/2024
adobe-target: true
---
# Process Explorer v17.06
**By Mark Russinovich**
Published: May 28, 2024
[![Download](media/shared/Download_sm.png)](https://download.sysinternals.com/files/ProcessExplorer.zip) [**Download Process Explorer**](https://download.sysinternals.com/files/ProcessExplorer.zip) **(3.3 MB)**
**Run now** from [Sysinternals Live](https://live.sysinternals.com/procexp.exe).
<br><br>
> [!VIDEO https://www.microsoft.com/en-us/videoplayer/embed/RE5d5Rd?autoplay=true&loop=true&controls=false]
<sup><i>Created with [ZoomIt](zoomit.md)</i></sup>
## Introduction
1 个赞
对对,这是一个重要原因。我只是举些例子~ 覆盖不全还望海纳。