How to use msvc abi on windows

hello i wanted to make a d3d11 example in zig using the new translate-c the following is the translate c part of my build.zig

    const target = b.standardTargetOptions(.{});
     if (target.result.os.tag == .windows) {
         target = b.resolveTargetQuery(.{
             .abi = .msvc,
             .os_tag = .windows,
         });
     }
    const optimize = b.standardOptimizeOption(.{});

    const cwin32 = b.addTranslateC(.{
        .root_source_file = b.path("src/c/win32.h"),
        .target = target,
        .optimize = optimize,
    });
    cwin32.linkSystemLibrary("user32", .{});
    cwin32.linkSystemLibrary("gdi32", .{});
    cwin32.linkSystemLibrary("d3d11", .{});
    cwin32.linkSystemLibrary("dxgi", .{});
    cwin32.linkSystemLibrary("d3dcompiler", .{});

when using the mingw/gnu abi if fails to find d3dcompiler lib
when using msvc abi (my prefered option) it fails with the following error
error: coff does not support linking multiple objects into one.

am i not doing something correctly or is it a current limitation of zig ?

I am guessing that mingw provides some kind of package config for d3dcompiler that is not available in msvcrt.
A possible fix might be to use the actual dll name in linkSystemLibrary
i.e. "d3dcompiler_47" or whatever the name of the dll actually is.

d3dcompiler_47 fixes the issue on the mingw/gnu abi as it’s now able to find the dll.
on msvc side however it can’t find the dll using this name.

read: Not So Direct Setup | Games for Windows and the DirectX SDK blog
see also: HLSL, FXC, and D3DCompile | Games for Windows and the DirectX SDK blog

On a windows system with the latest Windows 10 SDK installed (from Visual Studio) the files are included in C:\Program Files (x86)\Windows Kits\10

> fd d3dcompiler
Include\10.0.26100.0\um\d3dcompiler.h
Include\10.0.26100.0\um\d3dcompiler.inl
Lib\10.0.26100.0\um\arm64\d3dcompiler.lib
Lib\10.0.26100.0\um\x64\d3dcompiler.lib
Lib\10.0.26100.0\um\x86\d3dcompiler.lib
Redist\D3D\arm64\d3dcompiler_47.dll
Redist\D3D\x64\d3dcompiler_47.dll
Redist\D3D\x86\d3dcompiler_47.dll
bin\10.0.26100.0\arm64\d3dcompiler_47.dll
bin\10.0.26100.0\x64\d3dcompiler_47.dll
bin\10.0.26100.0\x86\d3dcompiler_47.dll

Note that there is a d3dcompiler.lib so your initial version was correct for msvcrt.
That means that your system is not configured to use the visual studio locations or you did not install the Windows 10(/11) SDK or the dlls are not in your PATH.

Normally zig autodetects the installation. You can verify it using:

❯ zig libc
# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.51.36231\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.51.36231\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

To install the SDK from visual studio, look in individual components:

If the PATH does not include C:\Program Files (x86)\Windows Kits\10\bin you can either add it or copy the files from redist into your application folder.

Ok so i finally managed to get both msvc and gnu abi compilation to work and i wanted to reply to document the steps needed for msvc specifically because it was the most difficult to get working.

By the way i’m on zig 0.16.0

Gnu ABI

This the one that the zig compiler picks by default when you don’t specify a target flag on windows platform.

The problem was that d3dcompiler library had different name d3dcompiler_47 upon using this the build should work.

MSVC ABI

Getting this one to work was very hard first off the arro-c compiler that is used to translate c code to zig code throws an error if you use the msvc abi, the only solution is to use a separate target for the translateC step like this

    // On windows force msvc toolchain
    const default_target:std.Target.Query = if(builtin.os.tag == .windows) .{
        .os_tag = .windows,
        .abi = .msvc,
    } else .{};

    const optimize = b.standardOptimizeOption(.{});
    const target = b.standardTargetOptions(.{.default_target = default_target });
    const header_target = b.resolveTargetQuery(.{
        .abi = .gnu,
        .os_tag = .windows,
        .cpu_arch = target.result.cpu.arch,
    });
    const main = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    if(target.result.os.tag == .windows){
        // -- win32api --
        const cwin32 = b.addTranslateC(.{
            .root_source_file = b.path("src/c/win32.h"),
            .target = header_target,
            .optimize = optimize,
        });
        main.addImport("cwin32", cwin32.createModule());
        main.linkSystemLibrary("user32", .{});
        main.linkSystemLibrary("gdi32", .{});
        main.linkSystemLibrary("d3d11", .{});
        main.linkSystemLibrary("dxgi", .{});
        main.linkSystemLibrary("dxguid", .{});
        main.linkSystemLibrary(if (target.result.abi == .msvc) "d3dcompiler" else "d3dcompiler_47", .{});
        
    }

Also on msvc abi you shouldn’t call linkSystemLibrary on the result of addTranslateC because that also produces an error. so it’s better to call it on the main module directly.

Also thanks to @dimdin for the help.