Skip to content

mingw: support -municode#19399

Merged
andrewrk merged 3 commits intoziglang:masterfrom
ypsvlq:mingw
Mar 28, 2024
Merged

mingw: support -municode#19399
andrewrk merged 3 commits intoziglang:masterfrom
ypsvlq:mingw

Conversation

@ypsvlq
Copy link
Copy Markdown
Contributor

@ypsvlq ypsvlq commented Mar 22, 2024

fixes #18621, fixes #9924

also rename mingwex to mingw32, which feels more appropriate as it contains the basic C runtime code

@squeek502
Copy link
Copy Markdown
Member

squeek502 commented Mar 23, 2024

Nice work, thanks for getting this fixed! Tested and confirmed this fixes the minimal reproduction in #18621 (comment).

wWinMain also works when using zig cc:

#include <windows.h>

int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PWSTR cmdline, int cmdshow) {
    return 0;
}
zig cc -o test-wwinmain-cc.exe test-wwinmain.c -lc -municode -Wl,--subsystem,windows
> dumpbin /headers test-wwinmain-cc.exe
...
            1180 entry point (0000000000401180) WinMainCRTStartup
...
               2 subsystem (Windows GUI)
...

But is there an intended way to provide -municode when using zig build-exe?

zig build-exe -cflags -municode -- test-wwinmain.c -lc --subsystem windows

doesn't seem to work

@ypsvlq
Copy link
Copy Markdown
Contributor Author

ypsvlq commented Mar 23, 2024

fixed

@squeek502
Copy link
Copy Markdown
Member

squeek502 commented Mar 23, 2024

Great! One last thing to make this maximally usable is integration with build.zig. I've added that + a standalone test and submitted it as a PR to your branch here: ypsvlq#1


For future reference, after this PR, here's how to build a C file with all possible entry points using zig build-exe (add -target x86_64-windows-gnu if cross compiling):

zig build-exe main.c -lc

zig build-exe wmain.c -lc -municode

zig build-exe winmain.c -lc

zig build-exe wwinmain.c -lc -municode

(can add --subsystem windows to set the subsystem for the WinMain/wWinMain versions but it's not strictly necessary)

See the added standalone test for the build.zig equivalent.

Copy link
Copy Markdown
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ypsvlq. One small change needed and then this is ready to land.

I'm confused why #18621 is marked as a regression when the fix requires adding a new feature (the -municode flag). How did it used to work?

@squeek502
Copy link
Copy Markdown
Member

squeek502 commented Mar 26, 2024

I'm confused why #18621 is marked as a regression when the fix requires adding a new feature (the -municode flag). How did it used to work?

There are two parts to that issue (and this PR):

  • The regression is that if WinMain is defined, it isn't detected/recognized when targeting MinGW and the linker fails with undefined symbol: main. In particular, this comment has a reproduction of only the regression
  • The -municode part of this PR is to support wmain/wWinMain which I don't think has ever been fully supported before when targeting MinGW (at least I couldn't get wWinMain to work with 0.11.0)

@ypsvlq can better clarify which parts of this PR address one or the other.


One thing I'd be interested in is if it's at all feasible to make MinGW recognize wWinMain/wmain without needing an explicit CLI flag (e.g. this is the case when targeting MSVC--it will use wWinMain without any CLI flags needed and without needing UNICODE defined AFAICT). Currently with this PR, these are functionally equivalent:

> zig build-exe wwinmain.c -target x86_64-windows-msvc -lc
> dumpbin /headers /nologo wwinmain.exe
           A9AB0 entry point (00000000004A9AB0) wWinMainCRTStartup
               2 subsystem (Windows GUI)

(both the entry point and the subsystem are inferred)

> zig build-exe wwinmain.c -target x86_64-windows-gnu -lc -municode --subsystem windows
> dumpbin /headers /nologo wwinmain.exe
            11A0 entry point (00000000004011A0) WinMainCRTStartup
               2 subsystem (Windows GUI)

(without -municode, the linker errors with undefined symbol: WinMain; without --subsystem windows, the subsystem is 3 subsystem (Windows CUI))

@ypsvlq
Copy link
Copy Markdown
Contributor Author

ypsvlq commented Mar 26, 2024

How did it used to work?

The version of mingw used in 0.11 includes the WinMain startup code in crtexe.c, in later versions it has been moved to a separate file which wasn't included in Zig. As far as I can tell wWinMain was never supported.

@chawyehsu
Copy link
Copy Markdown

This is great! Thanks @ypsvlq for working on it! And I believe it will also close #9924 , in which unicode entry points support against mingw was reported missing the first time I guess.

@ypsvlq ypsvlq requested a review from andrewrk March 27, 2024 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zig doesn't detect wWinMain symbol in C files. zig c++ fails to compiles windows with wWinMain/wmain when windows.h is imported

4 participants