From b23ace27db438652898b671f3417730ddc662101 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 15 Jul 2019 01:41:06 -0400 Subject: [PATCH] fix the build on windows --- src/main.cpp | 3 +++ std/build.zig | 13 ++++++++++++- std/fs.zig | 3 ++- std/fs/file.zig | 22 +++++++++++----------- std/os/windows.zig | 22 +++++++++++++++------- 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e58eb253f7..ce68e53d85 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1229,6 +1229,9 @@ int main(int argc, char **argv) { return term.code; } else if (cmd == CmdBuild) { if (g->enable_cache) { +#if defined(ZIG_OS_WINDOWS) + buf_replace(&g->output_file_path, '/', '\\'); +#endif if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0) return EXIT_FAILURE; } diff --git a/std/build.zig b/std/build.zig index 30dd983d29..f4e9c2b53b 100644 --- a/std/build.zig +++ b/std/build.zig @@ -216,6 +216,17 @@ pub const Builder = struct { return mem.dupe(self.allocator, u8, bytes) catch unreachable; } + fn dupePath(self: *Builder, bytes: []const u8) []u8 { + const the_copy = self.dupe(bytes); + for (the_copy) |*byte| { + switch (byte.*) { + '/', '\\' => byte.* = fs.path.sep, + else => {}, + } + } + return the_copy; + } + pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep { const write_file_step = self.allocator.create(WriteFileStep) catch unreachable; write_file_step.* = WriteFileStep.init(self, file_path, data); @@ -1412,7 +1423,7 @@ pub const LibExeObjStep = struct { } pub fn setOutputDir(self: *LibExeObjStep, dir: []const u8) void { - self.output_dir = self.builder.dupe(dir); + self.output_dir = self.builder.dupePath(dir); } pub fn install(self: *LibExeObjStep) void { diff --git a/std/fs.zig b/std/fs.zig index c656c34533..6b860ad2a2 100644 --- a/std/fs.zig +++ b/std/fs.zig @@ -110,7 +110,6 @@ pub fn updateFileMode(source_path: []const u8, dest_path: []const u8, mode: ?Fil } } const actual_mode = mode orelse src_stat.mode; - const in_stream = &src_file.inStream().stream; // TODO this logic could be made more efficient by calling makePath, once // that API does not require an allocator @@ -137,6 +136,8 @@ pub fn updateFileMode(source_path: []const u8, dest_path: []const u8, mode: ?Fil } else unreachable; defer atomic_file.deinit(); + const in_stream = &src_file.inStream().stream; + var buf: [mem.page_size * 6]u8 = undefined; while (true) { const amt = try in_stream.readFull(buf[0..]); diff --git a/std/fs/file.zig b/std/fs/file.zig index 18fe658366..55cc2fd97f 100644 --- a/std/fs/file.zig +++ b/std/fs/file.zig @@ -224,13 +224,13 @@ pub const File = struct { mode: Mode, /// access time in nanoseconds - atime: u64, + atime: i64, /// last modification time in nanoseconds - mtime: u64, + mtime: i64, /// creation time in nanoseconds - ctime: u64, + ctime: i64, }; pub const StatError = os.FStatError; @@ -251,9 +251,9 @@ pub const File = struct { return Stat{ .size = @bitCast(u64, st.size), .mode = st.mode, - .atime = @bitCast(usize, st.atim.tv_sec) * std.time.ns_per_s + @bitCast(usize, st.atim.tv_nsec), - .mtime = @bitCast(usize, st.mtim.tv_sec) * std.time.ns_per_s + @bitCast(usize, st.mtim.tv_nsec), - .ctime = @bitCast(usize, st.ctim.tv_sec) * std.time.ns_per_s + @bitCast(usize, st.ctim.tv_nsec), + .atime = st.atim.tv_sec * std.time.ns_per_s + st.atim.tv_nsec, + .mtime = st.mtim.tv_sec * std.time.ns_per_s + st.mtim.tv_nsec, + .ctime = st.ctim.tv_sec * std.time.ns_per_s + st.ctim.tv_nsec, }; } @@ -261,7 +261,7 @@ pub const File = struct { /// `atime`: access timestamp in nanoseconds /// `mtime`: last modification timestamp in nanoseconds - pub fn updateTimes(self: File, atime: u64, mtime: u64) UpdateTimesError!void { + pub fn updateTimes(self: File, atime: i64, mtime: i64) UpdateTimesError!void { if (windows.is_the_target) { const atime_ft = windows.nanoSecondsToFileTime(atime); const mtime_ft = windows.nanoSecondsToFileTime(mtime); @@ -269,12 +269,12 @@ pub const File = struct { } const times = [2]os.timespec{ os.timespec{ - .tv_sec = @bitCast(isize, atime / std.time.ns_per_s), - .tv_nsec = @bitCast(isize, atime % std.time.ns_per_s), + .tv_sec = atime / std.time.ns_per_s, + .tv_nsec = atime % std.time.ns_per_s, }, os.timespec{ - .tv_sec = @bitCast(isize, mtime / std.time.ns_per_s), - .tv_nsec = @bitCast(isize, mtime % std.time.ns_per_s), + .tv_sec = mtime / std.time.ns_per_s, + .tv_nsec = mtime % std.time.ns_per_s, }, }; try os.futimens(self.handle, ×); diff --git a/std/os/windows.zig b/std/os/windows.zig index a608839b80..68c643db81 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -783,16 +783,24 @@ pub fn SetFileTime( } } -pub fn fileTimeToNanoSeconds(ft: FILETIME) u64 { - const sec = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - return sec * std.time.ns_per_s; +/// A file time is a 64-bit value that represents the number of 100-nanosecond +/// intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated +/// Universal Time (UTC). +/// This function returns the number of nanoseconds since the canonical epoch, +/// which is the POSIX one (Jan 01, 1970 AD). +pub fn fileTimeToNanoSeconds(ft: FILETIME) i64 { + const hns = @bitCast(i64, (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime); + const adjusted_epoch = hns + std.time.epoch.windows * (std.time.ns_per_s / 100); + return adjusted_epoch * 100; } -pub fn nanoSecondsToFileTime(ns: u64) FILETIME { - const sec = ns / std.time.ns_per_s; +/// Converts a number of nanoseconds since the POSIX epoch to a Windows FILETIME. +pub fn nanoSecondsToFileTime(ns: i64) FILETIME { + const hns = @divFloor(ns, 100); + const adjusted_epoch = hns - std.time.epoch.windows * (std.time.ns_per_s / 100); return FILETIME{ - .dwHighDateTime = @truncate(u32, sec >> 32), - .dwLowDateTime = @truncate(u32, sec), + .dwHighDateTime = @truncate(u32, @bitCast(u64, adjusted_epoch) >> 32), + .dwLowDateTime = @truncate(u32, @bitCast(u64, adjusted_epoch)), }; }