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

From: Andrea Corallo <[email-masked]>
Date: Sat, 19 Dec 2020 07:57:10 +0000

Pal Gloss <[email-masked]> writes:

> 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

[...]

>   # 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

Okay this should be fixed by now.

>   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

Nice :)

While reporting the bug in GCC I've found this previous bugzilla report.

<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92696>

Interesting... should work now.

>   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

Should be fixed too.

[...]

> 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

Right so (unless I'm forgetting something) just the zlib linker error
should be remaining, correct?

I'll have a look later in the weekend or Monday.

> 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.

Thanks for the precise analysis this is very helpful.

The Windows port is a bit rusty, I believe nobody compiled it since 6+
months, is good we resurrect it and keep it running.

  Andrea