ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.79k stars 2.47k forks source link

Compilation fails while trying to getStdInHandle only when target is set to x86_64-windows #17186

Closed zlw closed 1 year ago

zlw commented 1 year ago

Zig Version

0.11.0

Steps to Reproduce and Observed Behavior

While following Crafting Interpreters book in Zig, I wanted to try cross-compiling to different targets. It works like a charm for linux and mac (I'm on mac), but it failed for windows while trying to get stdIn handle:

Build Summary: 0/3 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
└─ install zlox transitive failure
   └─ zig build-exe zlox ReleaseFast x86_64-windows 1 errors
/Users/zlw/.zigtools/0.11.0/zig/lib/std/os/windows.zig:1892:28: error: unable to evaluate comptime expression
                break :blk asm volatile (
                           ^~~
/Users/zlw/.zigtools/0.11.0/zig/lib/std/os/windows.zig:1907:15: note: called from here
    return teb().ProcessEnvironmentBlock;
           ~~~^~
/Users/zlw/.zigtools/0.11.0/zig/lib/std/io.zig:88:30: note: called from here
        return os.windows.peb().ProcessParameters.hStdInput;
               ~~~~~~~~~~~~~~^~
/Users/zlw/.zigtools/0.11.0/zig/lib/std/io.zig:102:33: note: called from here
        .handle = getStdInHandle(),
                  ~~~~~~~~~~~~~~^~
src/main.zig:15:30: note: called from here
const stdin = std.io.getStdIn().reader();
              ~~~~~~~~~~~~~~~^~
make: *** [cross_release] Error 2

To fully reproduce it you could clone the repo https://github.com/zlw/zlox/commit/166a2eb038532d0358e44f7be65506e651d0b9f3 and try to compile it with:

make cross_release target=windows

which runs:

zig build -Doptimize=ReleaseFast -Dtarget="x86_64-windows"

but I'm guessing the minimal way to reproduce it would be something like:

const std = @import("std");

const errout = std.io.getStdErr().writer();
const stdout = std.io.getStdOut().writer();
// it doesn't fail on two lines above
// but fails on the one below
const stdin = std.io.getStdIn().reader();

pub fn main() anyerror!void {}

Thanks for all the work on Zig, it's my first low-level language and it's been a great journey so far 😄 It made working with memory way less scary, Allocator a'la DI is an amazing idea 🤯

Expected Behavior

Cross compilation woks for all 3 main target on OSX

rohlem commented 1 year ago

On Linux and macOS the file handle for stdin is constant and can therefore be resolved at comptime. On Windows (fwict) this is not the case: It has to be looked up at runtime. Zig only allows initializing global (technically container-level) declarations with comptime-known values.

Your options are:

Vexu commented 1 year ago

Previous issues: #6845, #14203