I am building an executable that depends on npcap.
My strategy for depending on it is to link against the npcap-sdk (downloaded using the zig build system as a dependency in build.zig.zon), which is provided as pre-compiled static libraries and headers.
As far as I can tell, these binaries are produced using Visual Studio, which I am guessing means they are MSVC ABI?
Can I cross-compile my executable from x86_64-linux to x86_64-windows-gnu and expect it to work? Why or why not?
As of now, I believe cross compiling from x86_64-linux to x86_64-windows-msvc is impossible because zig does not bundle the MSVC headers.
I don’t know the answer “for sure” but I don’t think this is going to be an easy task. If it were me, I’d probably try instead to write a build.zig file for npcap and compile it to the x86_64-windows-gnu target, that might be less effort and you end up with a better result at the end. Give it a try thought to know for sure, some of it will depend on exactly how they built their libraries, what version of msvc libc did they actually link to. MSVC has MultiThreaded vs NonMultithreaded variants, static vs dynamic linking and Release vs Debug…so I think that gives you about 8 different variations. I’d try linking against it with the GNU target, expect to see linker errors, then maybe try with the MSVC target and see if that even works.
All that said there is another option that might be interesting and I might be willing to help with. I’ve created my own “Visual Studio Installer” in python based on one from Andrei (here’s his Download MSVC compiler/linker & Windows SDK without installing full Visual Studio · GitHub, here’s my latest vsinstall.py · GitHub). I’ve been meaning to open source it and might translate it to Zig…which if I do…means you potentially use it to install the MSVC headers/link libraries on any platform. At that point all you need to do is add a libc configuration to point to the include/library directories…although…it is meant to work with MSVC-only so we’re kind of back to the current problem. Well…maybe the idea will pan out maybe not
Visual Studio already has had the “Visual Studio Build Tools” workload that you can install without installing the IDE, etc. (unless that’s gone away).
You can link MSVC dynamic libraries if they don’t use libc++ (virtually all C libraries, some C++ libraries) and they don’t throw SEH exceptions to user code.
Back then you couldn’t link static libraries between MinGW and MSVC but this may changed. This means that you can’t link dynamic library implibs, and you need to generate implib/use dynamic library loading.
The general advice on Windows is to never exchange C runtime resources (such as FILE* or malloc()'d memory) across DLL boundaries because each DLL can have its own C runtime, and often does. A consequence of this is that you can link *-windows-gnu and *-windows-msvc EXEs/DLLs safely if they don’t exchange any such resources. However, the same is not true of static libraries; there you can run into all sorts of nasty ABI issues.