commit 5f78220dbe17133ece22e4f6a7e5e6337bfd7800 (tree)
parent d95dcb2a6238787e18c60f4ae4bfcf8fd757bd0c
Author: Techatrix <techatrix@mailbox.org>
Date: Sun, 14 Jun 2026 03:44:09 +0200
std.Build.Step.Run: add support specifying preopens
Diffstat:
4 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/lib/compiler/Maker/Step/Run.zig b/lib/compiler/Maker/Step/Run.zig
@@ -65,6 +65,12 @@ pub fn make(
}
}
+ for (conf_run.preopen_names.slice, conf_run.preopen_paths.slice) |name, path| {
+ man.hash.addBytesZ(name.slice(conf));
+ const cwd_path = try maker.resolveLazyPathIndex(arena, path, run_index);
+ man.hash.addBytes(try cwd_path.toString(arena));
+ }
+
man.hash.add(graph.fuzzing);
man.hash.add(conf_run.flags.color);
man.hash.add(conf_run.flags.disable_zig_progress);
@@ -1912,9 +1918,15 @@ fn runCommand(
},
.wasmtime => |bin_name| {
if (graph.enable_wasmtime) {
- try interp_argv.ensureUnusedCapacity(arena, 3 + argv.len);
+ try interp_argv.ensureUnusedCapacity(arena, 3 + argv.len + conf_run.preopen_names.slice.len);
interp_argv.appendAssumeCapacity(bin_name);
interp_argv.appendAssumeCapacity("--dir=.");
+ for (conf_run.preopen_names.slice, conf_run.preopen_paths.slice) |name, lazy_path| {
+ const path = try maker.resolveLazyPath(arena, lazy_path.get(conf), run_index);
+ path.root_dir.handle.createDirPath(io, path.subPathOrDot()) catch |e|
+ return step.fail(maker, "failed creating directory {f}: {t}", .{ path, e });
+ interp_argv.appendAssumeCapacity(try allocPrint(arena, "--dir={f}::{s}", .{ path, name.slice(conf) }));
+ }
// Wasmtime doeesn't inherit environment variables from the parent process
// by default. '-S inherit-env' was added in Wasmtime version 20.
interp_argv.appendAssumeCapacity("-Sinherit-env");
diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig
@@ -1070,6 +1070,8 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.file_inputs = .{ .slice = try s.initLazyPathList(run.file_inputs.items) },
.args = .{ .slice = try s.initArgsList(run.argv.items) },
.cwd = .{ .value = try s.addOptionalLazyPath(run.cwd) },
+ .preopen_names = .{ .slice = try s.initStringList(run.preopens.keys()) },
+ .preopen_paths = .{ .slice = try s.initLazyPathList(run.preopens.values()) },
.captured_stdout = .{ .value = if (run.captured_stdout) |cs| .{
.basename = try wc.addString(cs.basename),
.generated_file = cs.generated_file,
diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig
@@ -571,6 +571,8 @@ pub const Step = extern struct {
flags2: Flags2,
args: Storage.LengthPrefixedList(Arg.Index),
cwd: Storage.FlagOptional(.flags, .cwd, LazyPath.Index),
+ preopen_names: Storage.LengthPrefixedList(String),
+ preopen_paths: Storage.LengthPrefixedList(LazyPath.Index),
captured_stdout: Storage.FlagOptional(.flags, .captured_stdout, CapturedStream),
captured_stderr: Storage.FlagOptional(.flags, .captured_stderr, CapturedStream),
file_inputs: Storage.LengthPrefixedList(LazyPath.Index),
diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig
@@ -26,6 +26,10 @@ cwd: ?Build.LazyPath,
/// Override this field to modify the environment, or use setEnvironmentVariable
environ_map: ?*EnvMap,
+/// Named files that will be provided to the parent process.
+/// See `std.process.Preopens`.
+preopens: std.array_hash_map.String(Build.LazyPath),
+
/// Controls the `NO_COLOR` and `CLICOLOR_FORCE` environment variables.
color: Color = .auto,
@@ -200,6 +204,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
.argv = .empty,
.cwd = null,
.environ_map = null,
+ .preopens = .empty,
.disable_zig_progress = false,
.stdio = .infer_from_args,
.stdin = .none,
@@ -615,6 +620,17 @@ pub fn removeEnvironmentVariable(run: *Run, key: []const u8) void {
_ = run.getEnvMap().swapRemove(key);
}
+pub fn setPreopen(run: *Run, name: []const u8, resource: Build.LazyPath) void {
+ const graph = run.step.owner.graph;
+ const arena = graph.arena;
+ resource.addStepDependencies(&run.step);
+ run.preopens.put(
+ arena,
+ graph.dupeString(name),
+ resource.dupe(graph),
+ ) catch @panic("OOM");
+}
+
/// Adds a check for exact stderr match. Does not add any other checks.
pub fn expectStdErrEqual(run: *Run, bytes: []const u8) void {
const graph = run.step.owner.graph;