From d7eab060db6aff326a957e4dbffcd09263f7ffbd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 8 May 2026 13:18:16 -0700 Subject: [PATCH] configurer: serialize Step.UpdateSourceFiles --- lib/compiler/Maker/Step/UpdateSourceFiles.zig | 8 +-- lib/compiler/configurer.zig | 31 +++++--- lib/std/Build/Configuration.zig | 13 +--- lib/std/Build/Step/UpdateSourceFiles.zig | 71 +++++++++---------- lib/std/Build/Step/WriteFile.zig | 5 -- 5 files changed, 63 insertions(+), 65 deletions(-) diff --git a/lib/compiler/Maker/Step/UpdateSourceFiles.zig b/lib/compiler/Maker/Step/UpdateSourceFiles.zig index 779155cbab..744fd35341 100644 --- a/lib/compiler/Maker/Step/UpdateSourceFiles.zig +++ b/lib/compiler/Maker/Step/UpdateSourceFiles.zig @@ -35,7 +35,7 @@ pub fn make( for (conf_usf.embeds.slice) |*embed| { const dest_path: Path = .{ .root_dir = build_root, - .sub_path = embed.dest_path.slice(conf), + .sub_path = embed.sub_path.slice(conf), }; if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| { const dirname_path: Path = .{ @@ -47,7 +47,7 @@ pub fn make( } dest_path.root_dir.handle.writeFile(io, .{ .sub_path = dest_path.sub_path, - .data = embed.bytes.slice(conf), + .data = embed.contents.slice(conf), }) catch |err| return step.fail(maker, "failed to write file {f}: {t}", .{ dest_path, err }); any_miss = true; progress_node.completeOne(); @@ -56,7 +56,7 @@ pub fn make( for (conf_usf.copies.slice) |*copy| { const dest_path: Path = .{ .root_dir = build_root, - .sub_path = copy.dest_path.slice(conf), + .sub_path = copy.sub_path.slice(conf), }; if (Io.Dir.path.dirname(dest_path.sub_path)) |dirname| { const dirname_path: Path = .{ @@ -66,7 +66,7 @@ pub fn make( dirname_path.root_dir.handle.createDirPath(io, dirname_path.sub_path) catch |err| return step.fail(maker, "failed to create path {f}: {t}", .{ dirname_path, err }); } - const src_lazy_path = copy.src_path.get(conf); + const src_lazy_path = copy.src_file.get(conf); const source_path = try maker.resolveLazyPath(arena, src_lazy_path, step_index); if (!step.inputs.populated()) try step.addWatchInput(maker, arena, src_lazy_path); diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig index 37f813e2cd..10d1875d0d 100644 --- a/lib/compiler/configurer.zig +++ b/lib/compiler/configurer.zig @@ -464,6 +464,15 @@ const Serialize = struct { return result; } + fn initCopyList(s: *Serialize, list: []const Step.WriteFile.Copy) ![]const Configuration.Step.WriteFile.Copy { + const result = try s.arena.alloc(Configuration.Step.WriteFile.Copy, list.len); + for (result, list) |*dest, src| dest.* = .{ + .sub_path = src.sub_path, + .src_file = try s.addLazyPath(src.src_file), + }; + return result; + } + fn initOptionalStringList(s: *Serialize, list: []const ?[]const u8) ![]const Configuration.OptionalString { const wc = s.wc; 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 { .write_file => e: { const wf: *Step.WriteFile = @fieldParentPtr("step", step); - const copies = try arena.alloc(Configuration.Step.WriteFile.Copy, wf.copies.items.len); - for (copies, wf.copies.items) |*dest, src| dest.* = .{ - .sub_path = src.sub_path, - .src_file = try s.addLazyPath(src.src_file), - }; - const directories = try arena.alloc( Configuration.Step.WriteFile.Directory, wf.directories.items.len, @@ -925,7 +928,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.WriteFile, .{ .flags = .{ .embeds = wf.embeds.items.len != 0, - .copies = copies.len != 0, + .copies = wf.copies.items.len != 0, .directories = directories.len != 0, .mode = switch (wf.mode) { .whole_cached => .whole_cached, @@ -935,7 +938,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { }, .generated_directory = wf.generated_directory, .embeds = .{ .slice = wf.embeds.items }, - .copies = .{ .slice = copies }, + .copies = .{ .slice = try s.initCopyList(wf.copies.items) }, .directories = .{ .slice = directories }, .mutate_path = .{ .value = switch (wf.mode) { .mutate => |lp| try s.addLazyPath(lp), @@ -943,7 +946,17 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { } }, }))); }, - .update_source_files => @panic("TODO"), + .update_source_files => e: { + const usf: *Step.UpdateSourceFiles = @fieldParentPtr("step", step); + break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.UpdateSourceFiles, .{ + .flags = .{ + .embeds = usf.embeds.items.len != 0, + .copies = usf.copies.items.len != 0, + }, + .embeds = .{ .slice = usf.embeds.items }, + .copies = .{ .slice = try s.initCopyList(usf.copies.items) }, + }))); + }, .run => e: { const run: *Step.Run = @fieldParentPtr("step", step); var expect_stderr_exact: ?Configuration.Bytes = null; diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index 266a36bf43..b3d81c9ac9 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -1229,17 +1229,8 @@ pub const Step = extern struct { embeds: Storage.FlagLengthPrefixedList(.flags, .embeds, Embed), copies: Storage.FlagLengthPrefixedList(.flags, .copies, Copy), - pub const Embed = extern struct { - /// Relative to build root. - dest_path: String, - bytes: Bytes, - }; - - pub const Copy = extern struct { - /// Relative to build root. - dest_path: String, - src_path: LazyPath.Index, - }; + pub const Embed = WriteFile.Embed; + pub const Copy = WriteFile.Copy; pub const Flags = packed struct(u32) { tag: Tag = .update_source_files, diff --git a/lib/std/Build/Step/UpdateSourceFiles.zig b/lib/std/Build/Step/UpdateSourceFiles.zig index 7615b5829b..cc5b114b8c 100644 --- a/lib/std/Build/Step/UpdateSourceFiles.zig +++ b/lib/std/Build/Step/UpdateSourceFiles.zig @@ -6,64 +6,63 @@ const UpdateSourceFiles = @This(); const std = @import("std"); -const Io = std.Io; const Step = std.Build.Step; -const fs = std.fs; -const ArrayList = std.ArrayList; +const Configuration = std.Build.Configuration; step: Step, -output_source_files: std.ArrayList(OutputSourceFile), +embeds: std.ArrayList(Embed) = .empty, +copies: std.ArrayList(Copy) = .empty, pub const base_tag: Step.Tag = .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 const Embed = Step.WriteFile.Embed; +pub const Copy = Step.WriteFile.Copy; pub fn create(owner: *std.Build) *UpdateSourceFiles { - const usf = owner.allocator.create(UpdateSourceFiles) catch @panic("OOM"); + const graph = owner.graph; + const usf = graph.create(UpdateSourceFiles); usf.* = .{ .step = .init(.{ .tag = base_tag, .name = "UpdateSourceFiles", .owner = owner, }), - .output_source_files = .empty, }; return usf; } -/// A path relative to the package root. +/// Overwrites a path relative to the build root with the contents of another file. /// -/// 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, +/// 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, src_file: std.Build.LazyPath, sub_path: []const u8) void { + const graph = usf.step.owner.graph; + const wc = &graph.wip_configuration; + const arena = graph.arena; + + usf.copies.append(arena, .{ + .sub_path = wc.addString(sub_path) catch @panic("OOM"), + .src_file = src_file.dupe(graph), }) catch @panic("OOM"); - source.addStepDependencies(&usf.step); + + src_file.addStepDependencies(&usf.step); } -/// A path relative to the package root. +/// Overwrites a path relative to the package root with the provided bytes. /// -/// 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, +/// 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, contents: []const u8, sub_path: []const u8) void { + const graph = usf.step.owner.graph; + const wc = &graph.wip_configuration; + const arena = graph.arena; + + usf.embeds.append(arena, .{ + .sub_path = wc.addString(sub_path) catch @panic("OOM"), + .contents = wc.addBytes(contents) catch @panic("OOM"), }) catch @panic("OOM"); } diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 64a7a05666..a6b5f942d8 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -4,15 +4,10 @@ const WriteFile = @This(); const std = @import("std"); -const Io = std.Io; -const Dir = std.Io.Dir; const Step = std.Build.Step; -const ArrayList = std.ArrayList; -const assert = std.debug.assert; const Configuration = std.Build.Configuration; step: Step, - embeds: std.ArrayList(Embed) = .empty, copies: std.ArrayList(Copy) = .empty, directories: std.ArrayList(Directory) = .empty,