From bd4c1e34d28bb7ab88ada31bb0fa01fda6e4b201 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 9 May 2026 19:30:08 -0700 Subject: [PATCH] configurer: add search_prefixes back It is generally best practice to avoid calling this function, instead relying on the user to provide these paths via the standard build system interface. However, when integrating with other build systems, the user may have already provided the information to the other build system, and thus it is desirable to use that same information without requiring the user to provide it again. --- BRANCH_TODO | 23 +++++++++++++++++++++++ lib/compiler/Maker.zig | 3 +++ lib/compiler/Maker/ScannedConfig.zig | 6 ++++++ lib/std/Build.zig | 24 +++++++++++++++--------- lib/std/Build/Configuration.zig | 8 ++++++++ 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/BRANCH_TODO b/BRANCH_TODO index b54140d4a0fee66c9fc59a3dca66b906cf3f3d53..ffc063b7cc33675994c68b3ac6b7ea81889b2c80 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -77,3 +77,26 @@ closes #31397 * `b.build_root` (Directory) -> `b.root` (Path) * `ConfigHeader.Options`: `include_guard_override` -> `include_guard` + +### Perf Data Point: `zig build -h` (cached) + +``` +Benchmark 1 (34 runs): master/zig build -h + measurement mean ± σ min … max outliers delta + wall_time 150ms ± 5.52ms 145ms … 165ms 4 (12%) 0% + peak_rss 84.8MB ± 275KB 84.2MB … 85.1MB 0 ( 0%) 0% + cpu_cycles 593M ± 4.01M 588M … 608M 2 ( 6%) 0% + instructions 995M ± 52.5K 995M … 995M 0 ( 0%) 0% + cache_references 25.8M ± 165K 25.4M … 26.1M 0 ( 0%) 0% + cache_misses 651K ± 20.1K 619K … 697K 0 ( 0%) 0% + branch_misses 918K ± 7.44K 906K … 935K 0 ( 0%) 0% +Benchmark 2 (348 runs): branch/zig build -h + measurement mean ± σ min … max outliers delta + wall_time 14.3ms ± 744us 13.2ms … 23.3ms 8 ( 2%) ⚡- 90.4% ± 0.4% + peak_rss 78.5MB ± 562KB 77.1MB … 81.4MB 7 ( 2%) ⚡- 7.4% ± 0.2% + cpu_cycles 24.1M ± 821K 22.8M … 27.1M 3 ( 1%) ⚡- 95.9% ± 0.1% + instructions 43.7M ± 23.8K 43.7M … 43.8M 56 (16%) ⚡- 95.6% ± 0.0% + cache_references 1.46M ± 14.6K 1.40M … 1.50M 19 ( 5%) ⚡- 94.3% ± 0.1% + cache_misses 142K ± 4.87K 127K … 157K 2 ( 1%) ⚡- 78.1% ± 0.4% + branch_misses 126K ± 1.37K 120K … 129K 12 ( 3%) ⚡- 86.3% ± 0.1% +``` diff --git a/lib/compiler/Maker.zig b/lib/compiler/Maker.zig index 48a7cf785d8c76f84206762bace9dc7ff9eb76f5..d443a6ae4d52dff0da3c323648fdf88be500ffc7 100644 --- a/lib/compiler/Maker.zig +++ b/lib/compiler/Maker.zig @@ -446,6 +446,9 @@ pub fn main(init: process.Init.Minimal) !void { else => {}, } } + for (c.search_prefixes) |search_prefix| { + try graph.search_prefixes.append(arena, search_prefix.slice(c)); + } break :sc .{ .configuration = configuration, .top_level_steps = top_level_steps, diff --git a/lib/compiler/Maker/ScannedConfig.zig b/lib/compiler/Maker/ScannedConfig.zig index 7fc7cc9608fa268248b063d66f01f6ce4b9251ca..5bb3a9871f53a1c50bb994cd73483315673f23c5 100644 --- a/lib/compiler/Maker/ScannedConfig.zig +++ b/lib/compiler/Maker/ScannedConfig.zig @@ -20,6 +20,12 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { var serializer: Serializer = .{ .writer = w }; var s = try serializer.beginStruct(.{}); + { + var tf = try s.beginTupleField("search_prefixes", .{}); + for (c.search_prefixes) |string| try tf.field(string.slice(c), .{}); + try tf.end(); + } + try s.field("default_step", @intFromEnum(c.default_step), .{}); { var sf = try s.beginStructField("top_level_steps", .{}); diff --git a/lib/std/Build.zig b/lib/std/Build.zig index b5eeefa17189756fcb34d113a22f1646887f3f56..ad87bc246627a68fb3e769d9a8649d2dd3936edc 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -295,12 +295,12 @@ fn createChild( pkg_deps: AvailableDeps, user_input_options: UserInputOptionsMap, ) error{OutOfMemory}!*Build { - const allocator = parent.allocator; - const child = try allocator.create(Build); + const arena = parent.graph.arena; + const child = try arena.create(Build); child.* = .{ .graph = parent.graph, .root = root, - .allocator = allocator, + .allocator = arena, .install_tls = .{ .step = .init(.{ .tag = .top_level, @@ -334,8 +334,8 @@ fn createChild( .pkg_hash = pkg_hash, .available_deps = pkg_deps, }; - try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls); - try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls); + try child.top_level_steps.put(arena, child.install_tls.step.name, &child.install_tls); + try child.top_level_steps.put(arena, child.uninstall_tls.step.name, &child.uninstall_tls); child.default_step = &child.install_tls.step; return child; } @@ -1773,10 +1773,16 @@ pub fn run(b: *Build, argv: []const []const u8) []u8 { /// it is desirable to use that same information without requiring the user to /// provide it again. pub fn addSearchPrefix(b: *Build, search_prefix: []const u8) void { - _ = b; - _ = search_prefix; - @panic("TODO"); - //b.search_prefixes.append(b.allocator, b.dupePath(search_prefix)) catch @panic("OOM"); + if (b.isRoot()) { + const graph = b.graph; + const wc = &graph.wip_configuration; + const string = wc.addString(search_prefix) catch @panic("OOM"); + wc.search_prefixes.append(wc.gpa, string) catch @panic("OOM"); + } +} + +pub fn isRoot(b: *const Build) bool { + return b.pkg_hash.len == 0; } pub const Dependency = struct { diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index b08fb39543fca86db2db39a5809fb5eb1b7d2566..c008dcc90f31e445ea8b4701edf7ac0507e8e460 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -13,6 +13,7 @@ path_deps_sub: []String, unlazy_deps: []String, system_integrations: []SystemIntegration, available_options: []AvailableOption, +search_prefixes: []String, extra: []u32, default_step: Step.Index, generated_files_len: u32, @@ -26,6 +27,7 @@ pub const Header = extern struct { unlazy_deps_len: u32, system_integrations_len: u32, available_options_len: u32, + search_prefixes_len: u32, extra_len: u32, default_step: Step.Index, @@ -47,6 +49,7 @@ pub const Wip = struct { available_options: std.ArrayList(AvailableOption) = .empty, steps: std.ArrayList(Step) = .empty, path_deps: std.MultiArrayList(Path) = .empty, + search_prefixes: std.ArrayList(String) = .empty, extra: std.ArrayList(u32) = .empty, next_generated_file_index: u32 = 0, @@ -126,6 +129,7 @@ pub const Wip = struct { wip.available_options.deinit(gpa); wip.steps.deinit(gpa); wip.path_deps.deinit(gpa); + wip.search_prefixes.deinit(gpa); wip.extra.deinit(gpa); wip.* = undefined; } @@ -143,6 +147,7 @@ pub const Wip = struct { .unlazy_deps_len = @intCast(wip.unlazy_deps.items.len), .system_integrations_len = @intCast(wip.system_integrations.items.len), .available_options_len = @intCast(wip.available_options.items.len), + .search_prefixes_len = @intCast(wip.search_prefixes.items.len), .extra_len = @intCast(wip.extra.items.len), .default_step = static.default_step, @@ -157,6 +162,7 @@ pub const Wip = struct { @ptrCast(wip.unlazy_deps.items), @ptrCast(wip.system_integrations.items), @ptrCast(wip.available_options.items), + @ptrCast(wip.search_prefixes.items), @ptrCast(wip.extra.items), }; try w.writeVecAll(&buffers); @@ -3017,6 +3023,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { .unlazy_deps = try arena.alloc(String, header.unlazy_deps_len), .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len), .available_options = try arena.alloc(AvailableOption, header.available_options_len), + .search_prefixes = try arena.alloc(String, header.search_prefixes_len), .extra = try arena.alloc(u32, header.extra_len), .default_step = header.default_step, .generated_files_len = header.generated_files_len, @@ -3029,6 +3036,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { @ptrCast(result.unlazy_deps), @ptrCast(result.system_integrations), @ptrCast(result.available_options), + @ptrCast(result.search_prefixes), @ptrCast(result.extra), }; try reader.readVecAll(&vecs); -- 2.54.0