2019年09月29日

解决emacs 27.0.50的lwindow无效问题

<lwindow>键不知何故被emacs 27.0.50 和 26.3给吞了,怎么配置都不管用,使用emacs时不能按 win+D*、 *win+R 很不方便,所以提了一个bug。

在windows上编译emacs x64的文章转载,修改参考了 http://chriszheng.science/2015/03/19/Chinese-version-of-Emacs-building-guideline/

原来就一直都用zklhp的sourceforge上的版本。谢谢zklhp!

下载x86_64版的MSYS2,MinGW-w64

https://sourceforge.net/projects/msys2/files/Base/x86_64

配置

去掉了mail的支持,反正也不用

pacman -S base-devel mingw-w64-x86_64-toolchain \
mingw-w64-x86_64-xpm-nox mingw-w64-x86_64-libtiff \
mingw-w64-x86_64-giflib mingw-w64-x86_64-libpng \
mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-librsvg \
mingw-w64-x86_64-libxml2   

获得源码

现在Emacs的版本管理已经转为Git,获取源码已经很方便了。

pacman -S git

# [2019-09-26 周四 09:55:08]
# 只下载trunk的最新的吧,否则太大了。
cd /e/workspace/emacs_src
git clone --depth 1 git://git.sv.gnu.org/emacs.git

https://www.cnblogs.com/pansidong/p/11294128.html git clone时加上–depth 1

Git自动改换行符的功能(autocrlf)很讨厌,关掉它:

cd /e/workspace/emacs_src/emacs
git config core.autocrlf false

编译

运行C:\msys64里的mingw64_shell.bat,注意必须是它,这会启动一个MinGW-w64的环境。在这个窗口里切换到源码所在的目录,运行下面的命令编译Emacs并且安装到C:\emacs。如果是从开发版编译,第一行是必须的,否则

[2019-09-26 Thu 10:04] mingw64不在PATH里面啊

Albert@Albert MSYS /e/workspace/emacs_src/emacs
$ export PATH=/mingw64/bin:$PATH
./autogen.sh
PKG_CONFIG_PATH=/mingw64/lib/pkgconfig ./configure --host=x86_64-w64-mingw32 \
--target=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --with-wide-int \
--with-jpeg --with-xpm --with-png --with-tiff --with-rsvg --with-xml2 \
--without-imagemagick
make
make install prefix=/e/emacs

[2019-09-26 Thu 10:20] 不知道为什么build system type = x86_64-pc-msys, make会报错 ./configure 太慢了,run一次要10分钟

checking build system type... x86_64-pc-msys
checking host system type... x86_64-w64-mingw32

# 修改一下试试
#+BEGIN_SRC sh
PKG_CONFIG_PATH=/mingw64/lib/pkgconfig ./configure --host=x86_64-w64-mingw32 \
--with-wide-int \
--without-dbus \
--without-compress-install -C 'CFLAGS=-O2 -static -g3' \
--with-jpeg --with-xpm --with-png --with-tiff --with-rsvg --with-xml2 \
 --with-gnutls=ifavailable \
--without-imagemagick

[2019-09-26 Thu 10:53] 终于开始make了 [2019-09-26 Thu 12:09] make了一个小时啊

如果成功的话C:\emacs目录里就有编译好的Emacs了。因为编译的时候用了很多由第三方库提供的功能, 所以我们编译的这个Emacs是需要那些DLL才能运行的。如果你的系统里面MSYS2已经被添加到PATH环境变量里(例如PATH里包含了C:\msys2\mingw64\bin)了这不是问题,但如果环境变量里没有或者你想在其他电脑上用,需要用下面的命令复制所需的DLL到Emacs所在目录:

target="/e/emacs/bin"
cp /mingw64/bin/{libwinpthread-*.dll,libXpm-noX*.dll,libdbus-*.dll} $target
cp /mingw64/bin/{libgomp-*.dll,libgcc_s_seh-*.dll,libglib-*.dll} $target
cp /mingw64/bin/{libintl-*.dll,libiconv-*.dll,libgobject-*.dll} $target
cp /mingw64/bin/{libffi-*.dll,libgdk_pixbuf-*.dll,libgio-*.dll} $target
cp /mingw64/bin/{libgmodule-*.dll,zlib*.dll,librsvg-*.dll} $target
cp /mingw64/bin/{libcairo-*.dll,libcroco-*.dll,libpango-*.dll} $target
cp /mingw64/bin/{libpangocairo-*.dll,libxml2-*.dll,libfontconfig-*.dll} $target
cp /mingw64/bin/{libfreetype-*.dll,libpixman-*.dll,libpng*.dll} $target
cp /mingw64/bin/{libpangoft*.dll,libpangowin32-*.dll,liblzma-*.dll} $target
cp /mingw64/bin/{libexpat-*.dll,libharfbuzz-*.dll,libgnutls-*.dll} $target
cp /mingw64/bin/{libgnutlsxx-*.dll,libtiff-*.dll,libtiffxx-*.dll} $target
cp /mingw64/bin/{libjpeg-*.dll,libgif-*.dll,libbz2-*.dll,libjbig-*.dll} $target
cp /mingw64/bin/{libgmp-*.dll,libhogweed-*.dll,libnettle-*.dll} $target
cp /mingw64/bin/{libp11-kit-*.dll,libtasn1-*.dll} $target

话说谁能告诉我上面的命令如何优雅的写出来

Cloud Han回复说可以用下面的命令 我还没有试 先记录下来

cp $( pacman -Ql mingw-w64-x86_64-{libtiff,giflib,libpng,libjpeg-turbo,librsvg,libxml2,gnutls} | grep bin/.*\.dll$ | awk '{print $2}' ) <path_to_emacs_bin>

双击C:\emacs\bin目录里的runemacs.exe,如果没有错误,你已经成功编译了一个64位的GNU Emacs。

lwindow问题定位

[2019-09-26 Thu 16:44] 下午定位 bug在 http://git.savannah.gnu.org/cgit/emacs.git/commit/src/w32term.h?id=97d7a0b8db4ce32a8e489dec48634b7e85212eaa

在代码里grep keyword VK_LWINlwindow ,代码逻辑在w32fns.c里面。重点是 funhook() 函数。

修改了w32fns.c/w32inevt.c,但是没有效果,唉

编译时,先 rm temacs.exe ,再编译,否则make会报错。

[2019-09-29 Sun 10:06] bug的邮件来来回回了10来个,搞了4~5天,把git上最新代码下来,编译,w32fns.c改了n个地方,就是不行。

在折腾了大半个上午以后,终于发现为什么emacs26.3和27.0.50的lwindow+x的组合键不正常的原因了。360安全卫士拦截了emacs的按键模拟

  1. debug时 使用gdb debug时由于emacs在w32fns.c中会判断,如果debug时是不hook键盘的,键盘输入会直接发给系统,所以是正常的。

    为什么不hook时就正常,hook时就不正常?是VK_LWIN变了,键盘布局变了?都说不过去啊。git上没看见相关代码有变化。键盘布局一样的,emacs 26.2就ok。

  2. 没有debug时 正常启动的emacs会hook住键盘。然后根据情况模拟按键,再通过windows的api SendInput()发送按键。在网上查SendInput函数的时候,看见有blog提到360安全卫士的问题,在自己的机器上查了拦截日志。果然有log记录拦截了emacs的模拟按键,再360中增加了信任目录后ok了。

    唉,https://blog.csdn.net/foruok/article/details/53283620 Windows按键(VK_LWIN和VK_RWIN)死活出不来,查半天发现是360安全卫士的问题。它的驱动防护拦截了这个按键发送调用。