Includes nested too deeply on Windows VM?

I am trying to use Zig on a Windows 10 virtual machine, and I get rather mystifying error when zig running a hello world:

In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
In file included from zig\lib\libc\mingw\lib-common\ntdll.def.in:1:
zig\lib\libc\mingw\lib-common\ntdll.def.in:1:10: error: #include nested too deeply
#include "func.def.in"

(and that seems to happen for a bunch of different dlls)

Anyone saw something similar? Any way to fix/debug this further?

That’s zig 0.11

have you tried with a more recent version of the compiler ? If I remember correctly from reading issues on github, the embedded C compiler can be flaky with header file parsing, so maybe that’s related, sorry to not answer your question directly, but I would advise you to try another version or take your chance in the discord :slight_smile:

ntdll.lib is missing and it’s trying to produce it from .def files.
.def.in files are preprocessed using the C preprocessor.
The related code is in zig/mingw.zig functions buildImportLib and findDef.

Ah, so, presumably, if I have that, it should work, right? And so I must just install visual studio build tools? Will try that!

Yes, is should work.

I am downloading a subset of visual studio build tools, suitable for cross compiling, using a rust utility called xwin, and never had problems like this.

Visual studio build tools are neither required nor depended on by zig.

Zig produces ntdll.lib by shipping with ntdll.def.in files which are converted to ntdll.def files via aro C preprocessor (part of the zig compiler), which are then converted to ntdll.lib files via LLVM’s object::writeImportLibrary used when linking against ntdll.dll.

I don’t know why you would see “include nested too deply”. Creating ntdll.lib is an extremely commonly tested code path.

That said, I believe that message is coming from clang in zig 0.11, and since then, we switched to Aro (written in zig) for the C preprocessor being used here. This means if you get a weird error, myself or Vexu will know why it is happening and how to fix it.

3 Likes

Thanks for the extra context here Andrew, it helped! Mystery solved-ish!

Using zig 12:

PS Z:\tigerbeetle> .\zig-12\zig.exe run main.zig
error: unable to find zig self exe path: Unexpected

The key thing here is that Z: is the shared folder between my linux host and windows guest, set up with https://winfsp.dev.

If I move zig-12 to C:\ (“normal” windows disk), it works.

So, it seems like a bug somewhere between Zig’s std.fs and winfsp. This is further confirem if I try to compile code on Z:\ using compiler from C:\:

error.Unexpected NTSTATUS=0xc000014f
C:\zig\lib\std\os\windows.zig:244:40: 0x7ff6a116e932 in DeviceIoControl (build.exe.obj)
        else => return unexpectedStatus(rc),
                                       ^
C:\zig\lib\std\os\windows.zig:1230:28: 0x7ff6a113d4ac in GetFinalPathNameByHandle (build.exe.obj)
            DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_POINTS, &input_buf, &output_buf) catch |err| switch (err) {
                           ^
C:\zig\lib\std\os.zig:5177:68: 0x7ff6a10dd580 in getFdPath (build.exe.obj)
            const wide_slice = try windows.GetFinalPathNameByHandle(fd, .{}, wide_buf[0..]);
                                                                   ^
C:\zig\lib\std\fs.zig:1597:42: 0x7ff6a10dc7ad in realpathW (build.exe.obj)
        const out_path = try os.getFdPath(h_file, &buffer);

I guess either I have to develop on windows disk (and cp stuff between the shared folder and windows), or look into that samba thing…

Ah, the above crash isn’t even Zig compiler, it’s my code that calls realpath. I guess I got what I asked for, let me try to get rid of that realpath, which is generally always wrong to use (I think I need to set a cwd for a child process, which doesn’t assepts a dir fd, but maybe i can work around that).

EDIT: argh, yeah, my code does hit change std.ChildProcess to accept a directory handle for cwd rather than a string · Issue #5190 · ziglang/zig · GitHub :frowning:

Try WSL 2, you can use linux to mount remote filesystems and the linux root is visible as windows disk (for Debian distribution it is available as \\wsl$\Debian) using 9p (plan 9 remote file system).
The worst problem when working with windows is the case (in)sensitivity of the filesystem.

Thanks for that stack trace snippet! I was able to extract a std lib improvement and a follow-up issue for later from it.

3 Likes