Files
Andrew Kelley b4dbe483a7 std.Build: adjust temp files API
Remove the RemoveDir step with no replacement. This step had no valid
purpose. Mutating source files? That should be done with
UpdateSourceFiles step. Deleting temporary directories? That required
creating the tmp directories in the configure phase which is broken.
Deleting cached artifacts? That's going to cause problems.

Similarly, remove the `Build.makeTempPath` function. This was used to
create a temporary path in the configure place which, again, is the
wrong place to do it.

Instead, the WriteFile step has been updated with more functionality:

tmp mode: In this mode, the directory will be placed inside "tmp" rather
than "o", and caching will be skipped. During the `make` phase, the step
will always do all the file system operations, and on successful build
completion, the dir will be deleted along with all other tmp
directories. The directory is therefore eligible to be used for
mutations by other steps. `Build.addTempFiles` is introduced to
initialize a WriteFile step with this mode.

mutate mode: The operations will not be performed against a freshly
created directory, but instead act against a temporary directory.
`Build.addMutateFiles` is introduced to initialize a WriteFile step with
this mode.

`Build.tmpPath` is introduced, which is a shortcut for
`Build.addTempFiles` followed by `WriteFile.getDirectory`.

* give Cache a gpa rather than arena because that's what it asks for
2026-01-04 17:23:45 -08:00

81 lines
2.4 KiB
Zig

const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const test_step = b.step("test", "Test it");
b.default_step = test_step;
const touch_src = b.path("touch.zig");
const touch = b.addExecutable(.{
.name = "touch",
.root_module = b.createModule(.{
.root_source_file = touch_src,
.optimize = .Debug,
.target = target,
}),
});
const generated = b.addRunArtifact(touch).addOutputFileArg("subdir" ++ std.fs.path.sep_str ++ "generated.txt");
const exists_in = b.addExecutable(.{
.name = "exists_in",
.root_module = b.createModule(.{
.root_source_file = b.path("exists_in.zig"),
.optimize = .Debug,
.target = target,
}),
});
const has_basename = b.addExecutable(.{
.name = "has_basename",
.root_module = b.createModule(.{
.root_source_file = b.path("has_basename.zig"),
.optimize = .Debug,
.target = target,
}),
});
// Known path:
addTestRun(test_step, exists_in, touch_src.dirname(), &.{"touch.zig"});
// Generated file:
addTestRun(test_step, exists_in, generated.dirname(), &.{"generated.txt"});
// Generated file multiple levels:
addTestRun(test_step, exists_in, generated.dirname().dirname(), &.{
"subdir" ++ std.fs.path.sep_str ++ "generated.txt",
});
// Cache root:
const cache_dir = b.cache_root.path orelse
(b.cache_root.join(b.allocator, &.{"."}) catch @panic("OOM"));
addTestRun(
test_step,
has_basename,
generated.dirname().dirname().dirname().dirname(),
&.{std.fs.path.basename(cache_dir)},
);
// Absolute path:
const write_files = b.addWriteFiles();
_ = write_files.add("foo.txt", "");
const abs_path = write_files.getDirectory();
addTestRun(test_step, exists_in, abs_path, &.{"foo.txt"});
}
// Runs exe with the parameters [dirname, args...].
// Expects the exit code to be 0.
fn addTestRun(
test_step: *std.Build.Step,
exe: *std.Build.Step.Compile,
dirname: std.Build.LazyPath,
args: []const []const u8,
) void {
const run = test_step.owner.addRunArtifact(exe);
run.addDirectoryArg(dirname);
run.addArgs(args);
run.expectExitCode(0);
test_step.dependOn(&run.step);
}