diff --git a/lib/compiler/Maker/Step/Options.zig b/lib/compiler/Maker/Step/Options.zig index 9639dffa5bc9b6976bd19bbafff09c803f2fadf0..26ac62db41b7390e30e454738ce8a326abf06bf4 100644 --- a/lib/compiler/Maker/Step/Options.zig +++ b/lib/compiler/Maker/Step/Options.zig @@ -30,7 +30,7 @@ pub fn make( // generated zig file are observable by dependant steps. // Pathnames added to Options.args are assumed to be generated files whose // contents are also observable, while pathnames added to - // Options.args_untracked are treated as pure path string data with no + // Options.untracked_paths are treated as pure path string data with no // tracking of the path's state or contents. step.clearWatchInputs(maker); @@ -40,7 +40,7 @@ pub fn make( var args_bytes: std.ArrayList(u8) = .empty; - for (conf_options.args.slice) |arg| { + for (conf_options.files.slice) |arg| { const name = arg.name.slice(conf); const lazy_path = arg.path.get(conf); try step.addWatchInput(maker, arena, lazy_path); @@ -51,7 +51,20 @@ pub fn make( }); } - for (conf_options.args_untracked.slice) |arg| { + for (conf_options.directories.slice) |arg| { + const name = arg.name.slice(conf); + const lazy_path = arg.path.get(conf); + _ = try step.addDirectoryWatchInput(maker, lazy_path); + const arg_path = try maker.resolveLazyPath(arena, lazy_path, step_index); + _ = try man.addInputPath(arg_path, .{ + .handle = .{ .dir = null }, + }); + try args_bytes.print(arena, "pub const {f}: []const u8 = \"{f}\";\n", .{ + std.zig.fmtId(name), arg_path.fmtEscapeString(), + }); + } + + for (conf_options.untracked_paths.slice) |arg| { const name = arg.name.slice(conf); const lazy_path = arg.path.get(conf); const arg_path = try maker.resolveLazyPath(arena, lazy_path, step_index); diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index 9fb44c80d89336542fe91fdc7d58f9696a18b40f..a902374974e43dba5cac3bf2653b067d1f1c2956 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -1378,19 +1378,21 @@ pub const Step = extern struct { flags: @This().Flags, generated_file: GeneratedFileIndex, contents: Bytes, - args: Storage.FlagLengthPrefixedList(.flags, .args, Arg), - args_untracked: Storage.FlagLengthPrefixedList(.flags, .args_untracked, Arg), + files: Storage.FlagLengthPrefixedList(.flags, .files, NamedPath), + directories: Storage.FlagLengthPrefixedList(.flags, .directories, NamedPath), + untracked_paths: Storage.FlagLengthPrefixedList(.flags, .untracked_paths, NamedPath), - pub const Arg = extern struct { + pub const NamedPath = extern struct { name: String, path: LazyPath.Index, }; pub const Flags = packed struct(u32) { tag: Tag = .options, - args: bool, - args_untracked: bool, - _: u25 = 0, + files: bool, + directories: bool, + untracked_paths: bool, + _: u24 = 0, }; }; diff --git a/lib/std/Build/Serialize.zig b/lib/std/Build/Serialize.zig index b61cc49fd55885a4ca1d450eafcf0c3eae916be0..053cf86924dafc3c5e929b487f408d0b9c5482df 100644 --- a/lib/std/Build/Serialize.zig +++ b/lib/std/Build/Serialize.zig @@ -648,27 +648,35 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi .options => e: { const so: *Step.Options = @fieldParentPtr("step", step); - const args = try arena.alloc(Configuration.Step.Options.Arg, so.args.items.len); - for (args, so.args.items) |*dest, src| dest.* = .{ + const files = try arena.alloc(Configuration.Step.Options.NamedPath, so.files.items.len); + for (files, so.files.items) |*dest, src| dest.* = .{ .name = src.name, .path = try s.addLazyPath(src.path), }; - const args_untracked = try arena.alloc(Configuration.Step.Options.Arg, so.args_untracked.items.len); - for (args_untracked, so.args_untracked.items) |*dest, src| dest.* = .{ + const directories = try arena.alloc(Configuration.Step.Options.NamedPath, so.directories.items.len); + for (directories, so.directories.items) |*dest, src| dest.* = .{ + .name = src.name, + .path = try s.addLazyPath(src.path), + }; + + const untracked_paths = try arena.alloc(Configuration.Step.Options.NamedPath, so.untracked_paths.items.len); + for (untracked_paths, so.untracked_paths.items) |*dest, src| dest.* = .{ .name = src.name, .path = try s.addLazyPath(src.path), }; break :e try wc.addExtraErased(Configuration.Step.Options, .{ .flags = .{ - .args = so.args.items.len != 0, - .args_untracked = so.args_untracked.items.len != 0, + .files = so.files.items.len != 0, + .directories = so.directories.items.len != 0, + .untracked_paths = so.untracked_paths.items.len != 0, }, .generated_file = so.generated_file, .contents = try wc.addBytes(so.contents.items), - .args = .{ .slice = args }, - .args_untracked = .{ .slice = args_untracked }, + .files = .{ .slice = files }, + .directories = .{ .slice = directories }, + .untracked_paths = .{ .slice = untracked_paths }, }); }, })), diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 5f5b2a41cfd19e97667525014678315dc9bbcbf1..1d49670df9196608abf0b416525a3c394e1d7aa7 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -12,13 +12,14 @@ const Configuration = std.Build.Configuration; step: Step, generated_file: Configuration.GeneratedFileIndex, contents: std.ArrayList(u8) = .empty, -args: std.ArrayList(Arg) = .empty, -args_untracked: std.ArrayList(Arg) = .empty, +files: std.ArrayList(NamedPath) = .empty, +directories: std.ArrayList(NamedPath) = .empty, +untracked_paths: std.ArrayList(NamedPath) = .empty, encountered_types: std.StringHashMapUnmanaged(void), pub const base_tag: Step.Tag = .options; -pub const Arg = struct { +pub const NamedPath = struct { name: Configuration.String, path: LazyPath, }; @@ -421,18 +422,36 @@ fn printStructValue( } } -/// The added option has type `[]const u8` and value of the provided path. -/// This interface assumes the provided path is a generated file, and causes a -/// transitive dependency through Options on the file's contents. +/// The added option has type `[]const u8` and value of the provided file path. If the provided path is a +/// generated file, causes a transitive dependency on the file's contents. /// /// See also: +/// * `addOptionPathDirectory` /// * `addOptionPathUntracked` pub fn addOptionPath(options: *Options, name: []const u8, path: LazyPath) void { const graph = options.step.owner.graph; const arena = graph.arena; const wc = &graph.wip_configuration; - options.args.append(arena, .{ + options.files.append(arena, .{ + .name = wc.addString(name) catch @panic("OOM"), + .path = path.dupe(options.step.owner.graph), + }) catch @panic("OOM"); + path.addStepDependencies(&options.step); +} + +/// The added option has type `[]const u8` and value of the provided directory path. Causes a transitive +/// dependency through Options on the directory's contents. +/// +/// See also: +/// * `addOptionPath` +/// * `addOptionPathUntracked` +pub fn addOptionPathDirectory(options: *Options, name: []const u8, path: LazyPath) void { + const graph = options.step.owner.graph; + const arena = graph.arena; + const wc = &graph.wip_configuration; + + options.directories.append(arena, .{ .name = wc.addString(name) catch @panic("OOM"), .path = path.dupe(options.step.owner.graph), }) catch @panic("OOM"); @@ -450,7 +469,7 @@ pub fn addOptionPathUntracked(options: *Options, name: []const u8, path: LazyPat const arena = graph.arena; const wc = &graph.wip_configuration; - options.args_untracked.append(arena, .{ + options.untracked_paths.append(arena, .{ .name = wc.addString(name) catch @panic("OOM"), .path = path.dupe(options.step.owner.graph), }) catch @panic("OOM");