aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build/Step
diff options
context:
space:
mode:
authorAndrew Kelley <andrewrk@noreply.codeberg.org>2025-12-27 14:10:46 +0100
committerAndrew Kelley <andrewrk@noreply.codeberg.org>2025-12-27 14:10:46 +0100
commite55e6b5528bb2f01de242fcf32b172e244e98e74 (patch)
tree3a5eb3193d3d192c54ab0c2b7295a7f21861c27e /lib/std/Build/Step
parentc3f2de5e519926eb0029062fe8e782a6f9df9c05 (diff)
parent60a1ba0a8f3517356fa2941462f002a7f580545b (diff)
downloadzig-e55e6b5528bb2f01de242fcf32b172e244e98e74.tar.gz
zig-e55e6b5528bb2f01de242fcf32b172e244e98e74.zip
Merge pull request 'std: migrate all `fs` APIs to `Io`' (#30232) from std.Io-fs into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30232
Diffstat (limited to 'lib/std/Build/Step')
-rw-r--r--lib/std/Build/Step/CheckFile.zig5
-rw-r--r--lib/std/Build/Step/CheckObject.zig2
-rw-r--r--lib/std/Build/Step/Compile.zig59
-rw-r--r--lib/std/Build/Step/ConfigHeader.zig13
-rw-r--r--lib/std/Build/Step/InstallArtifact.zig7
-rw-r--r--lib/std/Build/Step/InstallDir.zig11
-rw-r--r--lib/std/Build/Step/ObjCopy.zig5
-rw-r--r--lib/std/Build/Step/Options.zig57
-rw-r--r--lib/std/Build/Step/RemoveDir.zig11
-rw-r--r--lib/std/Build/Step/Run.zig250
-rw-r--r--lib/std/Build/Step/UpdateSourceFiles.zig6
-rw-r--r--lib/std/Build/Step/WriteFile.zig37
12 files changed, 241 insertions, 222 deletions
diff --git a/lib/std/Build/Step/CheckFile.zig b/lib/std/Build/Step/CheckFile.zig
index efeedc8b80..1c3813ca82 100644
--- a/lib/std/Build/Step/CheckFile.zig
+++ b/lib/std/Build/Step/CheckFile.zig
@@ -3,7 +3,9 @@
//! TODO: generalize the code in std.testing.expectEqualStrings and make this
//! CheckFile step produce those helpful diagnostics when there is not a match.
const CheckFile = @This();
+
const std = @import("std");
+const Io = std.Io;
const Step = std.Build.Step;
const fs = std.fs;
const mem = std.mem;
@@ -49,11 +51,12 @@ pub fn setName(check_file: *CheckFile, name: []const u8) void {
fn make(step: *Step, options: Step.MakeOptions) !void {
_ = options;
const b = step.owner;
+ const io = b.graph.io;
const check_file: *CheckFile = @fieldParentPtr("step", step);
try step.singleUnchangingWatchInput(check_file.source);
const src_path = check_file.source.getPath2(b, step);
- const contents = fs.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| {
+ const contents = Io.Dir.cwd().readFileAlloc(io, src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| {
return step.fail("unable to read '{s}': {s}", .{
src_path, @errorName(err),
});
diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig
index c6c11ce2b9..ac8fafaa3f 100644
--- a/lib/std/Build/Step/CheckObject.zig
+++ b/lib/std/Build/Step/CheckObject.zig
@@ -547,12 +547,14 @@ pub fn checkComputeCompare(
fn make(step: *Step, make_options: Step.MakeOptions) !void {
_ = make_options;
const b = step.owner;
+ const io = b.graph.io;
const gpa = b.allocator;
const check_object: *CheckObject = @fieldParentPtr("step", step);
try step.singleUnchangingWatchInput(check_object.source);
const src_path = check_object.source.getPath3(b, step);
const contents = src_path.root_dir.handle.readFileAllocOptions(
+ io,
src_path.sub_path,
gpa,
.limited(check_object.max_bytes),
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
index c57c7750be..0454e5b79d 100644
--- a/lib/std/Build/Step/Compile.zig
+++ b/lib/std/Build/Step/Compile.zig
@@ -1,12 +1,15 @@
+const Compile = @This();
const builtin = @import("builtin");
+
const std = @import("std");
+const Io = std.Io;
const mem = std.mem;
const fs = std.fs;
const assert = std.debug.assert;
const panic = std.debug.panic;
const StringHashMap = std.StringHashMap;
const Sha256 = std.crypto.hash.sha2.Sha256;
-const Allocator = mem.Allocator;
+const Allocator = std.mem.Allocator;
const Step = std.Build.Step;
const LazyPath = std.Build.LazyPath;
const PkgConfigPkg = std.Build.PkgConfigPkg;
@@ -15,7 +18,6 @@ const RunError = std.Build.RunError;
const Module = std.Build.Module;
const InstallDir = std.Build.InstallDir;
const GeneratedFile = std.Build.GeneratedFile;
-const Compile = @This();
const Path = std.Build.Cache.Path;
pub const base_id: Step.Id = .compile;
@@ -920,20 +922,24 @@ const CliNamedModules = struct {
}
};
-fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 {
+fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 {
+ const step = &compile.step;
+ const b = step.owner;
+ const graph = b.graph;
+ const io = graph.io;
const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
const generated_file = maybe_path orelse {
- const w, const ttyconf = std.debug.lockStderrWriter(&.{});
- std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
- std.debug.unlockStderrWriter();
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {};
+ io.unlockStderr();
@panic("missing emit option for " ++ tag_name);
};
const path = generated_file.path orelse {
- const w, const ttyconf = std.debug.lockStderrWriter(&.{});
- std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
- std.debug.unlockStderrWriter();
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {};
+ io.unlockStderr();
@panic(tag_name ++ " is null. Is there a missing step dependency?");
};
@@ -1147,9 +1153,9 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
// For everything else, we directly link
// against the library file.
const full_path_lib = if (other_produces_implib)
- other.getGeneratedFilePath("generated_implib", &compile.step)
+ try other.getGeneratedFilePath("generated_implib", &compile.step)
else
- other.getGeneratedFilePath("generated_bin", &compile.step);
+ try other.getGeneratedFilePath("generated_bin", &compile.step);
try zig_args.append(full_path_lib);
total_linker_objects += 1;
@@ -1561,19 +1567,22 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
}
// -I and -L arguments that appear after the last --mod argument apply to all modules.
+ const cwd: Io.Dir = .cwd();
+ const io = b.graph.io;
+
for (b.search_prefixes.items) |search_prefix| {
- var prefix_dir = fs.cwd().openDir(search_prefix, .{}) catch |err| {
+ var prefix_dir = cwd.openDir(io, search_prefix, .{}) catch |err| {
return step.fail("unable to open prefix directory '{s}': {s}", .{
search_prefix, @errorName(err),
});
};
- defer prefix_dir.close();
+ defer prefix_dir.close(io);
// Avoid passing -L and -I flags for nonexistent directories.
// This prevents a warning, that should probably be upgraded to an error in Zig's
// CLI parsing code, when the linker sees an -L directory that does not exist.
- if (prefix_dir.access("lib", .{})) |_| {
+ if (prefix_dir.access(io, "lib", .{})) |_| {
try zig_args.appendSlice(&.{
"-L", b.pathJoin(&.{ search_prefix, "lib" }),
});
@@ -1584,7 +1593,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
}),
}
- if (prefix_dir.access("include", .{})) |_| {
+ if (prefix_dir.access(io, "include", .{})) |_| {
try zig_args.appendSlice(&.{
"-I", b.pathJoin(&.{ search_prefix, "include" }),
});
@@ -1660,7 +1669,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
args_length += arg.len + 1; // +1 to account for null terminator
}
if (args_length >= 30 * 1024) {
- try b.cache_root.handle.makePath("args");
+ try b.cache_root.handle.createDirPath(io, "args");
const args_to_escape = zig_args.items[2..];
var escaped_args = try std.array_list.Managed([]const u8).initCapacity(arena, args_to_escape.len);
@@ -1693,18 +1702,18 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
_ = try std.fmt.bufPrint(&args_hex_hash, "{x}", .{&args_hash});
const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash;
- if (b.cache_root.handle.access(args_file, .{})) |_| {
+ if (b.cache_root.handle.access(io, args_file, .{})) |_| {
// The args file is already present from a previous run.
} else |err| switch (err) {
error.FileNotFound => {
- try b.cache_root.handle.makePath("tmp");
+ try b.cache_root.handle.createDirPath(io, "tmp");
const rand_int = std.crypto.random.int(u64);
const tmp_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int);
- try b.cache_root.handle.writeFile(.{ .sub_path = tmp_path, .data = args });
- defer b.cache_root.handle.deleteFile(tmp_path) catch {
+ try b.cache_root.handle.writeFile(io, .{ .sub_path = tmp_path, .data = args });
+ defer b.cache_root.handle.deleteFile(io, tmp_path) catch {
// It's fine if the temporary file can't be cleaned up.
};
- b.cache_root.handle.rename(tmp_path, args_file) catch |rename_err| switch (rename_err) {
+ b.cache_root.handle.rename(tmp_path, b.cache_root.handle, args_file, io) catch |rename_err| switch (rename_err) {
error.PathAlreadyExists => {
// The args file was created by another concurrent build process.
},
@@ -1816,18 +1825,20 @@ pub fn doAtomicSymLinks(
filename_name_only: []const u8,
) !void {
const b = step.owner;
+ const io = b.graph.io;
const out_dir = fs.path.dirname(output_path) orelse ".";
const out_basename = fs.path.basename(output_path);
// sym link for libfoo.so.1 to libfoo.so.1.2.3
const major_only_path = b.pathJoin(&.{ out_dir, filename_major_only });
- fs.cwd().atomicSymLink(out_basename, major_only_path, .{}) catch |err| {
+ const cwd: Io.Dir = .cwd();
+ cwd.symLinkAtomic(io, out_basename, major_only_path, .{}) catch |err| {
return step.fail("unable to symlink {s} -> {s}: {s}", .{
major_only_path, out_basename, @errorName(err),
});
};
// sym link for libfoo.so to libfoo.so.1
const name_only_path = b.pathJoin(&.{ out_dir, filename_name_only });
- fs.cwd().atomicSymLink(filename_major_only, name_only_path, .{}) catch |err| {
+ cwd.symLinkAtomic(io, filename_major_only, name_only_path, .{}) catch |err| {
return step.fail("Unable to symlink {s} -> {s}: {s}", .{
name_only_path, filename_major_only, @errorName(err),
});
@@ -1897,7 +1908,7 @@ fn checkCompileErrors(compile: *Compile) !void {
try actual_eb.renderToWriter(.{
.include_reference_trace = false,
.include_source_line = false,
- }, &aw.writer, .no_color);
+ }, &aw.writer);
break :ae try aw.toOwnedSlice();
};
diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig
index df2419764d..b55efc0da4 100644
--- a/lib/std/Build/Step/ConfigHeader.zig
+++ b/lib/std/Build/Step/ConfigHeader.zig
@@ -1,5 +1,7 @@
-const std = @import("std");
const ConfigHeader = @This();
+
+const std = @import("std");
+const Io = std.Io;
const Step = std.Build.Step;
const Allocator = std.mem.Allocator;
const Writer = std.Io.Writer;
@@ -182,6 +184,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const gpa = b.allocator;
const arena = b.allocator;
+ const io = b.graph.io;
var man = b.graph.cache.obtain();
defer man.deinit();
@@ -205,7 +208,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
.autoconf_undef, .autoconf_at => |file_source| {
try bw.writeAll(c_generated_line);
const src_path = file_source.getPath2(b, step);
- const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| {
+ const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| {
return step.fail("unable to read autoconf input file '{s}': {s}", .{
src_path, @errorName(err),
});
@@ -219,7 +222,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
.cmake => |file_source| {
try bw.writeAll(c_generated_line);
const src_path = file_source.getPath2(b, step);
- const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| {
+ const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| {
return step.fail("unable to read cmake input file '{s}': {s}", .{
src_path, @errorName(err),
});
@@ -255,13 +258,13 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const sub_path = b.pathJoin(&.{ "o", &digest, config_header.include_path });
const sub_path_dirname = std.fs.path.dirname(sub_path).?;
- b.cache_root.handle.makePath(sub_path_dirname) catch |err| {
+ b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| {
return step.fail("unable to make path '{f}{s}': {s}", .{
b.cache_root, sub_path_dirname, @errorName(err),
});
};
- b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = output }) catch |err| {
+ b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = output }) catch |err| {
return step.fail("unable to write file '{f}{s}': {s}", .{
b.cache_root, sub_path, @errorName(err),
});
diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig
index c203ae924b..019d465f01 100644
--- a/lib/std/Build/Step/InstallArtifact.zig
+++ b/lib/std/Build/Step/InstallArtifact.zig
@@ -119,6 +119,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
_ = options;
const install_artifact: *InstallArtifact = @fieldParentPtr("step", step);
const b = step.owner;
+ const io = b.graph.io;
var all_cached = true;
@@ -163,15 +164,15 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const src_dir_path = dir.source.getPath3(b, step);
const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path);
- var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
+ var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
return step.fail("unable to open source directory '{f}': {s}", .{
src_dir_path, @errorName(err),
});
};
- defer src_dir.close();
+ defer src_dir.close(io);
var it = try src_dir.walk(b.allocator);
- next_entry: while (try it.next()) |entry| {
+ next_entry: while (try it.next(io)) |entry| {
for (dir.options.exclude_extensions) |ext| {
if (std.mem.endsWith(u8, entry.path, ext)) continue :next_entry;
}
diff --git a/lib/std/Build/Step/InstallDir.zig b/lib/std/Build/Step/InstallDir.zig
index fd8a7d113f..d03e72ca75 100644
--- a/lib/std/Build/Step/InstallDir.zig
+++ b/lib/std/Build/Step/InstallDir.zig
@@ -58,21 +58,20 @@ pub fn create(owner: *std.Build, options: Options) *InstallDir {
fn make(step: *Step, options: Step.MakeOptions) !void {
_ = options;
const b = step.owner;
+ const io = b.graph.io;
const install_dir: *InstallDir = @fieldParentPtr("step", step);
step.clearWatchInputs();
const arena = b.allocator;
const dest_prefix = b.getInstallPath(install_dir.options.install_dir, install_dir.options.install_subdir);
const src_dir_path = install_dir.options.source_dir.getPath3(b, step);
const need_derived_inputs = try step.addDirectoryWatchInput(install_dir.options.source_dir);
- var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
- return step.fail("unable to open source directory '{f}': {s}", .{
- src_dir_path, @errorName(err),
- });
+ var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
+ return step.fail("unable to open source directory '{f}': {t}", .{ src_dir_path, err });
};
- defer src_dir.close();
+ defer src_dir.close(io);
var it = try src_dir.walk(arena);
var all_cached = true;
- next_entry: while (try it.next()) |entry| {
+ next_entry: while (try it.next(io)) |entry| {
for (install_dir.options.exclude_extensions) |ext| {
if (mem.endsWith(u8, entry.path, ext)) continue :next_entry;
}
diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig
index b5f058ddfc..ea0714adf9 100644
--- a/lib/std/Build/Step/ObjCopy.zig
+++ b/lib/std/Build/Step/ObjCopy.zig
@@ -3,7 +3,7 @@ const ObjCopy = @This();
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
-const File = std.fs.File;
+const File = std.Io.File;
const InstallDir = std.Build.InstallDir;
const Step = std.Build.Step;
const elf = std.elf;
@@ -143,6 +143,7 @@ pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath {
fn make(step: *Step, options: Step.MakeOptions) !void {
const prog_node = options.progress_node;
const b = step.owner;
+ const io = b.graph.io;
const objcopy: *ObjCopy = @fieldParentPtr("step", step);
try step.singleUnchangingWatchInput(objcopy.input_file);
@@ -176,7 +177,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const cache_path = "o" ++ fs.path.sep_str ++ digest;
const full_dest_path = try b.cache_root.join(b.allocator, &.{ cache_path, objcopy.basename });
const full_dest_path_debug = try b.cache_root.join(b.allocator, &.{ cache_path, b.fmt("{s}.debug", .{objcopy.basename}) });
- b.cache_root.handle.makePath(cache_path) catch |err| {
+ b.cache_root.handle.createDirPath(io, cache_path) catch |err| {
return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) });
};
diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig
index 441928d5b8..610d417aea 100644
--- a/lib/std/Build/Step/Options.zig
+++ b/lib/std/Build/Step/Options.zig
@@ -1,12 +1,13 @@
-const std = @import("std");
+const Options = @This();
const builtin = @import("builtin");
+
+const std = @import("std");
+const Io = std.Io;
const fs = std.fs;
const Step = std.Build.Step;
const GeneratedFile = std.Build.GeneratedFile;
const LazyPath = std.Build.LazyPath;
-const Options = @This();
-
pub const base_id: Step.Id = .options;
step: Step,
@@ -441,6 +442,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
_ = make_options;
const b = step.owner;
+ const io = b.graph.io;
const options: *Options = @fieldParentPtr("step", step);
for (options.args.items) |item| {
@@ -468,18 +470,15 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
// Optimize for the hot path. Stat the file, and if it already exists,
// cache hit.
- if (b.cache_root.handle.access(sub_path, .{})) |_| {
+ if (b.cache_root.handle.access(io, sub_path, .{})) |_| {
// This is the hot path, success.
step.result_cached = true;
return;
} else |outer_err| switch (outer_err) {
error.FileNotFound => {
const sub_dirname = fs.path.dirname(sub_path).?;
- b.cache_root.handle.makePath(sub_dirname) catch |e| {
- return step.fail("unable to make path '{f}{s}': {s}", .{
- b.cache_root, sub_dirname, @errorName(e),
- });
- };
+ b.cache_root.handle.createDirPath(io, sub_dirname) catch |e|
+ return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, sub_dirname, e });
const rand_int = std.crypto.random.int(u64);
const tmp_sub_path = "tmp" ++ fs.path.sep_str ++
@@ -487,40 +486,40 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
basename;
const tmp_sub_path_dirname = fs.path.dirname(tmp_sub_path).?;
- b.cache_root.handle.makePath(tmp_sub_path_dirname) catch |err| {
- return step.fail("unable to make temporary directory '{f}{s}': {s}", .{
- b.cache_root, tmp_sub_path_dirname, @errorName(err),
+ b.cache_root.handle.createDirPath(io, tmp_sub_path_dirname) catch |err| {
+ return step.fail("unable to make temporary directory '{f}{s}': {t}", .{
+ b.cache_root, tmp_sub_path_dirname, err,
});
};
- b.cache_root.handle.writeFile(.{ .sub_path = tmp_sub_path, .data = options.contents.items }) catch |err| {
- return step.fail("unable to write options to '{f}{s}': {s}", .{
- b.cache_root, tmp_sub_path, @errorName(err),
+ b.cache_root.handle.writeFile(io, .{ .sub_path = tmp_sub_path, .data = options.contents.items }) catch |err| {
+ return step.fail("unable to write options to '{f}{s}': {t}", .{
+ b.cache_root, tmp_sub_path, err,
});
};
- b.cache_root.handle.rename(tmp_sub_path, sub_path) catch |err| switch (err) {
+ b.cache_root.handle.rename(tmp_sub_path, b.cache_root.handle, sub_path, io) catch |err| switch (err) {
error.PathAlreadyExists => {
// Other process beat us to it. Clean up the temp file.
- b.cache_root.handle.deleteFile(tmp_sub_path) catch |e| {
- try step.addError("warning: unable to delete temp file '{f}{s}': {s}", .{
- b.cache_root, tmp_sub_path, @errorName(e),
+ b.cache_root.handle.deleteFile(io, tmp_sub_path) catch |e| {
+ try step.addError("warning: unable to delete temp file '{f}{s}': {t}", .{
+ b.cache_root, tmp_sub_path, e,
});
};
step.result_cached = true;
return;
},
else => {
- return step.fail("unable to rename options from '{f}{s}' to '{f}{s}': {s}", .{
- b.cache_root, tmp_sub_path,
- b.cache_root, sub_path,
- @errorName(err),
+ return step.fail("unable to rename options from '{f}{s}' to '{f}{s}': {t}", .{
+ b.cache_root, tmp_sub_path,
+ b.cache_root, sub_path,
+ err,
});
},
};
},
- else => |e| return step.fail("unable to access options file '{f}{s}': {s}", .{
- b.cache_root, sub_path, @errorName(e),
+ else => |e| return step.fail("unable to access options file '{f}{s}': {t}", .{
+ b.cache_root, sub_path, e,
}),
}
}
@@ -544,11 +543,11 @@ test Options {
.cache = .{
.io = io,
.gpa = arena.allocator(),
- .manifest_dir = std.fs.cwd(),
+ .manifest_dir = Io.Dir.cwd(),
},
.zig_exe = "test",
.env_map = std.process.EnvMap.init(arena.allocator()),
- .global_cache_root = .{ .path = "test", .handle = std.fs.cwd() },
+ .global_cache_root = .{ .path = "test", .handle = Io.Dir.cwd() },
.host = .{
.query = .{},
.result = try std.zig.system.resolveTargetQuery(io, .{}),
@@ -559,8 +558,8 @@ test Options {
var builder = try std.Build.create(
&graph,
- .{ .path = "test", .handle = std.fs.cwd() },
- .{ .path = "test", .handle = std.fs.cwd() },
+ .{ .path = "test", .handle = Io.Dir.cwd() },
+ .{ .path = "test", .handle = Io.Dir.cwd() },
&.{},
);
diff --git a/lib/std/Build/Step/RemoveDir.zig b/lib/std/Build/Step/RemoveDir.zig
index e2d4c02abc..6f933da9ee 100644
--- a/lib/std/Build/Step/RemoveDir.zig
+++ b/lib/std/Build/Step/RemoveDir.zig
@@ -27,6 +27,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
_ = options;
const b = step.owner;
+ const io = b.graph.io;
const remove_dir: *RemoveDir = @fieldParentPtr("step", step);
step.clearWatchInputs();
@@ -34,15 +35,11 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const full_doomed_path = remove_dir.doomed_path.getPath2(b, step);
- b.build_root.handle.deleteTree(full_doomed_path) catch |err| {
+ b.build_root.handle.deleteTree(io, full_doomed_path) catch |err| {
if (b.build_root.path) |base| {
- return step.fail("unable to recursively delete path '{s}/{s}': {s}", .{
- base, full_doomed_path, @errorName(err),
- });
+ return step.fail("unable to recursively delete path '{s}/{s}': {t}", .{ base, full_doomed_path, err });
} else {
- return step.fail("unable to recursively delete path '{s}': {s}", .{
- full_doomed_path, @errorName(err),
- });
+ return step.fail("unable to recursively delete path '{s}': {t}", .{ full_doomed_path, err });
}
};
}
diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig
index 28c09e1faf..c0ba7f0cee 100644
--- a/lib/std/Build/Step/Run.zig
+++ b/lib/std/Build/Step/Run.zig
@@ -1,15 +1,16 @@
-const std = @import("std");
+const Run = @This();
const builtin = @import("builtin");
+
+const std = @import("std");
+const Io = std.Io;
const Build = std.Build;
-const Step = Build.Step;
-const fs = std.fs;
+const Step = std.Build.Step;
+const Dir = std.Io.Dir;
const mem = std.mem;
const process = std.process;
-const EnvMap = process.EnvMap;
+const EnvMap = std.process.EnvMap;
const assert = std.debug.assert;
-const Path = Build.Cache.Path;
-
-const Run = @This();
+const Path = std.Build.Cache.Path;
pub const base_id: Step.Id = .run;
@@ -25,19 +26,7 @@ cwd: ?Build.LazyPath,
env_map: ?*EnvMap,
/// Controls the `NO_COLOR` and `CLICOLOR_FORCE` environment variables.
-color: enum {
- /// `CLICOLOR_FORCE` is set, and `NO_COLOR` is unset.
- enable,
- /// `NO_COLOR` is set, and `CLICOLOR_FORCE` is unset.
- disable,
- /// If the build runner is using color, equivalent to `.enable`. Otherwise, equivalent to `.disable`.
- inherit,
- /// If stderr is captured or checked, equivalent to `.disable`. Otherwise, equivalent to `.inherit`.
- auto,
- /// The build runner does not modify the `CLICOLOR_FORCE` or `NO_COLOR` environment variables.
- /// They are treated like normal variables, so can be controlled through `setEnvironmentVariable`.
- manual,
-} = .auto,
+color: Color = .auto,
/// When `true` prevents `ZIG_PROGRESS` environment variable from being passed
/// to the child process, which otherwise would be used for the child to send
@@ -111,6 +100,20 @@ rebuilt_executable: ?Path,
/// If this Run step was produced by a Compile step, it is tracked here.
producer: ?*Step.Compile,
+pub const Color = enum {
+ /// `CLICOLOR_FORCE` is set, and `NO_COLOR` is unset.
+ enable,
+ /// `NO_COLOR` is set, and `CLICOLOR_FORCE` is unset.
+ disable,
+ /// If the build runner is using color, equivalent to `.enable`. Otherwise, equivalent to `.disable`.
+ inherit,
+ /// If stderr is captured or checked, equivalent to `.disable`. Otherwise, equivalent to `.inherit`.
+ auto,
+ /// The build runner does not modify the `CLICOLOR_FORCE` or `NO_COLOR` environment variables.
+ /// They are treated like normal variables, so can be controlled through `setEnvironmentVariable`.
+ manual,
+};
+
pub const StdIn = union(enum) {
none,
bytes: []const u8,
@@ -564,7 +567,7 @@ pub fn addPathDir(run: *Run, search_path: []const u8) void {
if (prev_path) |pp| {
const new_path = b.fmt("{s}{c}{s}", .{
pp,
- if (use_wine) fs.path.delimiter_windows else fs.path.delimiter,
+ if (use_wine) Dir.path.delimiter_windows else Dir.path.delimiter,
search_path,
});
env_map.put(key, new_path) catch @panic("OOM");
@@ -747,7 +750,7 @@ fn checksContainStderr(checks: []const StdIo.Check) bool {
fn convertPathArg(run: *Run, path: Build.Cache.Path) []const u8 {
const b = run.step.owner;
const path_str = path.toString(b.graph.arena) catch @panic("OOM");
- if (std.fs.path.isAbsolute(path_str)) {
+ if (Dir.path.isAbsolute(path_str)) {
// Absolute paths don't need changing.
return path_str;
}
@@ -755,19 +758,19 @@ fn convertPathArg(run: *Run, path: Build.Cache.Path) []const u8 {
const child_lazy_cwd = run.cwd orelse break :rel path_str;
const child_cwd = child_lazy_cwd.getPath3(b, &run.step).toString(b.graph.arena) catch @panic("OOM");
// Convert it from relative to *our* cwd, to relative to the *child's* cwd.
- break :rel std.fs.path.relative(b.graph.arena, child_cwd, path_str) catch @panic("OOM");
+ break :rel Dir.path.relative(b.graph.arena, child_cwd, path_str) catch @panic("OOM");
};
// Not every path can be made relative, e.g. if the path and the child cwd are on different
// disk designators on Windows. In that case, `relative` will return an absolute path which we can
// just return.
- if (std.fs.path.isAbsolute(child_cwd_rel)) {
+ if (Dir.path.isAbsolute(child_cwd_rel)) {
return child_cwd_rel;
}
// We're not done yet. In some cases this path must be prefixed with './':
// * On POSIX, the executable name cannot be a single component like 'foo'
// * Some executables might treat a leading '-' like a flag, which we must avoid
// There's no harm in it, so just *always* apply this prefix.
- return std.fs.path.join(b.graph.arena, &.{ ".", child_cwd_rel }) catch @panic("OOM");
+ return Dir.path.join(b.graph.arena, &.{ ".", child_cwd_rel }) catch @panic("OOM");
}
const IndexedOutput = struct {
@@ -845,13 +848,13 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
errdefer result.deinit();
result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory;
- const file = file_path.root_dir.handle.openFile(file_path.subPathOrDot(), .{}) catch |err| {
+ const file = file_path.root_dir.handle.openFile(io, file_path.subPathOrDot(), .{}) catch |err| {
return step.fail(
"unable to open input file '{f}': {t}",
.{ file_path, err },
);
};
- defer file.close();
+ defer file.close(io);
var buf: [1024]u8 = undefined;
var file_reader = file.reader(io, &buf);
@@ -964,15 +967,15 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
&digest,
);
- const output_dir_path = "o" ++ fs.path.sep_str ++ &digest;
+ const output_dir_path = "o" ++ Dir.path.sep_str ++ &digest;
for (output_placeholders.items) |placeholder| {
const output_sub_path = b.pathJoin(&.{ output_dir_path, placeholder.output.basename });
const output_sub_dir_path = switch (placeholder.tag) {
- .output_file => fs.path.dirname(output_sub_path).?,
+ .output_file => Dir.path.dirname(output_sub_path).?,
.output_directory => output_sub_path,
else => unreachable,
};
- b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
+ b.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| {
return step.fail("unable to make path '{f}{s}': {s}", .{
b.cache_root, output_sub_dir_path, @errorName(err),
});
@@ -994,17 +997,17 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
// We do not know the final output paths yet, use temp paths to run the command.
const rand_int = std.crypto.random.int(u64);
- const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int);
+ const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int);
for (output_placeholders.items) |placeholder| {
const output_components = .{ tmp_dir_path, placeholder.output.basename };
const output_sub_path = b.pathJoin(&output_components);
const output_sub_dir_path = switch (placeholder.tag) {
- .output_file => fs.path.dirname(output_sub_path).?,
+ .output_file => Dir.path.dirname(output_sub_path).?,
.output_directory => output_sub_path,
else => unreachable,
};
- b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
+ b.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| {
return step.fail("unable to make path '{f}{s}': {s}", .{
b.cache_root, output_sub_dir_path, @errorName(err),
});
@@ -1022,7 +1025,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, options, null);
- const dep_file_dir = std.fs.cwd();
+ const dep_file_dir = Dir.cwd();
const dep_file_basename = dep_output_file.generated_file.getPath2(b, step);
if (has_side_effects)
try man.addDepFile(dep_file_dir, dep_file_basename)
@@ -1039,29 +1042,23 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
// Rename into place
if (any_output) {
- const o_sub_path = "o" ++ fs.path.sep_str ++ &digest;
+ const o_sub_path = "o" ++ Dir.path.sep_str ++ &digest;
- b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |err| {
+ b.cache_root.handle.rename(tmp_dir_path, b.cache_root.handle, o_sub_path, io) catch |err| {
if (err == error.PathAlreadyExists) {
- b.cache_root.handle.deleteTree(o_sub_path) catch |del_err| {
- return step.fail("unable to remove dir '{f}'{s}: {s}", .{
- b.cache_root,
- tmp_dir_path,
- @errorName(del_err),
+ b.cache_root.handle.deleteTree(io, o_sub_path) catch |del_err| {
+ return step.fail("unable to remove dir '{f}'{s}: {t}", .{
+ b.cache_root, tmp_dir_path, del_err,
});
};
- b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |retry_err| {
- return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {s}", .{
- b.cache_root, tmp_dir_path,
- b.cache_root, o_sub_path,
- @errorName(retry_err),
+ b.cache_root.handle.rename(tmp_dir_path, b.cache_root.handle, o_sub_path, io) catch |retry_err| {
+ return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{
+ b.cache_root, tmp_dir_path, b.cache_root, o_sub_path, retry_err,
});
};
} else {
- return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {s}", .{
- b.cache_root, tmp_dir_path,
- b.cache_root, o_sub_path,
- @errorName(err),
+ return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{
+ b.cache_root, tmp_dir_path, b.cache_root, o_sub_path, err,
});
}
};
@@ -1110,8 +1107,8 @@ pub fn rerunInFuzzMode(
errdefer result.deinit();
result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory;
- const file = try file_path.root_dir.handle.openFile(file_path.subPathOrDot(), .{});
- defer file.close();
+ const file = try file_path.root_dir.handle.openFile(io, file_path.subPathOrDot(), .{});
+ defer file.close(io);
var buf: [1024]u8 = undefined;
var file_reader = file.reader(io, &buf);
@@ -1144,12 +1141,11 @@ pub fn rerunInFuzzMode(
const has_side_effects = false;
const rand_int = std.crypto.random.int(u64);
- const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int);
+ const tmp_dir_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int);
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, .{
.progress_node = prog_node,
.watch = undefined, // not used by `runCommand`
.web_server = null, // only needed for time reports
- .ttyconf = fuzz.ttyconf,
.unit_test_timeout_ns = null, // don't time out fuzz tests for now
.gpa = fuzz.gpa,
}, .{
@@ -1240,6 +1236,7 @@ fn runCommand(
const b = step.owner;
const arena = b.allocator;
const gpa = options.gpa;
+ const io = b.graph.io;
const cwd: ?[]const u8 = if (run.cwd) |lazy_cwd| lazy_cwd.getPath2(b, step) else null;
@@ -1260,33 +1257,6 @@ fn runCommand(
};
defer env_map.deinit();
- color: switch (run.color) {
- .manual => {},
- .enable => {
- try env_map.put("CLICOLOR_FORCE", "1");
- env_map.remove("NO_COLOR");
- },
- .disable => {
- try env_map.put("NO_COLOR", "1");
- env_map.remove("CLICOLOR_FORCE");
- },
- .inherit => switch (options.ttyconf) {
- .no_color, .windows_api => continue :color .disable,
- .escape_codes => continue :color .enable,
- },
- .auto => {
- const capture_stderr = run.captured_stderr != null or switch (run.stdio) {
- .check => |checks| checksContainStderr(checks.items),
- .infer_from_args, .inherit, .zig_test => false,
- };
- if (capture_stderr) {
- continue :color .disable;
- } else {
- continue :color .inherit;
- }
- },
- }
-
const opt_generic_result = spawnChildAndCollect(run, argv, &env_map, has_side_effects, options, fuzz_context) catch |err| term: {
// InvalidExe: cpu arch mismatch
// FileNotFound: can happen with a wrong dynamic linker path
@@ -1308,7 +1278,7 @@ fn runCommand(
const need_cross_libc = exe.is_linking_libc and
(root_target.isGnuLibC() or (root_target.isMuslLibC() and exe.linkage == .dynamic));
const other_target = exe.root_module.resolved_target.?.result;
- switch (std.zig.system.getExternalExecutor(&b.graph.host.result, &other_target, .{
+ switch (std.zig.system.getExternalExecutor(io, &b.graph.host.result, &other_target, .{
.qemu_fixes_dl = need_cross_libc and b.libc_runtimes_dir != null,
.link_libc = exe.is_linking_libc,
})) {
@@ -1468,8 +1438,8 @@ fn runCommand(
captured.output.generated_file.path = output_path;
const sub_path = b.pathJoin(&output_components);
- const sub_path_dirname = fs.path.dirname(sub_path).?;
- b.cache_root.handle.makePath(sub_path_dirname) catch |err| {
+ const sub_path_dirname = Dir.path.dirname(sub_path).?;
+ b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| {
return step.fail("unable to make path '{f}{s}': {s}", .{
b.cache_root, sub_path_dirname, @errorName(err),
});
@@ -1480,7 +1450,7 @@ fn runCommand(
.leading => mem.trimStart(u8, stream.bytes.?, &std.ascii.whitespace),
.trailing => mem.trimEnd(u8, stream.bytes.?, &std.ascii.whitespace),
};
- b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = data }) catch |err| {
+ b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = data }) catch |err| {
return step.fail("unable to write file '{f}{s}': {s}", .{
b.cache_root, sub_path, @errorName(err),
});
@@ -1589,6 +1559,8 @@ fn spawnChildAndCollect(
) !?EvalGenericResult {
const b = run.step.owner;
const arena = b.allocator;
+ const graph = b.graph;
+ const io = graph.io;
if (fuzz_context != null) {
assert(!has_side_effects);
@@ -1654,8 +1626,12 @@ fn spawnChildAndCollect(
if (!run.disable_zig_progress and !inherit) {
child.progress_node = options.progress_node;
}
- if (inherit) std.debug.lockStdErr();
- defer if (inherit) std.debug.unlockStdErr();
+ const terminal_mode: Io.Terminal.Mode = if (inherit) m: {
+ const stderr = try io.lockStderr(&.{}, graph.stderr_mode);
+ break :m stderr.terminal_mode;
+ } else .no_color;
+ defer if (inherit) io.unlockStderr();
+ try setColorEnvironmentVariables(run, env_map, terminal_mode);
var timer = try std.time.Timer.start();
const res = try evalGeneric(run, &child);
run.step.result_duration_ns = timer.read();
@@ -1663,6 +1639,35 @@ fn spawnChildAndCollect(
}
}
+fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, terminal_mode: Io.Terminal.Mode) !void {
+ color: switch (run.color) {
+ .manual => {},
+ .enable => {
+ try env_map.put("CLICOLOR_FORCE", "1");
+ env_map.remove("NO_COLOR");
+ },
+ .disable => {
+ try env_map.put("NO_COLOR", "1");
+ env_map.remove("CLICOLOR_FORCE");
+ },
+ .inherit => switch (terminal_mode) {
+ .no_color, .windows_api => continue :color .disable,
+ .escape_codes => continue :color .enable,
+ },
+ .auto => {
+ const capture_stderr = run.captured_stderr != null or switch (run.stdio) {
+ .check => |checks| checksContainStderr(checks.items),
+ .infer_from_args, .inherit, .zig_test => false,
+ };
+ if (capture_stderr) {
+ continue :color .disable;
+ } else {
+ continue :color .inherit;
+ }
+ },
+ }
+}
+
const StdioPollEnum = enum { stdout, stderr };
fn evalZigTest(
@@ -1671,8 +1676,10 @@ fn evalZigTest(
options: Step.MakeOptions,
fuzz_context: ?FuzzContext,
) !EvalZigTestResult {
- const gpa = run.step.owner.allocator;
- const arena = run.step.owner.allocator;
+ const step_owner = run.step.owner;
+ const gpa = step_owner.allocator;
+ const arena = step_owner.allocator;
+ const io = step_owner.graph.io;
// We will update this every time a child runs.
run.step.result_peak_rss = 0;
@@ -1691,14 +1698,14 @@ fn evalZigTest(
};
while (true) {
- try child.spawn();
+ try child.spawn(io);
var poller = std.Io.poll(gpa, StdioPollEnum, .{
.stdout = child.stdout.?,
.stderr = child.stderr.?,
});
var child_killed = false;
defer if (!child_killed) {
- _ = child.kill() catch {};
+ _ = child.kill(io) catch {};
poller.deinit();
run.step.result_peak_rss = @max(
run.step.result_peak_rss,
@@ -1724,11 +1731,11 @@ fn evalZigTest(
run.step.result_stderr = try arena.dupe(u8, poller.reader(.stderr).buffered());
// Clean up everything and wait for the child to exit.
- child.stdin.?.close();
+ child.stdin.?.close(io);
child.stdin = null;
poller.deinit();
child_killed = true;
- const term = try child.wait();
+ const term = try child.wait(io);
run.step.result_peak_rss = @max(
run.step.result_peak_rss,
child.resource_usage_statistics.getMaxRss() orelse 0,
@@ -1744,11 +1751,11 @@ fn evalZigTest(
poller.reader(.stderr).tossBuffered();
// Clean up everything and wait for the child to exit.
- child.stdin.?.close();
+ child.stdin.?.close(io);
child.stdin = null;
poller.deinit();
child_killed = true;
- const term = try child.wait();
+ const term = try child.wait(io);
run.step.result_peak_rss = @max(
run.step.result_peak_rss,
child.resource_usage_statistics.getMaxRss() orelse 0,
@@ -1836,6 +1843,7 @@ fn pollZigTest(
switch (ctx.fuzz.mode) {
.forever => {
sendRunFuzzTestMessage(
+ io,
child.stdin.?,
ctx.unit_test_index,
.forever,
@@ -1844,6 +1852,7 @@ fn pollZigTest(
},
.limit => |limit| {
sendRunFuzzTestMessage(
+ io,
child.stdin.?,
ctx.unit_test_index,
.iterations,
@@ -1853,11 +1862,11 @@ fn pollZigTest(
}
} else if (opt_metadata.*) |*md| {
// Previous unit test process died or was killed; we're continuing where it left off
- requestNextTest(child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };
+ requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };
} else {
// Running unit tests normally
run.fuzz_tests.clearRetainingCapacity();
- sendMessage(child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err };
+ sendMessage(io, child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err };
}
var active_test_index: ?u32 = null;
@@ -1973,7 +1982,7 @@ fn pollZigTest(
active_test_index = null;
if (timer) |*t| t.reset();
- requestNextTest(child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err };
+ requestNextTest(io, child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err };
},
.test_started => {
active_test_index = opt_metadata.*.?.next_index - 1;
@@ -2022,7 +2031,7 @@ fn pollZigTest(
active_test_index = null;
if (timer) |*t| md.ns_per_test[tr_hdr.index] = t.lap();
- requestNextTest(child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };
+ requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };
},
.coverage_id => {
coverage_id = body_r.takeInt(u64, .little) catch unreachable;
@@ -2093,7 +2102,7 @@ pub const CachedTestMetadata = struct {
}
};
-fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void {
+fn requestNextTest(io: Io, in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void {
while (metadata.next_index < metadata.names.len) {
const i = metadata.next_index;
metadata.next_index += 1;
@@ -2104,31 +2113,31 @@ fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr
if (sub_prog_node.*) |n| n.end();
sub_prog_node.* = metadata.prog_node.start(name, 0);
- try sendRunTestMessage(in, .run_test, i);
+ try sendRunTestMessage(io, in, .run_test, i);
return;
} else {
metadata.next_index = std.math.maxInt(u32); // indicate that all tests are done
- try sendMessage(in, .exit);
+ try sendMessage(io, in, .exit);
}
}
-fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void {
+fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void {
const header: std.zig.Client.Message.Header = .{
.tag = tag,
.bytes_len = 0,
};
- var w = file.writer(&.{});
+ var w = file.writer(io, &.{});
w.interface.writeStruct(header, .little) catch |err| switch (err) {
error.WriteFailed => return w.err.?,
};
}
-fn sendRunTestMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag, index: u32) !void {
+fn sendRunTestMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void {
const header: std.zig.Client.Message.Header = .{
.tag = tag,
.bytes_len = 4,
};
- var w = file.writer(&.{});
+ var w = file.writer(io, &.{});
w.interface.writeStruct(header, .little) catch |err| switch (err) {
error.WriteFailed => return w.err.?,
};
@@ -2138,7 +2147,8 @@ fn sendRunTestMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag, index:
}
fn sendRunFuzzTestMessage(
- file: std.fs.File,
+ io: Io,
+ file: Io.File,
index: u32,
kind: std.Build.abi.fuzz.LimitKind,
amount_or_instance: u64,
@@ -2147,7 +2157,7 @@ fn sendRunFuzzTestMessage(
.tag = .start_fuzzing,
.bytes_len = 4 + 1 + 8,
};
- var w = file.writer(&.{});
+ var w = file.writer(io, &.{});
w.interface.writeStruct(header, .little) catch |err| switch (err) {
error.WriteFailed => return w.err.?,
};
@@ -2167,30 +2177,30 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {
const io = b.graph.io;
const arena = b.allocator;
- try child.spawn();
- errdefer _ = child.kill() catch {};
+ try child.spawn(io);
+ errdefer _ = child.kill(io) catch {};
try child.waitForSpawn();
switch (run.stdin) {
.bytes => |bytes| {
- child.stdin.?.writeAll(bytes) catch |err| {
- return run.step.fail("unable to write stdin: {s}", .{@errorName(err)});
+ child.stdin.?.writeStreamingAll(io, bytes) catch |err| {
+ return run.step.fail("unable to write stdin: {t}", .{err});
};
- child.stdin.?.close();
+ child.stdin.?.close(io);
child.stdin = null;
},
.lazy_path => |lazy_path| {
const path = lazy_path.getPath3(b, &run.step);
- const file = path.root_dir.handle.openFile(path.subPathOrDot(), .{}) catch |err| {
- return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)});
+ const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| {
+ return run.step.fail("unable to open stdin file: {t}", .{err});
};
- defer file.close();
+ defer file.close(io);
// TODO https://github.com/ziglang/zig/issues/23955
var read_buffer: [1024]u8 = undefined;
var file_reader = file.reader(io, &read_buffer);
var write_buffer: [1024]u8 = undefined;
- var stdin_writer = child.stdin.?.writer(&write_buffer);
+ var stdin_writer = child.stdin.?.writer(io, &write_buffer);
_ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) {
error.ReadFailed => return run.step.fail("failed to read from {f}: {t}", .{
path, file_reader.err.?,
@@ -2204,7 +2214,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {
stdin_writer.err.?,
}),
};
- child.stdin.?.close();
+ child.stdin.?.close(io);
child.stdin = null;
},
.none => {},
@@ -2263,7 +2273,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {
run.step.result_peak_rss = child.resource_usage_statistics.getMaxRss() orelse 0;
return .{
- .term = try child.wait(),
+ .term = try child.wait(io),
.stdout = stdout_bytes,
.stderr = stderr_bytes,
};
@@ -2276,7 +2286,7 @@ fn addPathForDynLibs(run: *Run, artifact: *Step.Compile) void {
if (compile.root_module.resolved_target.?.result.os.tag == .windows and
compile.isDynamicLibrary())
{
- addPathDir(run, fs.path.dirname(compile.getEmittedBin().getPath2(b, &run.step)).?);
+ addPathDir(run, Dir.path.dirname(compile.getEmittedBin().getPath2(b, &run.step)).?);
}
}
}
diff --git a/lib/std/Build/Step/UpdateSourceFiles.zig b/lib/std/Build/Step/UpdateSourceFiles.zig
index 7cdb521d21..1c4c94f9cf 100644
--- a/lib/std/Build/Step/UpdateSourceFiles.zig
+++ b/lib/std/Build/Step/UpdateSourceFiles.zig
@@ -78,13 +78,13 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
var any_miss = false;
for (usf.output_source_files.items) |output_source_file| {
if (fs.path.dirname(output_source_file.sub_path)) |dirname| {
- b.build_root.handle.makePath(dirname) catch |err| {
+ b.build_root.handle.createDirPath(io, dirname) catch |err| {
return step.fail("unable to make path '{f}{s}': {t}", .{ b.build_root, dirname, err });
};
}
switch (output_source_file.contents) {
.bytes => |bytes| {
- b.build_root.handle.writeFile(.{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| {
+ b.build_root.handle.writeFile(io, .{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| {
return step.fail("unable to write file '{f}{s}': {t}", .{
b.build_root, output_source_file.sub_path, err,
});
@@ -99,7 +99,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
.cwd(),
io,
source_path,
- b.build_root.handle.adaptToNewApi(),
+ b.build_root.handle,
output_source_file.sub_path,
.{},
) catch |err| {
diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig
index 030c7c6811..145c7f9bb3 100644
--- a/lib/std/Build/Step/WriteFile.zig
+++ b/lib/std/Build/Step/WriteFile.zig
@@ -206,9 +206,9 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
}
- const open_dir_cache = try arena.alloc(fs.Dir, write_file.directories.items.len);
+ const open_dir_cache = try arena.alloc(Io.Dir, write_file.directories.items.len);
var open_dirs_count: usize = 0;
- defer closeDirs(open_dir_cache[0..open_dirs_count]);
+ defer Io.Dir.closeMany(io, open_dir_cache[0..open_dirs_count]);
for (write_file.directories.items, open_dir_cache) |dir, *open_dir_cache_elem| {
man.hash.addBytes(dir.sub_path);
@@ -218,7 +218,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const need_derived_inputs = try step.addDirectoryWatchInput(dir.source);
const src_dir_path = dir.source.getPath3(b, step);
- var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
+ var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
return step.fail("unable to open source directory '{f}': {s}", .{
src_dir_path, @errorName(err),
});
@@ -228,7 +228,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
var it = try src_dir.walk(gpa);
defer it.deinit();
- while (try it.next()) |entry| {
+ while (try it.next(io)) |entry| {
if (!dir.options.pathIncluded(entry.path)) continue;
switch (entry.kind) {
@@ -259,16 +259,13 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
write_file.generated_directory.path = try b.cache_root.join(arena, &.{ "o", &digest });
- var cache_dir = b.cache_root.handle.makeOpenPath(cache_path, .{}) catch |err| {
- return step.fail("unable to make path '{f}{s}': {s}", .{
- b.cache_root, cache_path, @errorName(err),
- });
- };
- defer cache_dir.close();
+ var cache_dir = b.cache_root.handle.createDirPathOpen(io, cache_path, .{}) catch |err|
+ return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, cache_path, err });
+ defer cache_dir.close(io);
for (write_file.files.items) |file| {
if (fs.path.dirname(file.sub_path)) |dirname| {
- cache_dir.makePath(dirname) catch |err| {
+ cache_dir.createDirPath(io, dirname) catch |err| {
return step.fail("unable to make path '{f}{s}{c}{s}': {t}", .{
b.cache_root, cache_path, fs.path.sep, dirname, err,
});
@@ -276,7 +273,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
switch (file.contents) {
.bytes => |bytes| {
- cache_dir.writeFile(.{ .sub_path = file.sub_path, .data = bytes }) catch |err| {
+ cache_dir.writeFile(io, .{ .sub_path = file.sub_path, .data = bytes }) catch |err| {
return step.fail("unable to write file '{f}{s}{c}{s}': {t}", .{
b.cache_root, cache_path, fs.path.sep, file.sub_path, err,
});
@@ -284,7 +281,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
},
.copy => |file_source| {
const source_path = file_source.getPath2(b, step);
- const prev_status = Io.Dir.updateFile(.cwd(), io, source_path, cache_dir.adaptToNewApi(), file.sub_path, .{}) catch |err| {
+ const prev_status = Io.Dir.updateFile(.cwd(), io, source_path, cache_dir, file.sub_path, .{}) catch |err| {
return step.fail("unable to update file from '{s}' to '{f}{s}{c}{s}': {t}", .{
source_path, b.cache_root, cache_path, fs.path.sep, file.sub_path, err,
});
@@ -303,7 +300,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const dest_dirname = dir.sub_path;
if (dest_dirname.len != 0) {
- cache_dir.makePath(dest_dirname) catch |err| {
+ cache_dir.createDirPath(io, dest_dirname) catch |err| {
return step.fail("unable to make path '{f}{s}{c}{s}': {s}", .{
b.cache_root, cache_path, fs.path.sep, dest_dirname, @errorName(err),
});
@@ -312,19 +309,19 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
var it = try already_open_dir.walk(gpa);
defer it.deinit();
- while (try it.next()) |entry| {
+ while (try it.next(io)) |entry| {
if (!dir.options.pathIncluded(entry.path)) continue;
const src_entry_path = try src_dir_path.join(arena, entry.path);
const dest_path = b.pathJoin(&.{ dest_dirname, entry.path });
switch (entry.kind) {
- .directory => try cache_dir.makePath(dest_path),
+ .directory => try cache_dir.createDirPath(io, dest_path),
.file => {
const prev_status = Io.Dir.updateFile(
- src_entry_path.root_dir.handle.adaptToNewApi(),
+ src_entry_path.root_dir.handle,
io,
src_entry_path.sub_path,
- cache_dir.adaptToNewApi(),
+ cache_dir,
dest_path,
.{},
) catch |err| {
@@ -341,7 +338,3 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
try step.writeManifest(&man);
}
-
-fn closeDirs(dirs: []fs.Dir) void {
- for (dirs) |*d| d.close();
-}