self-hosted: find all libc paths; windows linker code
parent
2614ef056a
commit
72599d420b
|
@ -276,6 +276,7 @@ pub const Compilation = struct {
|
|||
LibCRequiredButNotProvidedOrFound,
|
||||
LibCMissingDynamicLinker,
|
||||
InvalidDarwinVersionString,
|
||||
UnsupportedLinkArchitecture,
|
||||
};
|
||||
|
||||
pub const Event = union(enum) {
|
||||
|
|
|
@ -20,8 +20,10 @@ pub const LibCInstallation = struct {
|
|||
CCompilerExitCode,
|
||||
CCompilerCrashed,
|
||||
CCompilerCannotFindHeaders,
|
||||
CCompilerCannotFindCRuntime,
|
||||
LibCRuntimeNotFound,
|
||||
LibCStdLibHeaderNotFound,
|
||||
LibCKernel32LibNotFound,
|
||||
UnsupportedArchitecture,
|
||||
};
|
||||
|
||||
pub fn parse(
|
||||
|
@ -111,7 +113,7 @@ pub const LibCInstallation = struct {
|
|||
\\lib_dir={}
|
||||
\\
|
||||
\\# The directory that contains `crtbegin.o`.
|
||||
\\# On Linux, can be found with `cc -print-file-name=crt1.o`.
|
||||
\\# On Linux, can be found with `cc -print-file-name=crtbegin.o`.
|
||||
\\# Not needed when targeting MacOS or Windows.
|
||||
\\static_lib_dir={}
|
||||
\\
|
||||
|
@ -142,21 +144,22 @@ pub const LibCInstallation = struct {
|
|||
self.initEmpty();
|
||||
var group = event.Group(FindError!void).init(loop);
|
||||
errdefer group.cancelAll();
|
||||
var windows_sdk: ?*c.ZigWindowsSDK = null;
|
||||
errdefer if (windows_sdk) |sdk| c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk));
|
||||
|
||||
switch (builtin.os) {
|
||||
builtin.Os.windows => {
|
||||
var sdk: *c.ZigWindowsSDK = undefined;
|
||||
switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) {
|
||||
c.ZigFindWindowsSdkError.None => {
|
||||
defer c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk));
|
||||
windows_sdk = sdk;
|
||||
|
||||
errdefer if (self.msvc_lib_dir) |s| loop.allocator.free(s);
|
||||
if (sdk.msvc_lib_dir_ptr) |ptr| {
|
||||
self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, ptr[0..sdk.msvc_lib_dir_len]);
|
||||
}
|
||||
//try group.call(findNativeIncludeDirWindows, self, loop);
|
||||
//try group.call(findNativeLibDirWindows, self, loop);
|
||||
//try group.call(findNativeMsvcLibDir, self, loop);
|
||||
//try group.call(findNativeKernel32LibDir, self, loop);
|
||||
try group.call(findNativeKernel32LibDir, self, loop, sdk);
|
||||
try group.call(findNativeIncludeDirWindows, self, loop, sdk);
|
||||
try group.call(findNativeLibDirWindows, self, loop, sdk);
|
||||
},
|
||||
c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory,
|
||||
c.ZigFindWindowsSdkError.NotFound => return error.NotFound,
|
||||
|
@ -230,61 +233,64 @@ pub const LibCInstallation = struct {
|
|||
const stdlib_path = try std.os.path.join(loop.allocator, search_path, "stdlib.h");
|
||||
defer loop.allocator.free(stdlib_path);
|
||||
|
||||
if (std.os.File.access(loop.allocator, stdlib_path)) |_| {
|
||||
if (try fileExists(loop.allocator, stdlib_path)) {
|
||||
self.include_dir = try std.mem.dupe(loop.allocator, u8, search_path);
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
error.NotFound, error.PermissionDenied => continue,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => return error.FileSystem,
|
||||
}
|
||||
}
|
||||
|
||||
return error.LibCStdLibHeaderNotFound;
|
||||
}
|
||||
|
||||
async fn findNativeIncludeDirWindows(self: *LibCInstallation, loop: *event.Loop) !void {
|
||||
// TODO
|
||||
//ZigWindowsSDK *sdk = get_windows_sdk(g);
|
||||
//g->libc_include_dir = buf_alloc();
|
||||
//if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) {
|
||||
// fprintf(stderr, "Unable to determine libc include path. --libc-include-dir");
|
||||
// exit(1);
|
||||
//}
|
||||
@panic("TODO");
|
||||
async fn findNativeIncludeDirWindows(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) !void {
|
||||
var search_buf: [2]Search = undefined;
|
||||
const searches = fillSearch(&search_buf, sdk);
|
||||
|
||||
var result_buf = try std.Buffer.initSize(loop.allocator, 0);
|
||||
defer result_buf.deinit();
|
||||
|
||||
for (searches) |search| {
|
||||
result_buf.shrink(0);
|
||||
const stream = &std.io.BufferOutStream.init(&result_buf).stream;
|
||||
try stream.print("{}\\Include\\{}\\ucrt", search.path, search.version);
|
||||
|
||||
const stdlib_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "stdlib.h");
|
||||
defer loop.allocator.free(stdlib_path);
|
||||
|
||||
if (try fileExists(loop.allocator, stdlib_path)) {
|
||||
self.include_dir = result_buf.toOwnedSlice();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return error.LibCStdLibHeaderNotFound;
|
||||
}
|
||||
|
||||
async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop) FindError!void {
|
||||
// TODO
|
||||
//ZigWindowsSDK *sdk = get_windows_sdk(g);
|
||||
async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) FindError!void {
|
||||
var search_buf: [2]Search = undefined;
|
||||
const searches = fillSearch(&search_buf, sdk);
|
||||
|
||||
//if (g->msvc_lib_dir == nullptr) {
|
||||
// Buf* vc_lib_dir = buf_alloc();
|
||||
// if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) {
|
||||
// fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir");
|
||||
// exit(1);
|
||||
// }
|
||||
// g->msvc_lib_dir = vc_lib_dir;
|
||||
//}
|
||||
var result_buf = try std.Buffer.initSize(loop.allocator, 0);
|
||||
defer result_buf.deinit();
|
||||
|
||||
//if (g->libc_lib_dir == nullptr) {
|
||||
// Buf* ucrt_lib_path = buf_alloc();
|
||||
// if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) {
|
||||
// fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir");
|
||||
// exit(1);
|
||||
// }
|
||||
// g->libc_lib_dir = ucrt_lib_path;
|
||||
//}
|
||||
|
||||
//if (g->kernel32_lib_dir == nullptr) {
|
||||
// Buf* kern_lib_path = buf_alloc();
|
||||
// if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) {
|
||||
// fprintf(stderr, "Unable to determine kernel32 path. --kernel32-lib-dir");
|
||||
// exit(1);
|
||||
// }
|
||||
// g->kernel32_lib_dir = kern_lib_path;
|
||||
//}
|
||||
@panic("TODO");
|
||||
for (searches) |search| {
|
||||
result_buf.shrink(0);
|
||||
const stream = &std.io.BufferOutStream.init(&result_buf).stream;
|
||||
try stream.print("{}\\Lib\\{}\\ucrt\\", search.path, search.version);
|
||||
switch (builtin.arch) {
|
||||
builtin.Arch.i386 => try stream.write("x86"),
|
||||
builtin.Arch.x86_64 => try stream.write("x64"),
|
||||
builtin.Arch.aarch64 => try stream.write("arm"),
|
||||
else => return error.UnsupportedArchitecture,
|
||||
}
|
||||
const ucrt_lib_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "ucrt.lib");
|
||||
defer loop.allocator.free(ucrt_lib_path);
|
||||
if (try fileExists(loop.allocator, ucrt_lib_path)) {
|
||||
self.lib_dir = result_buf.toOwnedSlice();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return error.LibCRuntimeNotFound;
|
||||
}
|
||||
|
||||
async fn findNativeLibDirLinux(self: *LibCInstallation, loop: *event.Loop) FindError!void {
|
||||
|
@ -330,17 +336,37 @@ pub const LibCInstallation = struct {
|
|||
dyn_test.result = result;
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
error.CCompilerCannotFindCRuntime => return,
|
||||
error.LibCRuntimeNotFound => return,
|
||||
else => return err,
|
||||
}
|
||||
}
|
||||
|
||||
async fn findNativeMsvcLibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void {
|
||||
@panic("TODO");
|
||||
}
|
||||
|
||||
async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void {
|
||||
@panic("TODO");
|
||||
async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) FindError!void {
|
||||
var search_buf: [2]Search = undefined;
|
||||
const searches = fillSearch(&search_buf, sdk);
|
||||
|
||||
var result_buf = try std.Buffer.initSize(loop.allocator, 0);
|
||||
defer result_buf.deinit();
|
||||
|
||||
for (searches) |search| {
|
||||
result_buf.shrink(0);
|
||||
const stream = &std.io.BufferOutStream.init(&result_buf).stream;
|
||||
try stream.print("{}\\Lib\\{}\\um\\", search.path, search.version);
|
||||
switch (builtin.arch) {
|
||||
builtin.Arch.i386 => try stream.write("x86\\"),
|
||||
builtin.Arch.x86_64 => try stream.write("x64\\"),
|
||||
builtin.Arch.aarch64 => try stream.write("arm\\"),
|
||||
else => return error.UnsupportedArchitecture,
|
||||
}
|
||||
const kernel32_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "kernel32.lib");
|
||||
defer loop.allocator.free(kernel32_path);
|
||||
if (try fileExists(loop.allocator, kernel32_path)) {
|
||||
self.kernel32_lib_dir = result_buf.toOwnedSlice();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return error.LibCKernel32LibNotFound;
|
||||
}
|
||||
|
||||
fn initEmpty(self: *LibCInstallation) void {
|
||||
|
@ -386,8 +412,8 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo
|
|||
},
|
||||
}
|
||||
var it = std.mem.split(exec_result.stdout, "\n\r");
|
||||
const line = it.next() orelse return error.CCompilerCannotFindCRuntime;
|
||||
const dirname = std.os.path.dirname(line) orelse return error.CCompilerCannotFindCRuntime;
|
||||
const line = it.next() orelse return error.LibCRuntimeNotFound;
|
||||
const dirname = std.os.path.dirname(line) orelse return error.LibCRuntimeNotFound;
|
||||
|
||||
if (want_dirname) {
|
||||
return std.mem.dupe(loop.allocator, u8, dirname);
|
||||
|
@ -395,3 +421,42 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo
|
|||
return std.mem.dupe(loop.allocator, u8, line);
|
||||
}
|
||||
}
|
||||
|
||||
const Search = struct {
|
||||
path: []const u8,
|
||||
version: []const u8,
|
||||
};
|
||||
|
||||
fn fillSearch(search_buf: *[2]Search, sdk: *c.ZigWindowsSDK) []Search {
|
||||
var search_end: usize = 0;
|
||||
if (sdk.path10_ptr) |path10_ptr| {
|
||||
if (sdk.version10_ptr) |ver10_ptr| {
|
||||
search_buf[search_end] = Search{
|
||||
.path = path10_ptr[0..sdk.path10_len],
|
||||
.version = ver10_ptr[0..sdk.version10_len],
|
||||
};
|
||||
search_end += 1;
|
||||
}
|
||||
}
|
||||
if (sdk.path81_ptr) |path81_ptr| {
|
||||
if (sdk.version81_ptr) |ver81_ptr| {
|
||||
search_buf[search_end] = Search{
|
||||
.path = path81_ptr[0..sdk.path81_len],
|
||||
.version = ver81_ptr[0..sdk.version81_len],
|
||||
};
|
||||
search_end += 1;
|
||||
}
|
||||
}
|
||||
return search_buf[0..search_end];
|
||||
}
|
||||
|
||||
|
||||
fn fileExists(allocator: *std.mem.Allocator, path: []const u8) !bool {
|
||||
if (std.os.File.access(allocator, path)) |_| {
|
||||
return true;
|
||||
} else |err| switch (err) {
|
||||
error.NotFound, error.PermissionDenied => return false,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => return error.FileSystem,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,8 +313,150 @@ fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void {
|
|||
try ctx.args.append(full_path_with_null.ptr);
|
||||
}
|
||||
|
||||
fn constructLinkerArgsCoff(ctx: *Context) void {
|
||||
@panic("TODO");
|
||||
fn constructLinkerArgsCoff(ctx: *Context) !void {
|
||||
try ctx.args.append(c"-NOLOGO");
|
||||
|
||||
if (!ctx.comp.strip) {
|
||||
try ctx.args.append(c"-DEBUG");
|
||||
}
|
||||
|
||||
switch (ctx.comp.target.getArch()) {
|
||||
builtin.Arch.i386 => try ctx.args.append(c"-MACHINE:X86"),
|
||||
builtin.Arch.x86_64 => try ctx.args.append(c"-MACHINE:X64"),
|
||||
builtin.Arch.aarch64 => try ctx.args.append(c"-MACHINE:ARM"),
|
||||
else => return error.UnsupportedLinkArchitecture,
|
||||
}
|
||||
|
||||
if (ctx.comp.windows_subsystem_windows) {
|
||||
try ctx.args.append(c"/SUBSYSTEM:windows");
|
||||
} else if (ctx.comp.windows_subsystem_console) {
|
||||
try ctx.args.append(c"/SUBSYSTEM:console");
|
||||
}
|
||||
|
||||
const is_library = ctx.comp.kind == Compilation.Kind.Lib;
|
||||
|
||||
const out_arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-OUT:{}\x00", ctx.out_file_path.toSliceConst());
|
||||
try ctx.args.append(out_arg.ptr);
|
||||
|
||||
if (ctx.comp.haveLibC()) {
|
||||
try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.msvc_lib_dir.?)).ptr);
|
||||
try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.kernel32_lib_dir.?)).ptr);
|
||||
try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.lib_dir.?)).ptr);
|
||||
}
|
||||
|
||||
if (ctx.link_in_crt) {
|
||||
const lib_str = if (ctx.comp.is_static) "lib" else "";
|
||||
const d_str = if (ctx.comp.build_mode == builtin.Mode.Debug) "d" else "";
|
||||
|
||||
if (ctx.comp.is_static) {
|
||||
const cmt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "libcmt{}.lib\x00", d_str);
|
||||
try ctx.args.append(cmt_lib_name.ptr);
|
||||
} else {
|
||||
const msvcrt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "msvcrt{}.lib\x00", d_str);
|
||||
try ctx.args.append(msvcrt_lib_name.ptr);
|
||||
}
|
||||
|
||||
const vcruntime_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}vcruntime{}.lib\x00", lib_str, d_str);
|
||||
try ctx.args.append(vcruntime_lib_name.ptr);
|
||||
|
||||
const crt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}ucrt{}.lib\x00", lib_str, d_str);
|
||||
try ctx.args.append(crt_lib_name.ptr);
|
||||
|
||||
// Visual C++ 2015 Conformance Changes
|
||||
// https://msdn.microsoft.com/en-us/library/bb531344.aspx
|
||||
try ctx.args.append(c"legacy_stdio_definitions.lib");
|
||||
|
||||
// msvcrt depends on kernel32
|
||||
try ctx.args.append(c"kernel32.lib");
|
||||
} else {
|
||||
try ctx.args.append(c"-NODEFAULTLIB");
|
||||
if (!is_library) {
|
||||
try ctx.args.append(c"-ENTRY:WinMainCRTStartup");
|
||||
// TODO
|
||||
//if (g->have_winmain) {
|
||||
// lj->args.append("-ENTRY:WinMain");
|
||||
//} else {
|
||||
// lj->args.append("-ENTRY:WinMainCRTStartup");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_library and !ctx.comp.is_static) {
|
||||
try ctx.args.append(c"-DLL");
|
||||
}
|
||||
|
||||
//for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
|
||||
// const char *lib_dir = g->lib_dirs.at(i);
|
||||
// lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
|
||||
//}
|
||||
|
||||
for (ctx.comp.link_objects) |link_object| {
|
||||
const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
|
||||
try ctx.args.append(link_obj_with_null.ptr);
|
||||
}
|
||||
try addFnObjects(ctx);
|
||||
|
||||
switch (ctx.comp.kind) {
|
||||
Compilation.Kind.Exe, Compilation.Kind.Lib => {
|
||||
if (!ctx.comp.haveLibC()) {
|
||||
@panic("TODO");
|
||||
//Buf *builtin_o_path = build_o(g, "builtin");
|
||||
//lj->args.append(buf_ptr(builtin_o_path));
|
||||
}
|
||||
|
||||
// msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
|
||||
// TODO
|
||||
//Buf *compiler_rt_o_path = build_compiler_rt(g);
|
||||
//lj->args.append(buf_ptr(compiler_rt_o_path));
|
||||
},
|
||||
Compilation.Kind.Obj => {},
|
||||
}
|
||||
|
||||
//Buf *def_contents = buf_alloc();
|
||||
//ZigList<const char *> gen_lib_args = {0};
|
||||
//for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
|
||||
// LinkLib *link_lib = g->link_libs_list.at(lib_i);
|
||||
// if (buf_eql_str(link_lib->name, "c")) {
|
||||
// continue;
|
||||
// }
|
||||
// if (link_lib->provided_explicitly) {
|
||||
// if (lj->codegen->zig_target.env_type == ZigLLVM_GNU) {
|
||||
// Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
|
||||
// lj->args.append(buf_ptr(arg));
|
||||
// }
|
||||
// else {
|
||||
// lj->args.append(buf_ptr(link_lib->name));
|
||||
// }
|
||||
// } else {
|
||||
// buf_resize(def_contents, 0);
|
||||
// buf_appendf(def_contents, "LIBRARY %s\nEXPORTS\n", buf_ptr(link_lib->name));
|
||||
// for (size_t exp_i = 0; exp_i < link_lib->symbols.length; exp_i += 1) {
|
||||
// Buf *symbol_name = link_lib->symbols.at(exp_i);
|
||||
// buf_appendf(def_contents, "%s\n", buf_ptr(symbol_name));
|
||||
// }
|
||||
// buf_appendf(def_contents, "\n");
|
||||
|
||||
// Buf *def_path = buf_alloc();
|
||||
// os_path_join(g->cache_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path);
|
||||
// os_write_file(def_path, def_contents);
|
||||
|
||||
// Buf *generated_lib_path = buf_alloc();
|
||||
// os_path_join(g->cache_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path);
|
||||
|
||||
// gen_lib_args.resize(0);
|
||||
// gen_lib_args.append("link");
|
||||
|
||||
// coff_append_machine_arg(g, &gen_lib_args);
|
||||
// gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
|
||||
// gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
|
||||
// Buf diag = BUF_INIT;
|
||||
// if (!zig_lld_link(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
|
||||
// fprintf(stderr, "%s\n", buf_ptr(&diag));
|
||||
// exit(1);
|
||||
// }
|
||||
// lj->args.append(buf_ptr(generated_lib_path));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
fn constructLinkerArgsMachO(ctx: *Context) !void {
|
||||
|
|
|
@ -287,7 +287,10 @@ ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) {
|
|||
}
|
||||
rc = RegQueryValueEx(key, "KitsRoot10", NULL, NULL, (LPBYTE)priv->base.path10_ptr, &tmp_buf_len);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
priv->base.path10_len = tmp_buf_len;
|
||||
priv->base.path10_len = tmp_buf_len - 1;
|
||||
if (priv->base.path10_ptr[priv->base.path10_len - 1] == '\\') {
|
||||
priv->base.path10_len -= 1;
|
||||
}
|
||||
} else {
|
||||
free((void*)priv->base.path10_ptr);
|
||||
priv->base.path10_ptr = nullptr;
|
||||
|
@ -302,7 +305,10 @@ ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) {
|
|||
}
|
||||
rc = RegQueryValueEx(key, "KitsRoot81", NULL, NULL, (LPBYTE)priv->base.path81_ptr, &tmp_buf_len);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
priv->base.path81_len = tmp_buf_len;
|
||||
priv->base.path81_len = tmp_buf_len - 1;
|
||||
if (priv->base.path81_ptr[priv->base.path81_len - 1] == '\\') {
|
||||
priv->base.path81_len -= 1;
|
||||
}
|
||||
} else {
|
||||
free((void*)priv->base.path81_ptr);
|
||||
priv->base.path81_ptr = nullptr;
|
||||
|
|
|
@ -139,7 +139,9 @@ pub const File = struct {
|
|||
|
||||
const err = windows.GetLastError();
|
||||
switch (err) {
|
||||
windows.ERROR.FILE_NOT_FOUND => return error.NotFound,
|
||||
windows.ERROR.FILE_NOT_FOUND,
|
||||
windows.ERROR.PATH_NOT_FOUND,
|
||||
=> return error.NotFound,
|
||||
windows.ERROR.ACCESS_DENIED => return error.PermissionDenied,
|
||||
else => return os.unexpectedErrorWindows(err),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue