Subject: bug#45303: #45303 [feature/native-comp] building error on Windows

From: Pal Gloss <[email-masked]>
Date: Fri, 18 Dec 2020 23:21:44 +0100

I retried building with the most recent feature/native-comp branch and if you
skip to the last code block, you can see how I managed to build emacs with it
and use it (I've been using a similar build on Win10 for about 2 days).  I can
confirm that my previous hack for =nt/epaths.nt= is not needed anymore.

#+begin_src shell :exports code
git rev-parse HEAD feature/native-comp
#+end_src

: 87f6e937995c433825173fb0473a801791d5beac
: 87f6e937995c433825173fb0473a801791d5beac

#+begin_src shell :exports code
gcc --version
#+end_src

: gcc.exe (Rev6, Built by MSYS2 project) 10.2.0
: Copyright (C) 2020 Free Software Foundation, Inc.
: This is free software; see the source for copying conditions.  There is NO
: warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

First trying without any hacking:
#+begin_src shell :exports code
pacman -S --needed 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-lcms2 \
mingw-w64-x86_64-jansson \
mingw-w64-x86_64-libxml2 \
mingw-w64-x86_64-gnutls \
mingw-w64-x86_64-zlib \
mingw-w64-x86_64-harfbuzz \
mingw-w64-x86_64-libgccjit
PROCESSORS_TO_USE="3"
EMACS_VERSION=emacs-native-comp
./autogen.sh
mkdir -p ../build
cd ../build
../emacs/configure \
--with-xml2 \
--without-pop \
--prefix="/home/cramaph1/$EMACS_VERSION/dest" \
--without-compress-install \
--without-dbus \
--with-nativecomp \
--with-modules 'CFLAGS=-O2 -g3'
make -j"$PROCESSORS_TO_USE"
#+end_src

Results in this output (man lines elided, some markers added for my future explanations):
#+begin_example
# snip ... 8< ... snip ... 8< ...
CC       comp.o
CC       dynlib.o
../../emacs/src/comp.c: In function 'Fcomp__compile_ctxt_to_file':
../../emacs/src/comp.c:4458:12: warning: unused variable 'oldset' [-Wunused-variable]
4458 |   sigset_t oldset;
|            ^~~~~~
../../emacs/src/comp.c: In function 'eln_load_path_final_clean_up':
../../emacs/src/comp.c:4621:29: warning: passing argument 1 of 'internal_condition_case_4' from incompatible pointer type [-Wincompatible-pointer-types]
4621 |  internal_condition_case_4 (Fdirectory_files,
|                             ^~~~~~~~~~~~~~~~
|                             |
|                             struct Lisp_X * (*)(struct Lisp_X *, struct Lisp_X *, struct Lisp_X *, struct Lisp_X *, struct Lisp_X *)
In file included from ../../emacs/src/comp.c:23:
../../emacs/src/lisp.h:4160:47: note: expected 'struct Lisp_X * (*)(struct Lisp_X *, struct Lisp_X *, struct Lisp_X *, struct Lisp_X *)' but argument is of type 'struct Lisp_X * (*)(struct Lisp_X *, struct Lisp_X *, struct Lisp_X *, struct
Lisp_X *, struct Lisp_X *)'
4160 | extern Lisp_Object internal_condition_case_4 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));
|                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CC       process.o
# snip ... 8< ... snip ... 8< ...
CC       callproc.o
../../emacs/src/callproc.c: In function 'call_process':
../../emacs/src/callproc.c:916:17: warning: implicit declaration of function 'strsignal'; did you mean 'xsignal'? [-Wimplicit-function-declaration]
916 |       signame = strsignal (WTERMSIG (status));
|                 ^~~~~~~~~
|                 xsignal
../../emacs/src/callproc.c:916:17: warning: nested extern declaration of 'strsignal' [-Wnested-externs]
../../emacs/src/callproc.c:916:15: warning: assignment to 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
916 |       signame = strsignal (WTERMSIG (status));
|               ^
# snip ... 8< ... snip ... 8< ...
CC       w32menu.o
CC       w32reg.o
../../emacs/src/w32menu.c: In function 'set_frame_menubar':
../../emacs/src/w32menu.c:326:2: warning: 'memcpy' offset [3, 10] from the object at '<unknown>' is out of the bounds of referenced subobject 'contents' with type 'struct Lisp_X *[]' at offset 3 [-Warray-bounds]
326 |  memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
|  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
327 |   previous_menu_items_used * word_size);
|   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../emacs/src/w32menu.c:26:
../../emacs/src/lisp.h:1623:17: note: subobject 'contents' declared here
1623 |     Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
|                 ^~~~~~~~
CC       w32font.o
# snip ... 8< ... snip ... 8< ...
CC       w32.o
CC       w32console.o
CC       w32heap.o
CC       w32inevt.o
CC       w32proc.o
CC       w32image.o
../../emacs/src/w32.c: In function '_sys_read_ahead':
../../emacs/src/w32.c:8790:10: warning: 'rc' may be used uninitialized in this function [-Wmaybe-uninitialized]
8790 |   if (rc == sizeof (char))
|       ~~~^~~~~~~~~~~~~~~~
CC       fontset.o
# snip ... 8< ... snip ... 8< ...
CCLD     temacs.exe
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: comp.o: in function `md5_gz_stream':
C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/comp.c:713: undefined reference to `inflateInit2_'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/comp.c:730: undefined reference to `inflate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/comp.c:741: undefined reference to `inflateEnd'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/comp.c:741: undefined reference to `inflateEnd'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: comp.o: in function `declare_imported_func':
C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/comp.c:973: undefined reference to `gcc_jit_type_get_const'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: process.o: in function `status_message':
C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/process.c:754: undefined reference to `strsignal'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: callproc.o: in function `call_process':
C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/callproc.c:916: undefined reference to `strsignal'
collect2.exe: error: ld returned 1 exit status
make[1]: *** [Makefile:661: temacs.exe] Error 1
make[1]: Leaving directory '/home/cramaph1/emacs-native-comp/build/src'
make: *** [Makefile:434: src] Error 2
#+end_example

Retrying (with hacks/patches to fix "../../emacs/src/comp.c:4621:29" and
"C:\msys64\home\cramaph1\emacs-native-comp\build\src/../../emacs/src/comp.c:713:
undefined reference to `inflateInit2_'" and other linker errors):
#+begin_src shell :exports code
cd ../emacs
rm -rf ../build
git restore .
# patch to adapt to (new) 5th parameter to directory-files
sed -i -e '/internal_condition_case_4/,/FOR_EACH/ {
s/internal_condition_case_4/internal_condition_case_5/
s/Qt, return_nil);/Qnil, Qt, return_nil);/
}' \
src/comp.c
sed -i -e '/extern Lisp_Object internal_condition_case_4/a extern Lisp_Object internal_condition_case_5 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));' src/lisp.h
sed -i -e '/Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as/ {
s/ARG4 as/ARG4, ARG5 as/
a    its arguments.  */
a Lisp_Object
a internal_condition_case_5 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object,
a                                                 Lisp_Object, Lisp_Object,
a                                                 Lisp_Object),
a                            Lisp_Object arg1, Lisp_Object arg2,
a                            Lisp_Object arg3, Lisp_Object arg4,
a                            Lisp_Object arg5,
a                            Lisp_Object handlers,
a                            Lisp_Object (*hfun) (Lisp_Object))
a {
a   struct handler *c = push_handler (handlers, CONDITION_CASE);
a   if (sys_setjmp (c->jmp))
a     {
a       Lisp_Object val = handlerlist->val;
a       clobbered_eassert (handlerlist == c);
a       handlerlist = handlerlist->next;
a       return hfun (val);
a     }
a   else
a     {
a       Lisp_Object val = bfun (arg1, arg2, arg3, arg4, arg5);
a       eassert (handlerlist == c);
a       handlerlist = c->next;
a       return val;
a     }
a }
a /* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as
}' src/eval.c
mkdir -p ../build
cd ../build
../emacs/configure \
--with-xml2 \
--without-pop \
--prefix="/home/cramaph1/$EMACS_VERSION/dest" \
--without-compress-install \
--without-dbus \
--with-nativecomp \
--with-modules 'CFLAGS=-O2 -g3'
# fix linker errors by making sure the correct libraries are added to the linker command
sed -i -e 's/^LIBGCCJIT = *$/LIBGCCJIT = -lz -lgccjit/' src/Makefile
make -j"$PROCESSORS_TO_USE"
#+end_src

This allows the build to progress much further (I still see the warnings about
strsignal during the compilation, though,
e.g. "../../emacs/src/callproc.c:916:17", but not during the linking), to
#+begin_example
./temacs --batch  -l loadup --temacs=pbootstrap \
--bin-dest /home/cramaph1/emacs-native-comp/dest/bin/ --eln-dest "/home/cramaph1/emacs-native-comp/dest/lib/emacs/28.0.50/"
Loading loadup.el (source)...
Dump mode: pbootstrap
# snip ... 8< ... snip ... 8< ...
Dumping under the name bootstrap-emacs.pdmp
Dumping fingerprint: 2c36b7fa02d1a33e038a3cd004d3be5ad3cf1286ad3174e3b48e8ebd34535a96
Dump complete
Byte counts: header=100 hot=8039500 discardable=166920 cold=4821304
Reloc counts: hot=443956 discardable=5041
make -C ../lisp compile-first EMACS="../src/bootstrap-emacs.exe"
# snip ... 8< ... snip ... 8< ...
ELC+ELN   ../../emacs/lisp/term/w32-win.elc
# snip ... 8< ... snip ... 8< ...
Debugger entered--Lisp error: (error "Cannot find libgccjit")
signal(error ("Cannot find libgccjit"))
error("Cannot find libgccjit")
comp-ensure-native-compiler()
batch-byte-native-compile-for-bootstrap()
command-line-1(("--eval" "(setq load-prefer-newer t)" "-l" "comp" "-f" "byte-compile-refresh-preloaded" "-f" "batch-byte-native-compile-for-bootstrap" "../../emacs/lisp/term/w32-win.el"))
command-line()
normal-top-level()

make[2]: *** [Makefile:297: ../../emacs/lisp/term/w32-win.elc] Error 127
make[1]: *** [Makefile:797: ../../emacs/lisp/term/w32-win.elc] Error 2
#+end_example

Indeed, if I do =find /mingw64 -name libgccjit\*dll=, I only get
=/mingw64/bin/libgccjit-0.dll= as result.  That files comes from
mingw-w64-x86_64-libgccjit, as shown by =pacman -Qo /mingw64/bin/libgccjit-0.dll=.

So I try again, but now also patching in libgccjit-0.dll to replace libgccjit.dll.
#+begin_src shell :exports code
cd ../emacs
rm -rf ../build
git restore .
# patch to adapt to (new) 5th parameter to directory-files
sed -i -e '/internal_condition_case_4/,/FOR_EACH/ {
s/internal_condition_case_4/internal_condition_case_5/
s/Qt, return_nil);/Qnil, Qt, return_nil);/
}' \
src/comp.c
sed -i -e '/extern Lisp_Object internal_condition_case_4/a extern Lisp_Object internal_condition_case_5 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));' src/lisp.h
sed -i -e '/Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as/ {
s/ARG4 as/ARG4, ARG5 as/
a    its arguments.  */
a Lisp_Object
a internal_condition_case_5 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object,
a                                                 Lisp_Object, Lisp_Object,
a                                                 Lisp_Object),
a                            Lisp_Object arg1, Lisp_Object arg2,
a                            Lisp_Object arg3, Lisp_Object arg4,
a                            Lisp_Object arg5,
a                            Lisp_Object handlers,
a                            Lisp_Object (*hfun) (Lisp_Object))
a {
a   struct handler *c = push_handler (handlers, CONDITION_CASE);
a   if (sys_setjmp (c->jmp))
a     {
a       Lisp_Object val = handlerlist->val;
a       clobbered_eassert (handlerlist == c);
a       handlerlist = handlerlist->next;
a       return hfun (val);
a     }
a   else
a     {
a       Lisp_Object val = bfun (arg1, arg2, arg3, arg4, arg5);
a       eassert (handlerlist == c);
a       handlerlist = c->next;
a       return val;
a     }
a }
a /* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as
}' src/eval.c
# patch to look for libgccjit-0.dll instead of libgcc.dll in lisp/term/w32-win.el & src/emacs.c
sed -i -e 's/libgccjit.dll/libgccjit-0.dll/' lisp/term/w32-win.el
sed -i -e 's/libgccjit.dll/libgccjit-0.dll/' src/emacs.c
mkdir -p ../build
cd ../build
../emacs/configure \
--with-xml2 \
--without-pop \
--prefix="/home/cramaph1/$EMACS_VERSION/dest" \
--without-compress-install \
--without-dbus \
--with-nativecomp \
--with-modules 'CFLAGS=-O2 -g3'
# fix linker errors by making sure the correct libraries are added to the linker command
sed -i -e 's/^LIBGCCJIT = *$/LIBGCCJIT = -lz -lgccjit/' src/Makefile
make -j"$PROCESSORS_TO_USE"
#+end_src

Now I get a crash with a backtrace:
#+begin_example
Backtrace:
00000004001afb22
00000004000b40a6
00000004000ccc64
000000040020a4ca
00007ff9e5f58040
00007ff9e6181847
00007ff9e614a881
00007ff9e61804b6
make[2]: *** [Makefile:297: ../../emacs/lisp/term/w32-win.elc] Error 3
make[1]: *** [Makefile:797: ../../emacs/lisp/term/w32-win.elc] Error 2
make[1]: Leaving directory '/home/cramaph1/emacs-native-comp/build/src'
make: *** [Makefile:434: src] Error 2
#+end_example

This crash is due to the =#pragma GCC diagnostic= around a =if
(gcc_jit_global_set_initializer)=: see this example program where the
=#pragma= around the =if(...)= makes it into a separate statement from the
={...}= body.  Apparently, on my machine, =gcc_jit_global_set_initializer= is
NULL but the body gets executed anyway.
#+begin_src c :exports code
/* save as /tmp/t.c, then run (cd /tmp && gcc t.c && ./a.exe) */
/* It should print nothing at all, but on my machine, it prints

This should not be printed, but will be printed anyway (2).

This is gcc.exe (Rev6, Built by MSYS2 project) 10.2.0 */
#include <stdio.h>

int main() {
if (0)
{
printf("This will not be printed (1).\n");
}

#pragma GCC diagnostic ignored "-Waddress"
if (0)
#pragma GCC diagnostic pop
{
printf("This should not be printed, but will be printed anyway (2).\n");
}

#pragma GCC diagnostic ignored "-Waddress"
if (0)
{
#pragma GCC diagnostic pop
printf("This should not be printed (3).\n");
}
return 0;
}
#+end_src

So I try again, this time inverting the =#pragma GCC diagnostic pop= and the ={= lines, too:
#+begin_src shell :exports code
cd ../emacs
rm -rf ../build
git restore .
# patch to avoid gcc_jit_global_set_initializer (crashes on my machine...; it
# seems there is an interaction with the #pragma and the rest of the parsing
# because the statement is incomplete?) and to adapt to (new) 5th parameter to
# directory-files
sed -i -e '/if (gcc_jit_global_set_initializer)/,/{/ {
/#pragma GCC diagnostic pop/d
/{/a #pragma GCC diagnostic pop
}' \
-e '/internal_condition_case_4/,/FOR_EACH/ {
s/internal_condition_case_4/internal_condition_case_5/
s/Qt, return_nil);/Qnil, Qt, return_nil);/
}' \
src/comp.c
sed -i -e '/extern Lisp_Object internal_condition_case_4/a extern Lisp_Object internal_condition_case_5 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));' src/lisp.h
sed -i -e '/Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as/ {
s/ARG4 as/ARG4, ARG5 as/
a    its arguments.  */
a Lisp_Object
a internal_condition_case_5 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object,
a                                                 Lisp_Object, Lisp_Object,
a                                                 Lisp_Object),
a                            Lisp_Object arg1, Lisp_Object arg2,
a                            Lisp_Object arg3, Lisp_Object arg4,
a                            Lisp_Object arg5,
a                            Lisp_Object handlers,
a                            Lisp_Object (*hfun) (Lisp_Object))
a {
a   struct handler *c = push_handler (handlers, CONDITION_CASE);
a   if (sys_setjmp (c->jmp))
a     {
a       Lisp_Object val = handlerlist->val;
a       clobbered_eassert (handlerlist == c);
a       handlerlist = handlerlist->next;
a       return hfun (val);
a     }
a   else
a     {
a       Lisp_Object val = bfun (arg1, arg2, arg3, arg4, arg5);
a       eassert (handlerlist == c);
a       handlerlist = c->next;
a       return val;
a     }
a }
a /* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as
}' src/eval.c
# patch to look for libgccjit-0.dll instead of libgcc.dll in lisp/term/w32-win.el & src/emacs.c
sed -i -e 's/libgccjit.dll/libgccjit-0.dll/' lisp/term/w32-win.el
sed -i -e 's/libgccjit.dll/libgccjit-0.dll/' src/emacs.c
mkdir -p ../build
cd ../build
../emacs/configure \
--with-xml2 \
--without-pop \
--prefix="/home/cramaph1/$EMACS_VERSION/dest" \
--without-compress-install \
--without-dbus \
--with-nativecomp \
--with-modules 'CFLAGS=-O2 -g3'
# fix linker errors by making sure the correct libraries are added to the linker command
sed -i -e 's/^LIBGCCJIT = *$/LIBGCCJIT = -lz -lgccjit/' src/Makefile
make -j"$PROCESSORS_TO_USE"
make install
#+end_src

The build and =make install= succeeded, so I run the newly built emacs, but I get error messages in =*Asyng-native-compile-log*:
#+begin_example
Warning: arch-dependent data dir '%emacs_dir%/libexec/emacs/28.0.50/x86_64-w64-mingw32/': No such file or directory
#+end_example

When I do <F1> v exec-directory, I see
#+begin_example
exec-directory is a variable defined in ‘C source code’.
Its value is "%emacs_dir%/libexec/emacs/28.0.50/x86_64-w64-mingw32/"

This variable may be risky if used as a file-local variable.
Probably introduced at or before Emacs version 16.

Documentation:
Cannot open doc string file "DOC"
#+end_example

So I try a last time, adding conditional code to relocate =exec-directory= on Windows:
#+begin_src shell :exports code
cd ../emacs
rm -rf ../build
git restore .
# patch to avoid gcc_jit_global_set_initializer (crashes on my machine...; it
# seems there is an interaction with the #pragma and the rest of the parsing
# because the statement is incomplete?) and to adapt to (new) 5th parameter to
# directory-files
sed -i -e '/if (gcc_jit_global_set_initializer)/,/{/ {
/#pragma GCC diagnostic pop/d
/{/a #pragma GCC diagnostic pop
}' \
-e '/internal_condition_case_4/,/FOR_EACH/ {
s/internal_condition_case_4/internal_condition_case_5/
s/Qt, return_nil);/Qnil, Qt, return_nil);/
}' \
src/comp.c
sed -i -e '/extern Lisp_Object internal_condition_case_4/a extern Lisp_Object internal_condition_case_5 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));' src/lisp.h
sed -i -e '/Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as/ {
s/ARG4 as/ARG4, ARG5 as/
a    its arguments.  */
a Lisp_Object
a internal_condition_case_5 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object,
a                                                 Lisp_Object, Lisp_Object,
a                                                 Lisp_Object),
a                            Lisp_Object arg1, Lisp_Object arg2,
a                            Lisp_Object arg3, Lisp_Object arg4,
a                            Lisp_Object arg5,
a                            Lisp_Object handlers,
a                            Lisp_Object (*hfun) (Lisp_Object))
a {
a   struct handler *c = push_handler (handlers, CONDITION_CASE);
a   if (sys_setjmp (c->jmp))
a     {
a       Lisp_Object val = handlerlist->val;
a       clobbered_eassert (handlerlist == c);
a       handlerlist = handlerlist->next;
a       return hfun (val);
a     }
a   else
a     {
a       Lisp_Object val = bfun (arg1, arg2, arg3, arg4, arg5);
a       eassert (handlerlist == c);
a       handlerlist = c->next;
a       return val;
a     }
a }
a /* Like internal_condition_case_1 but call BFUN with ARG1, ARG2, ARG3, ARG4 as
}' src/eval.c
# patch to look for libgccjit-0.dll instead of libgcc.dll in lisp/term/w32-win.el & src/emacs.c
sed -i -e 's/libgccjit.dll/libgccjit-0.dll/' lisp/term/w32-win.el
sed -i -e 's/libgccjit.dll/libgccjit-0.dll/' src/emacs.c
# patch to fix the %emacs_dir% issue in exec-path at runtime
sed -i -e '/PATH_EXEC, 0);/ {
s/.*/#ifdef WINDOWSNT/
a /* On MS-Windows, PATH_EXEC normally starts with a literal
a    "%emacs_dir%", so it will never work without some tweaking. */
a w32_relocate (PATH_EXEC),
a #else
a PATH_EXEC,
a #endif
a 0);
}' src/callproc.c
mkdir -p ../build
cd ../build
../emacs/configure \
--with-xml2 \
--without-pop \
--prefix="/home/cramaph1/$EMACS_VERSION/dest" \
--without-compress-install \
--without-dbus \
--with-nativecomp \
--with-modules 'CFLAGS=-O2 -g3'
# fix linker errors by making sure the correct libraries are added to the linker command
sed -i -e 's/^LIBGCCJIT = *$/LIBGCCJIT = -lz -lgccjit/' src/Makefile
make -j"$PROCESSORS_TO_USE"
make install
#+end_src

And now emacs 28.0.50 seems to work (there are some compilation issues with

hyperbole, but my config is usable). If I do =M-: (apropos-value
’("%emacs_dir%") nil)=, I still see these directories that look fishy, but
<F1> i works for me at the moment.
#+begin_example
Info-default-directory-list
("%emacs_dir%/share/info/")
----------------
configure-info-directory
"%emacs_dir%/share/info"
#+end_example

Sorry for the wall of text, I am just trying to show that I built up my
hacks/patches step by step and make sure they are still needed.