I'm developing in a linux environment using WSl (windows subsystem for linux). Most of the time, the linux binary of zig works great, but somewhere in the standard library, it discovers I'm actually on a windows computer and gets very confused.
Sample Program:
const std = @import("std");
pub fn main() !void {
const res = std.fs.cwd().openRead("selectors/samples.ipldsel");
const stdout = &std.io.getStdOut().outStream().stream;
try stdout.print("res = {}\n", .{res});
}
This crashes with quite the error when I try to run it.
$ zig run file-read.zig
/home/tim/zig-linux-x86_64-0.5.0+786700249/lib/zig/std/os.zig:2348:29: error: dependency on dynamic library 'kernel32' requires enabling Position Independent Code
switch (windows.kernel32.GetLastError()) {
^
/home/tim/zig-linux-x86_64-0.5.0+786700249/lib/zig/std/os.zig:2348:29: note: fixed by `--library kernel32` or `-fPIC`
switch (windows.kernel32.GetLastError()) {
^
/home/tim/zig-linux-x86_64-0.5.0+786700249/lib/zig/std/os/windows.zig:1040:41: note: referenced here
pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
^
/home/tim/zig-linux-x86_64-0.5.0+786700249/lib/zig/std/os.zig:2352:37: note: referenced here
else => |err| return windows.unexpectedError(err),
^
/home/tim/zig-linux-x86_64-0.5.0+786700249/lib/zig/std/os.zig:2343:85: note: referenced here
pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!void {
^
/home/tim/zig-linux-x86_64-0.5.0+786700249/lib/zig/std/fs.zig:813:85: error: expected type '*c_void', found 'i32'
.RootDirectory = if (path.isAbsoluteWindowsW(sub_path_w)) null else self.fd,
^
An immediate workaround for you would be to pass an explicit target (perhaps -target x86_64-linux-gnu for example).
The bigger question here is, what should the "native" target be detected as in this case? Windows or Linux?
In this case, I would say the "native" target is linux. It's windows providing a (mostly) linux compatible userspace. It runs unmodified linux elf files and expects them to make linux system calls using a linux shaped filesystem.
Linux should be the native target if you're running a Linux or Windows binary in WSL. WSL will allow you to run binaries from either platform.
jared@DEV06:~$ /mnt/d/zig-windows-x86_64-0.5.0+eff50abce/zig.exe version
0.5.0+eff50abce
jared@DEV06:~$ /mnt/d/zig-linux-x86_64-0.5.0+eff50abce/zig version
0.5.0+eff50abce
On second look, this does look like Zig getting confused about what the host system is. It looks like it's pulling this information from 2 different sources but it should be pulling from only one. More investigation needed.
For those that want a quick summary of WSL:
WSL is implemented at the system call level on Windows 10. It's up to the user to provide a rootfs. You can register/install your rootfs with WSL by providing a tar.gz file of your rootfs. Once it's registered/installed, you can enter your linux instance by invoking the wsl executable (or wslconfig on older versions of Windows 10) and providing the name of your registered distro.
WSL distros also typically provide their own installer. I wrote a generic installer that explains some more details about how installation works here: https://github.com/marler8997/wsl-register
That being said, Microsoft announced that they are going to release WSL version 2 to operate in more of a hyper-visor mode, where the distro provide the rootfs and the kernel.
Actually, I just got the exact same error on my Linux workstation. It's running a fresh install of pop-os (ubuntu derivitive). I think this may be a more serious regression affecting linux or something is really wrong with my code.
It's just #2584
With 2584 closed and the most recent std.fs changes in master, I haven't gotten a stack trace again. Here's the difference when comparing Linux vs Windows zig in WSL. BadPathName is a result of using a forward slash in the test code. Using backslashes works, as long as you're not using . or .. (#4605).
WSL
jared@DEV03:/mnt/g/zig/issue-4411$ ../zig/build-release/bin/zig.exe run src/file-read.zig
./src/main.zig = error.BadPathName
src/main.zig = error.BadPathName
./build.zig = error.BadPathName
build.zig = File{ .handle = c_void@90, .io_mode = Mode.blocking, .async_block_allowed = void }
jared@DEV03:/mnt/g/zig/issue-4411$ ../zig-linux-x86_64-0.5.0+80ff549e2/zig run src/file-read.zig
./src/main.zig = File{ .handle = 3, .io_mode = Mode.blocking, .async_block_allowed = void }
src/main.zig = File{ .handle = 4, .io_mode = Mode.blocking, .async_block_allowed = void }
./build.zig = File{ .handle = 5, .io_mode = Mode.blocking, .async_block_allowed = void }
build.zig = File{ .handle = 6, .io_mode = Mode.blocking, .async_block_allowed = void }
CMD
G:\zig\issue-4411>zig run src\file-read.zig
./src/main.zig = error.BadPathName
src/main.zig = error.BadPathName
./build.zig = error.BadPathName
build.zig = File{ .handle = c_void@f4, .io_mode = Mode.blocking, .async_block_allowed = void }
Most helpful comment
Linux should be the native target if you're running a Linux or Windows binary in WSL. WSL will allow you to run binaries from either platform.