Skip to content

build failure for c sources that include windows.h when targetting msvc abi #19805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hyphenrf opened this issue Apr 29, 2024 · 10 comments
Closed
Labels
question No questions on the issue tracker, please.

Comments

@hyphenrf
Copy link

hyphenrf commented Apr 29, 2024

Zig Version

0.11.0

Steps to Reproduce and Observed Behavior

fails in these locations under libc/include/any-windows-any:

winnt.h:2815:7: error: unknown type name 'PCONTEXT'
winnt.h:7838:44: error: unknown type name 'PCONTEXT'
minwinbase.h:314:11: error: unknown type name 'PCONTEXT'
processthreadsapi.h:200:69: error: unknown type name 'CONTEXT'
winbase.h:1190:86: error: unknown type name 'PCONTEXT'
winbase.h:3250:42: error: unknown type name 'PCONTEXT'
winbase.h:3250:84: error: unknown type name 'PCONTEXT'
winbase.h:3254:82: error: unknown type name 'PCONTEXT'
winbase.h:3260:52: error: unknown type name 'PCONTEXT'
winbase.h:3261:48: error: unknown type name 'PCONTEXT'
winbase.h:3267:52: error: unknown type name 'PCONTEXT'
stdlib.h:388:47: error: expected ';' after top level declarator
stdlib.h:389:48: error: expected ';' after top level declarator
stdlib.h:396:26: error: expected ';' after top level declarator
stdlib.h:681:69: error: expected ';' after top level declarator
stdlib.h:683:48: error: expected ';' after top level declarator
stdlib.h:684:55: error: expected ';' after top level declarator
malloc.h:123:28: error: use of undeclared identifier '_ALLOCA_S_MARKER_SIZE'
malloc.h:142:34: error: use of undeclared identifier '_ALLOCA_S_MARKER_SIZE'

repro:

$ nix-shell -p zig_0_11
// test.c
#include <windows.h>
int main() {}
// build.zig
const std = @import("std");

pub fn build(b: *std.Build) !void {
    const exe = b.addExecutable(.{
        .name = "test",
        .target = .{ .cpu_arch = .x86, .os_tag = .windows, .abi = .msvc },
        .optimize = .ReleaseSmall,
    });
    exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-w"} }); // cut the warnings noise

    // is this really the best way to get windows.h? :(
    const windows_include_dir = try std.fs.path.resolve(
        b.allocator,
        &.{ std.fs.path.dirname(b.zig_exe).?, "..", "lib/zig/libc/include/any-windows-any" },
    );
    exe.addIncludePath(.{ .path = windows_include_dir });

    b.installArtifact(exe);
}
$ zig build

Expected Behavior

it builds

@hyphenrf hyphenrf added the bug Observed behavior contradicts documented or intended behavior label Apr 29, 2024
@alexrp
Copy link
Member

alexrp commented Apr 29, 2024

To my knowledge, cross-compiling for the MSVC ABI from non-Windows is not supported. You need to use the GNU ABI instead. If you do that, you also don't need to mess with include paths like this.

@hyphenrf
Copy link
Author

hyphenrf commented Apr 29, 2024

switching to .abi = .gnu, and commenting out the custom include path logic, windows.h was not found
uncommenting the custom include path logic, it seems to not fail on syntactic issues, but rather linkage ones (I forgot to link libc in my original recipe)
adding linkLibC() to the recipe, it successfully builds :)

const std = @import("std");

pub fn build(b: *std.Build) !void {
    const exe = b.addExecutable(.{
        .name = "test",
        .target = .{ .cpu_arch = .x86, .os_tag = .windows, .abi = .gnu },
        .optimize = .ReleaseSmall,
    });
    exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-w"} });
    const windows_include_dir = try std.fs.path.resolve(
        b.allocator,
        &.{ std.fs.path.dirname(b.zig_exe).?, "..", "lib/zig/libc/include/any-windows-any" },
    );
    exe.addIncludePath(.{ .path = windows_include_dir });
    exe.linkLibC();
    b.installArtifact(exe);
}

final build.zig

so it seems the issue is now reduced to msvc abi (with a side of include path unpleasantness).

@hyphenrf hyphenrf changed the title build failure for c sources that include windows.h build failure for c sources that include windows.h when targetting msvc abi Apr 29, 2024
@hyphenrf
Copy link
Author

does building it like this incur an incompatibility with windows systems that have no knowledge of mingw, by the way?

@squeek502
Copy link
Collaborator

squeek502 commented Apr 29, 2024

You can remove

    // is this really the best way to do it :(
    const windows_include_dir = try std.fs.path.resolve(
        b.allocator,
        &.{ std.fs.path.dirname(b.zig_exe).?, "..", "lib/zig/libc/include/any-windows-any" },
    );

now that you have linkLibC():

const std = @import("std");

pub fn build(b: *std.Build) !void {
    const dll = b.addSharedLibrary(.{
        .name = "test",
        .target = .{ .cpu_arch = .x86, .os_tag = .windows, .abi = .gnu },
        .optimize = .ReleaseSmall,
    });
    dll.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-w"} });
    dll.linkLibC();

    b.installArtifact(dll);
}

In the future, questions like this should be directed towards one of the community spaces first.

@squeek502 squeek502 closed this as not planned Won't fix, can't repro, duplicate, stale Apr 29, 2024
@squeek502 squeek502 added question No questions on the issue tracker, please. and removed bug Observed behavior contradicts documented or intended behavior labels Apr 29, 2024
@hyphenrf
Copy link
Author

hyphenrf commented Apr 29, 2024

oops you're right! I could swear I tried linkLibC before, but maybe with the abi unchanged that's why it didn't work.
edit: just confirmed, when all is the same but the abi is set to msvc, zig can't find windows.h

nevertheless, the two open issues I found on my initial search (#11926, #6003) seemed marginally related and rather old. neither reported errors similar to the ones I had here. so I figured it'd be worth reporting as an issue. the original issue stands: a build failure when targeting msvc abi and including windows.h

@squeek502 if that's not applicable and deserves the wontfix for some reason, please let me know

@squeek502
Copy link
Collaborator

Targeting the msvc ABI means using the MSVC includes, which cannot be distributed by Zig due to their licensing. Zig can find MSVC includes if they are installed on Windows, but not on other host systems.

For example, this would succeed on Windows if you have the MSVC/SDK includes installed:

const std = @import("std");

pub fn build(b: *std.Build) !void {
    const dll = b.addSharedLibrary(.{
        .name = "test",
        .target = .{ .cpu_arch = .x86, .os_tag = .windows, .abi = .msvc },
        .optimize = .ReleaseSmall,
    });
    dll.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-w"} });
    dll.linkLibC();

    b.installArtifact(dll);
}

The most relevant issue is probably #6565

@marler8997
Copy link
Contributor

@squeek502 we might be able to leverage win32metadata/zigwin32 to generate includes compatible with MSVC headers...?

@squeek502
Copy link
Collaborator

squeek502 commented Apr 30, 2024

I think headers are just one component, would also need .lib files, etc (basically, everything that MinGW provides, so I think the task would effectively become 'create a MSVC-identical MinGW alternative').

@marler8997
Copy link
Contributor

If you're talking about the link lib files, those are trivially easy to generate. Much easier than the header files.

@hyphenrf
Copy link
Author

hyphenrf commented Apr 30, 2024

in the interim, a more informative error message when using the msvc abi in target may be worth having I think (with the exception of native-native-msvc, already indicating we're using the system sdk)
afaik custom error messages are already present when pointing at other targets, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question No questions on the issue tracker, please.
Projects
None yet
Development

No branches or pull requests

4 participants