webview / webview_go

Go language bindings for the webview library.
MIT License
215 stars 38 forks source link

Support for EventToken.h on mingw64 #45

Open W1M0R opened 4 months ago

W1M0R commented 4 months ago

@SteffenL Sorry for bringing this up again, because I know you have answered this question so many times:

  1. https://github.com/webview/webview_go/issues/40
  2. https://github.com/webview/webview_go/issues/32#issuecomment-1994886418
  3. https://github.com/webview/webview_go/issues/21#issuecomment-1855110818
  4. https://github.com/webview/webview_go/issues/20#issuecomment-1855112766
  5. https://github.com/webview/webview_go/issues/20#issuecomment-1855114803
  6. https://github.com/webview/webview_go/issues/17#issuecomment-1831236249
  7. https://github.com/webview/webview_go/issues/8#issuecomment-1732569840

I have a suggestion that might add better support for mingw64. Here are a few examples I want to present:

  1. https://learn.microsoft.com/en-us/windows/win32/api/eventtoken/
  2. https://github.com/microsoft/win32metadata/blob/main/generation/WinSDK/RecompiledIdlHeaders/winrt/EventToken.h
  3. https://learn.microsoft.com/en-us/windows/win32/api/eventtoken/ns-eventtoken-eventregistrationtoken
  4. https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-headers/include/eventtoken.h
  5. https://github.com/ziglang/zig/blob/9be8a9000faead40b1aec4877506ff10b066659c/lib/libc/include/any-windows-any/eventtoken.h#L4
  6. https://github.com/search?q=eventtoken.h&type=code&p=2

Here is a screenshot of the file on my local system:

image

The associated verbose build output:

TERM='dumb' x86_64-w64-mingw32-g++ -I . -m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=$WORK/b500=/tmp/go-build -gno-record-gcc-switches -I $WORK/b500/ -I/nix/store/57s2nhck96xz82vpdq92jkii9c1q2bdq-mingw-w64-x86_64-w64-mingw32-11.0.1-headers/include -I/home/user/go/pkg/mod/github.com/webview/webview_go@v0.0.0-20240220051247-56f456ca3a43/libs/webview/include -DWEBVIEW_STATIC -DWEBVIEW_EDGE -std=c++14 -I/home/user/go/pkg/mod/github.com/webview/webview_go@v0.0.0-20240220051247-56f456ca3a43/libs/mswebview2/include -frandom-seed=Isb35zOTZ8oW2P-K900j -o $WORK/b500/_x004.o -c webview.cc
# github.com/webview/webview_go
In file included from /home/user/go/pkg/mod/github.com/webview/webview_go@v0.0.0-20240220051247-56f456ca3a43/libs/webview/include/webview.h:2076,
                 from webview.cc:1:
/home/user/go/pkg/mod/github.com/webview/webview_go@v0.0.0-20240220051247-56f456ca3a43/libs/mswebview2/include/WebView2.h:978:10: fatal error: EventToken.h: No such file or directory
  978 | #include "EventToken.h"
      |          ^~~~~~~~~~~~~~
compilation terminated.

The important part in the above output is the additional header location added via -I/nix/store/57s2nhck96xz82vpdq92jkii9c1q2bdq-mingw-w64-x86_64-w64-mingw32-11.0.1-headers/include, so that eventtoken.h will be available for include.

It looks like the convention for referencing the "EventToken.h" header with the mingw-64 compilation toolchain, is to use lowercase, e.g. <eventtoken.h>. The Windows API docs itself also refers to this header in lowercase. However, searching GitHub, I can see that both variants are used.

What I'm trying to figure out, is whether this generated file (https://github.com/webview/webview_go/blob/master/libs/mswebview2/include/WebView2.h) could somehow be patched to use a lowercase include of eventtoken.h, and whether that would still work for non-mingw builds.

@SteffenL Do you have insight in how WebView2.h is generated and whether somewhere in the process a lowercase include of eventtoken.h can be used (if not for every toolchain, then specifically for the mingw toolchain)?

SteffenL commented 4 months ago

Thanks for your detailed description!

I agree that eventtoken.h should be preferred over EventToken.h.

I've checked my Ubuntu 22.04 environment and mingw-w64 doesn't have the header there; however, on Ubuntu 24.04 the header is located at /usr/share/mingw-w64/include/eventtoken.h.

I believe the WebView2.h header is generated with MIDL from the WebView2.idl file which is also included in the WebView2 SDK. I recall unsuccessfully attempting to generate the header file using WIDL quite a while ago.

I can pull a few ideas with varied quality from the top of my head:

I'm not originally a Go developer so ideas are much appreciated.

W1M0R commented 4 months ago

I see the webview project has this file: https://github.com/webview/webview/blob/93be13a101e548c13d47ae36a6ea00300b2ecfc0/webview_mingw_support.h

#ifndef WEBVIEW_MINGW_SUPPORT_H
#define WEBVIEW_MINGW_SUPPORT_H
#ifdef _WIN32

// Some MinGW distributions do not have the EventToken.h header (used by WebView2).
// Define the things used by WebView2 from the EventToken.h header if needed.
#if defined(__has_include)
#if !defined(WEBVIEW_HAVE_EVENTTOKEN_H) && __has_include(<EventToken.h>)
#include <EventToken.h>
#define WEBVIEW_HAVE_EVENTTOKEN_H
#endif
#if !defined(WEBVIEW_HAVE_EVENTTOKEN_H) && defined(__eventtoken_h__)
#define WEBVIEW_HAVE_EVENTTOKEN_H
#endif
#if !defined(WEBVIEW_HAVE_EVENTTOKEN_H)
#include <cstdint>
typedef struct EventRegistrationToken {
  int64_t value;
} EventRegistrationToken;
#endif
#endif

#endif /* _WIN32 */
#endif /* WEBVIEW_MINGW_SUPPORT_H */

It looks like there is some kind of __has_include function. Maybe something equivalent could be done for the go binding? This is similar in spirit to the first two approaches that you mentioned (maintain/wrap EventToken.h).

Your thought process in this pull request feels like it could work for the go binding as well: https://github.com/webview/webview/pull/957

I'm just not sure how this would be done. If a custom EventToken.h is kept alongside WebView2.h, then it will probably always be included due to the include "EventToken.h" (i.e. the double quotes would prefer the locally maintained EventToken.h). But as you indicated, if the locally maintained EventToken.h is just a wrapper (i.e. using some of the methods shown in your pull request and the code extract above), then it may be possible to #include <EventToken.h> or #include <eventtoken.h> (i.e. the angle brackets would prefer the system headers) within the wrapper. The wrapper could also do more specific checks for mingw64 (https://mingw-w64-public.narkive.com/vPnBj4FG/detect-mingw), e.g. using the built-in defines __MINGW64__, __MINGW32__, __MINGW64_VERSION_MAJOR.