authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-08 13:18:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:35-07:00
logd7eab060db6aff326a957e4dbffcd09263f7ffbd
tree6c09212927ff8b7558f9f5ca5b79d81b30a018c0
parentf9f00c2dee151231361df7aa45a71ca33f90dcd1

configurer: serialize Step.UpdateSourceFiles


5 files changed, 63 insertions(+), 65 deletions(-)

lib/compiler/Maker/Step/UpdateSourceFiles.zig+4-4
...@@ -35,7 +35,7 @@ pub fn make(...@@ -35,7 +35,7 @@ pub fn make(
35 for (conf_usf.embeds.slice) |*embed| {35 for (conf_usf.embeds.slice) |*embed| {
36 const dest_path: Path = .{36 const dest_path: Path = .{
37 .root_dir = build_root,37 .root_dir = build_root,
38 .sub_path = embed.dest_path.slice(conf),38 .sub_path = embed.sub_path.slice(conf),
39 };39 };
40 if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| {40 if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| {
41 const dirname_path: Path = .{41 const dirname_path: Path = .{
...@@ -47,7 +47,7 @@ pub fn make(...@@ -47,7 +47,7 @@ pub fn make(
47 }47 }
48 dest_path.root_dir.handle.writeFile(io, .{48 dest_path.root_dir.handle.writeFile(io, .{
49 .sub_path = dest_path.sub_path,49 .sub_path = dest_path.sub_path,
50 .data = embed.bytes.slice(conf),50 .data = embed.contents.slice(conf),
51 }) catch |err| return step.fail(maker, "failed to write file {f}: {t}", .{ dest_path, err });51 }) catch |err| return step.fail(maker, "failed to write file {f}: {t}", .{ dest_path, err });
52 any_miss = true;52 any_miss = true;
53 progress_node.completeOne();53 progress_node.completeOne();
...@@ -56,7 +56,7 @@ pub fn make(...@@ -56,7 +56,7 @@ pub fn make(
56 for (conf_usf.copies.slice) |*copy| {56 for (conf_usf.copies.slice) |*copy| {
57 const dest_path: Path = .{57 const dest_path: Path = .{
58 .root_dir = build_root,58 .root_dir = build_root,
59 .sub_path = copy.dest_path.slice(conf),59 .sub_path = copy.sub_path.slice(conf),
60 };60 };
61 if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| {61 if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| {
62 const dirname_path: Path = .{62 const dirname_path: Path = .{
...@@ -66,7 +66,7 @@ pub fn make(...@@ -66,7 +66,7 @@ pub fn make(
66 dirname_path.root_dir.handle.createDirPath(io, dirname_path.sub_path) catch |err|66 dirname_path.root_dir.handle.createDirPath(io, dirname_path.sub_path) catch |err|
67 return step.fail(maker, "failed to create path {f}: {t}", .{ dirname_path, err });67 return step.fail(maker, "failed to create path {f}: {t}", .{ dirname_path, err });
68 }68 }
69 const src_lazy_path = copy.src_path.get(conf);69 const src_lazy_path = copy.src_file.get(conf);
70 const source_path = try maker.resolveLazyPath(arena, src_lazy_path, step_index);70 const source_path = try maker.resolveLazyPath(arena, src_lazy_path, step_index);
71 if (!step.inputs.populated()) try step.addWatchInput(maker, arena, src_lazy_path);71 if (!step.inputs.populated()) try step.addWatchInput(maker, arena, src_lazy_path);
7272
lib/compiler/configurer.zig+22-9
...@@ -464,6 +464,15 @@ const Serialize = struct {...@@ -464,6 +464,15 @@ const Serialize = struct {
464 return result;464 return result;
465 }465 }
466466
467 fn initCopyList(s: *Serialize, list: []const Step.WriteFile.Copy) ![]const Configuration.Step.WriteFile.Copy {
468 const result = try s.arena.alloc(Configuration.Step.WriteFile.Copy, list.len);
469 for (result, list) |*dest, src| dest.* = .{
470 .sub_path = src.sub_path,
471 .src_file = try s.addLazyPath(src.src_file),
472 };
473 return result;
474 }
475
467 fn initOptionalStringList(s: *Serialize, list: []const ?[]const u8) ![]const Configuration.OptionalString {476 fn initOptionalStringList(s: *Serialize, list: []const ?[]const u8) ![]const Configuration.OptionalString {
468 const wc = s.wc;477 const wc = s.wc;
469 const result = try s.arena.alloc(Configuration.OptionalString, list.len);478 const result = try s.arena.alloc(Configuration.OptionalString, list.len);
...@@ -905,12 +914,6 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -905,12 +914,6 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
905 .write_file => e: {914 .write_file => e: {
906 const wf: *Step.WriteFile = @fieldParentPtr("step", step);915 const wf: *Step.WriteFile = @fieldParentPtr("step", step);
907916
908 const copies = try arena.alloc(Configuration.Step.WriteFile.Copy, wf.copies.items.len);
909 for (copies, wf.copies.items) |*dest, src| dest.* = .{
910 .sub_path = src.sub_path,
911 .src_file = try s.addLazyPath(src.src_file),
912 };
913
914 const directories = try arena.alloc(917 const directories = try arena.alloc(
915 Configuration.Step.WriteFile.Directory,918 Configuration.Step.WriteFile.Directory,
916 wf.directories.items.len,919 wf.directories.items.len,
...@@ -925,7 +928,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -925,7 +928,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
925 break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.WriteFile, .{928 break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.WriteFile, .{
926 .flags = .{929 .flags = .{
927 .embeds = wf.embeds.items.len != 0,930 .embeds = wf.embeds.items.len != 0,
928 .copies = copies.len != 0,931 .copies = wf.copies.items.len != 0,
929 .directories = directories.len != 0,932 .directories = directories.len != 0,
930 .mode = switch (wf.mode) {933 .mode = switch (wf.mode) {
931 .whole_cached => .whole_cached,934 .whole_cached => .whole_cached,
...@@ -935,7 +938,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -935,7 +938,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
935 },938 },
936 .generated_directory = wf.generated_directory,939 .generated_directory = wf.generated_directory,
937 .embeds = .{ .slice = wf.embeds.items },940 .embeds = .{ .slice = wf.embeds.items },
938 .copies = .{ .slice = copies },941 .copies = .{ .slice = try s.initCopyList(wf.copies.items) },
939 .directories = .{ .slice = directories },942 .directories = .{ .slice = directories },
940 .mutate_path = .{ .value = switch (wf.mode) {943 .mutate_path = .{ .value = switch (wf.mode) {
941 .mutate => |lp| try s.addLazyPath(lp),944 .mutate => |lp| try s.addLazyPath(lp),
...@@ -943,7 +946,17 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -943,7 +946,17 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
943 } },946 } },
944 })));947 })));
945 },948 },
946 .update_source_files => @panic("TODO"),949 .update_source_files => e: {
950 const usf: *Step.UpdateSourceFiles = @fieldParentPtr("step", step);
951 break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.UpdateSourceFiles, .{
952 .flags = .{
953 .embeds = usf.embeds.items.len != 0,
954 .copies = usf.copies.items.len != 0,
955 },
956 .embeds = .{ .slice = usf.embeds.items },
957 .copies = .{ .slice = try s.initCopyList(usf.copies.items) },
958 })));
959 },
947 .run => e: {960 .run => e: {
948 const run: *Step.Run = @fieldParentPtr("step", step);961 const run: *Step.Run = @fieldParentPtr("step", step);
949 var expect_stderr_exact: ?Configuration.Bytes = null;962 var expect_stderr_exact: ?Configuration.Bytes = null;
lib/std/Build/Configuration.zig+2-11
...@@ -1229,17 +1229,8 @@ pub const Step = extern struct {...@@ -1229,17 +1229,8 @@ pub const Step = extern struct {
1229 embeds: Storage.FlagLengthPrefixedList(.flags, .embeds, Embed),1229 embeds: Storage.FlagLengthPrefixedList(.flags, .embeds, Embed),
1230 copies: Storage.FlagLengthPrefixedList(.flags, .copies, Copy),1230 copies: Storage.FlagLengthPrefixedList(.flags, .copies, Copy),
12311231
1232 pub const Embed = extern struct {1232 pub const Embed = WriteFile.Embed;
1233 /// Relative to build root.1233 pub const Copy = WriteFile.Copy;
1234 dest_path: String,
1235 bytes: Bytes,
1236 };
1237
1238 pub const Copy = extern struct {
1239 /// Relative to build root.
1240 dest_path: String,
1241 src_path: LazyPath.Index,
1242 };
12431234
1244 pub const Flags = packed struct(u32) {1235 pub const Flags = packed struct(u32) {
1245 tag: Tag = .update_source_files,1236 tag: Tag = .update_source_files,
lib/std/Build/Step/UpdateSourceFiles.zig+35-36
...@@ -6,64 +6,63 @@...@@ -6,64 +6,63 @@
6const UpdateSourceFiles = @This();6const UpdateSourceFiles = @This();
77
8const std = @import("std");8const std = @import("std");
9const Io = std.Io;
10const Step = std.Build.Step;9const Step = std.Build.Step;
11const fs = std.fs;10const Configuration = std.Build.Configuration;
12const ArrayList = std.ArrayList;
1311
14step: Step,12step: Step,
15output_source_files: std.ArrayList(OutputSourceFile),13embeds: std.ArrayList(Embed) = .empty,
14copies: std.ArrayList(Copy) = .empty,
1615
17pub const base_tag: Step.Tag = .update_source_files;16pub const base_tag: Step.Tag = .update_source_files;
1817
19pub const OutputSourceFile = struct {18pub const Embed = Step.WriteFile.Embed;
20 contents: Contents,19pub const Copy = Step.WriteFile.Copy;
21 sub_path: []const u8,
22};
23
24pub const Contents = union(enum) {
25 bytes: []const u8,
26 copy: std.Build.LazyPath,
27};
2820
29pub fn create(owner: *std.Build) *UpdateSourceFiles {21pub fn create(owner: *std.Build) *UpdateSourceFiles {
30 const usf = owner.allocator.create(UpdateSourceFiles) catch @panic("OOM");22 const graph = owner.graph;
23 const usf = graph.create(UpdateSourceFiles);
31 usf.* = .{24 usf.* = .{
32 .step = .init(.{25 .step = .init(.{
33 .tag = base_tag,26 .tag = base_tag,
34 .name = "UpdateSourceFiles",27 .name = "UpdateSourceFiles",
35 .owner = owner,28 .owner = owner,
36 }),29 }),
37 .output_source_files = .empty,
38 };30 };
39 return usf;31 return usf;
40}32}
4133
42/// A path relative to the package root.34/// Overwrites a path relative to the build root with the contents of another file.
43///35///
44/// Be careful with this because it updates source files. This should not be36/// Because it updates source files, this should not be used as part of the
45/// used as part of the normal build process, but as a utility occasionally37/// normal build process, but as a utility occasionally run by a developer with
46/// run by a developer with intent to modify source files and then commit38/// intent to modify source files and then commit those changes to version
47/// those changes to version control.39/// control.
48pub fn addCopyFileToSource(usf: *UpdateSourceFiles, source: std.Build.LazyPath, sub_path: []const u8) void {40pub fn addCopyFileToSource(usf: *UpdateSourceFiles, src_file: std.Build.LazyPath, sub_path: []const u8) void {
49 const b = usf.step.owner;41 const graph = usf.step.owner.graph;
50 usf.output_source_files.append(b.allocator, .{42 const wc = &graph.wip_configuration;
51 .contents = .{ .copy = source },43 const arena = graph.arena;
52 .sub_path = sub_path,44
45 usf.copies.append(arena, .{
46 .sub_path = wc.addString(sub_path) catch @panic("OOM"),
47 .src_file = src_file.dupe(graph),
53 }) catch @panic("OOM");48 }) catch @panic("OOM");
54 source.addStepDependencies(&usf.step);49
50 src_file.addStepDependencies(&usf.step);
55}51}
5652
57/// A path relative to the package root.53/// Overwrites a path relative to the package root with the provided bytes.
58///54///
59/// Be careful with this because it updates source files. This should not be55/// Because it updates source files, this should not be used as part of the
60/// used as part of the normal build process, but as a utility occasionally56/// normal build process, but as a utility occasionally run by a developer with
61/// run by a developer with intent to modify source files and then commit57/// intent to modify source files and then commit those changes to version
62/// those changes to version control.58/// control.
63pub fn addBytesToSource(usf: *UpdateSourceFiles, bytes: []const u8, sub_path: []const u8) void {59pub fn addBytesToSource(usf: *UpdateSourceFiles, contents: []const u8, sub_path: []const u8) void {
64 const b = usf.step.owner;60 const graph = usf.step.owner.graph;
65 usf.output_source_files.append(b.allocator, .{61 const wc = &graph.wip_configuration;
66 .contents = .{ .bytes = bytes },62 const arena = graph.arena;
67 .sub_path = sub_path,63
64 usf.embeds.append(arena, .{
65 .sub_path = wc.addString(sub_path) catch @panic("OOM"),
66 .contents = wc.addBytes(contents) catch @panic("OOM"),
68 }) catch @panic("OOM");67 }) catch @panic("OOM");
69}68}
lib/std/Build/Step/WriteFile.zig-5
...@@ -4,15 +4,10 @@...@@ -4,15 +4,10 @@
4const WriteFile = @This();4const WriteFile = @This();
55
6const std = @import("std");6const std = @import("std");
7const Io = std.Io;
8const Dir = std.Io.Dir;
9const Step = std.Build.Step;7const Step = std.Build.Step;
10const ArrayList = std.ArrayList;
11const assert = std.debug.assert;
12const Configuration = std.Build.Configuration;8const Configuration = std.Build.Configuration;
139
14step: Step,10step: Step,
15
16embeds: std.ArrayList(Embed) = .empty,11embeds: std.ArrayList(Embed) = .empty,
17copies: std.ArrayList(Copy) = .empty,12copies: std.ArrayList(Copy) = .empty,
18directories: std.ArrayList(Directory) = .empty,13directories: std.ArrayList(Directory) = .empty,