Commit d1c14f2f52
Changed files (6)
lib/std/Build/Step/UpdateSourceFiles.zig
@@ -0,0 +1,114 @@
+//! Writes data to paths relative to the package root, effectively mutating the
+//! package's source files. Be careful with the latter functionality; it should
+//! not be used during the normal build process, but as a utility run by a
+//! developer with intention to update source files, which will then be
+//! committed to version control.
+const std = @import("std");
+const Step = std.Build.Step;
+const fs = std.fs;
+const ArrayList = std.ArrayList;
+const UpdateSourceFiles = @This();
+
+step: Step,
+output_source_files: std.ArrayListUnmanaged(OutputSourceFile),
+
+pub const base_id: Step.Id = .update_source_files;
+
+pub const OutputSourceFile = struct {
+ contents: Contents,
+ sub_path: []const u8,
+};
+
+pub const Contents = union(enum) {
+ bytes: []const u8,
+ copy: std.Build.LazyPath,
+};
+
+pub fn create(owner: *std.Build) *UpdateSourceFiles {
+ const usf = owner.allocator.create(UpdateSourceFiles) catch @panic("OOM");
+ usf.* = .{
+ .step = Step.init(.{
+ .id = base_id,
+ .name = "UpdateSourceFiles",
+ .owner = owner,
+ .makeFn = make,
+ }),
+ .output_source_files = .{},
+ };
+ return usf;
+}
+
+/// A path relative to the package root.
+///
+/// Be careful with this because it updates source files. This should not be
+/// used as part of the normal build process, but as a utility occasionally
+/// run by a developer with intent to modify source files and then commit
+/// those changes to version control.
+pub fn addCopyFileToSource(usf: *UpdateSourceFiles, source: std.Build.LazyPath, sub_path: []const u8) void {
+ const b = usf.step.owner;
+ usf.output_source_files.append(b.allocator, .{
+ .contents = .{ .copy = source },
+ .sub_path = sub_path,
+ }) catch @panic("OOM");
+ source.addStepDependencies(&usf.step);
+}
+
+/// A path relative to the package root.
+///
+/// Be careful with this because it updates source files. This should not be
+/// used as part of the normal build process, but as a utility occasionally
+/// run by a developer with intent to modify source files and then commit
+/// those changes to version control.
+pub fn addBytesToSource(usf: *UpdateSourceFiles, bytes: []const u8, sub_path: []const u8) void {
+ const b = usf.step.owner;
+ usf.output_source_files.append(b.allocator, .{
+ .contents = .{ .bytes = bytes },
+ .sub_path = sub_path,
+ }) catch @panic("OOM");
+}
+
+fn make(step: *Step, prog_node: std.Progress.Node) !void {
+ _ = prog_node;
+ const b = step.owner;
+ const usf: *UpdateSourceFiles = @fieldParentPtr("step", step);
+
+ 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| {
+ return step.fail("unable to make path '{}{s}': {s}", .{
+ b.build_root, dirname, @errorName(err),
+ });
+ };
+ }
+ switch (output_source_file.contents) {
+ .bytes => |bytes| {
+ b.build_root.handle.writeFile(.{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| {
+ return step.fail("unable to write file '{}{s}': {s}", .{
+ b.build_root, output_source_file.sub_path, @errorName(err),
+ });
+ };
+ any_miss = true;
+ },
+ .copy => |file_source| {
+ if (!step.inputs.populated()) try step.addWatchInput(file_source);
+
+ const source_path = file_source.getPath2(b, step);
+ const prev_status = fs.Dir.updateFile(
+ fs.cwd(),
+ source_path,
+ b.build_root.handle,
+ output_source_file.sub_path,
+ .{},
+ ) catch |err| {
+ return step.fail("unable to update file from '{s}' to '{}{s}': {s}", .{
+ source_path, b.build_root, output_source_file.sub_path, @errorName(err),
+ });
+ };
+ any_miss = any_miss or prev_status == .stale;
+ },
+ }
+ }
+
+ step.result_cached = !any_miss;
+}
lib/std/Build/Step/WriteFile.zig
@@ -1,13 +1,6 @@
-//! WriteFile is primarily used to create a directory in an appropriate
-//! location inside the local cache which has a set of files that have either
-//! been generated during the build, or are copied from the source package.
-//!
-//! However, this step has an additional capability of writing data to paths
-//! relative to the package root, effectively mutating the package's source
-//! files. Be careful with the latter functionality; it should not be used
-//! during the normal build process, but as a utility run by a developer with
-//! intention to update source files, which will then be committed to version
-//! control.
+//! WriteFile is used to create a directory in an appropriate location inside
+//! the local cache which has a set of files that have either been generated
+//! during the build, or are copied from the source package.
const std = @import("std");
const Step = std.Build.Step;
const fs = std.fs;
@@ -19,8 +12,6 @@ step: Step,
// The elements here are pointers because we need stable pointers for the GeneratedFile field.
files: std.ArrayListUnmanaged(File),
directories: std.ArrayListUnmanaged(Directory),
-
-output_source_files: std.ArrayListUnmanaged(OutputSourceFile),
generated_directory: std.Build.GeneratedFile,
pub const base_id: Step.Id = .write_file;
@@ -52,11 +43,6 @@ pub const Directory = struct {
};
};
-pub const OutputSourceFile = struct {
- contents: Contents,
- sub_path: []const u8,
-};
-
pub const Contents = union(enum) {
bytes: []const u8,
copy: std.Build.LazyPath,
@@ -73,7 +59,6 @@ pub fn create(owner: *std.Build) *WriteFile {
}),
.files = .{},
.directories = .{},
- .output_source_files = .{},
.generated_directory = .{ .step = &write_file.step },
};
return write_file;
@@ -150,33 +135,6 @@ pub fn addCopyDirectory(
};
}
-/// A path relative to the package root.
-/// Be careful with this because it updates source files. This should not be
-/// used as part of the normal build process, but as a utility occasionally
-/// run by a developer with intent to modify source files and then commit
-/// those changes to version control.
-pub fn addCopyFileToSource(write_file: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) void {
- const b = write_file.step.owner;
- write_file.output_source_files.append(b.allocator, .{
- .contents = .{ .copy = source },
- .sub_path = sub_path,
- }) catch @panic("OOM");
- source.addStepDependencies(&write_file.step);
-}
-
-/// A path relative to the package root.
-/// Be careful with this because it updates source files. This should not be
-/// used as part of the normal build process, but as a utility occasionally
-/// run by a developer with intent to modify source files and then commit
-/// those changes to version control.
-pub fn addBytesToSource(write_file: *WriteFile, bytes: []const u8, sub_path: []const u8) void {
- const b = write_file.step.owner;
- write_file.output_source_files.append(b.allocator, .{
- .contents = .{ .bytes = bytes },
- .sub_path = sub_path,
- }) catch @panic("OOM");
-}
-
/// Returns a `LazyPath` representing the base directory that contains all the
/// files from this `WriteFile`.
pub fn getDirectory(write_file: *WriteFile) std.Build.LazyPath {
@@ -202,46 +160,6 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void {
const b = step.owner;
const write_file: *WriteFile = @fieldParentPtr("step", step);
- // Writing to source files is kind of an extra capability of this
- // WriteFile - arguably it should be a different step. But anyway here
- // it is, it happens unconditionally and does not interact with the other
- // files here.
- var any_miss = false;
- for (write_file.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| {
- return step.fail("unable to make path '{}{s}': {s}", .{
- b.build_root, dirname, @errorName(err),
- });
- };
- }
- switch (output_source_file.contents) {
- .bytes => |bytes| {
- b.build_root.handle.writeFile(.{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| {
- return step.fail("unable to write file '{}{s}': {s}", .{
- b.build_root, output_source_file.sub_path, @errorName(err),
- });
- };
- any_miss = true;
- },
- .copy => |file_source| {
- const source_path = file_source.getPath2(b, step);
- const prev_status = fs.Dir.updateFile(
- fs.cwd(),
- source_path,
- b.build_root.handle,
- output_source_file.sub_path,
- .{},
- ) catch |err| {
- return step.fail("unable to update file from '{s}' to '{}{s}': {s}", .{
- source_path, b.build_root, output_source_file.sub_path, @errorName(err),
- });
- };
- any_miss = any_miss or prev_status == .stale;
- },
- }
- }
-
// The cache is used here not really as a way to speed things up - because writing
// the data to a file would probably be very fast - but as a way to find a canonical
// location to put build artifacts.
@@ -278,6 +196,7 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void {
if (try step.cacheHit(&man)) {
const digest = man.final();
write_file.generated_directory.path = try b.cache_root.join(b.allocator, &.{ "o", &digest });
+ step.result_cached = true;
return;
}
lib/std/Build/Step.zig
@@ -102,6 +102,7 @@ pub const Id = enum {
fmt,
translate_c,
write_file,
+ update_source_files,
run,
check_file,
check_object,
@@ -122,6 +123,7 @@ pub const Id = enum {
.fmt => Fmt,
.translate_c => TranslateC,
.write_file => WriteFile,
+ .update_source_files => UpdateSourceFiles,
.run => Run,
.check_file => CheckFile,
.check_object => CheckObject,
@@ -148,6 +150,7 @@ pub const RemoveDir = @import("Step/RemoveDir.zig");
pub const Run = @import("Step/Run.zig");
pub const TranslateC = @import("Step/TranslateC.zig");
pub const WriteFile = @import("Step/WriteFile.zig");
+pub const UpdateSourceFiles = @import("Step/UpdateSourceFiles.zig");
pub const Inputs = struct {
table: Table,
@@ -680,4 +683,5 @@ test {
_ = Run;
_ = TranslateC;
_ = WriteFile;
+ _ = UpdateSourceFiles;
}
lib/std/Build.zig
@@ -1052,6 +1052,10 @@ pub fn addWriteFiles(b: *Build) *Step.WriteFile {
return Step.WriteFile.create(b);
}
+pub fn addUpdateSourceFiles(b: *Build) *Step.UpdateSourceFiles {
+ return Step.UpdateSourceFiles.create(b);
+}
+
pub fn addRemoveDirTree(b: *Build, dir_path: LazyPath) *Step.RemoveDir {
return Step.RemoveDir.create(b, dir_path);
}
test/tests.zig
@@ -882,7 +882,7 @@ pub fn addCliTests(b: *std.Build) *Step {
const unformatted_code_utf16 = "\xff\xfe \x00 \x00 \x00 \x00/\x00/\x00 \x00n\x00o\x00 \x00r\x00e\x00a\x00s\x00o\x00n\x00";
const fmt6_path = std.fs.path.join(b.allocator, &.{ tmp_path, "fmt6.zig" }) catch @panic("OOM");
- const write6 = b.addWriteFiles();
+ const write6 = b.addUpdateSourceFiles();
write6.addBytesToSource(unformatted_code_utf16, fmt6_path);
write6.step.dependOn(&run5.step);
build.zig
@@ -595,7 +595,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
run_opt.addArg("-o");
run_opt.addFileArg(b.path("stage1/zig1.wasm"));
- const copy_zig_h = b.addWriteFiles();
+ const copy_zig_h = b.addUpdateSourceFiles();
copy_zig_h.addCopyFileToSource(b.path("lib/zig.h"), "stage1/zig.h");
const update_zig1_step = b.step("update-zig1", "Update stage1/zig1.wasm");