Cross-compiling for Windows: What is the difference between `-gnu` and `-msvc`?

When cross-compiling for windows from linux, what is the difference between using targets:

  1. zig build -Dtarget=native-windows-gnu
  2. zig build -Dtarget=native-windows-msvc

?

It appears that -msvc is impossible to do from linux if I need to link libc, because I would need to install the windows sdk on linux which is impossible?

Targeting the msvc ABI means using the headers/libraries from the Windows SDK/MSVC. Those are under a proprietary license which means that they cannot be distributed. When targeting msvc, Zig attempts to find the location of those headers/libraries using techniques similar to those used in vswhere (registry lookups, etc). This means that the msvc target will effectively only work when the host system is Windows (and the host system needs the SDK/MSVC files installed separately from Zig).

MinGW (which is what the gnu ABI means when targeting Windows) is an effort to provide those same headers/libraries (in terms of ABI-compatibility) that can actually be distributed, and Zig in turn does distribute them. This means that Zig is able to target the gnu ABI for Windows from any host system (and that capability only depends on the Zig installation itself).

So, basically, if you want cross-compilation for Windows targets and are linking libc, then you’ll want to get things working with the gnu ABI.

Here’s an issue from when Zig switched the default Windows ABI from msvc to gnu:

6 Likes

I’ve had success cross compiling for MSVC from Linux by using the scripts in this git repo:
https://github.com/mstorsjo/msvc-wine

I used it to compile a DLL which was injected into a Windows application running under wine. Seems like it would be useful to you :slight_smile:

3 Likes
1 Like

Or alternative use xwin to get WinSDK+MSCRT includes and libraries, like: GitHub - kassane/xwin-zig-test: Testing Zig with xwin - Microsoft CRT headers and libraries + Windows SDK headers and libraries

1 Like