authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-09 19:30:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:35-07:00
logbd4c1e34d28bb7ab88ada31bb0fa01fda6e4b201
tree731779e26d459eb1c81ccd9672cb78457ef54b1a
parenta249201aecdb0a342ba871ce7adc86926297dcee

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.

5 files changed, 55 insertions(+), 9 deletions(-)

BRANCH_TODO+23
...@@ -77,3 +77,26 @@ closes #31397...@@ -77,3 +77,26 @@ closes #31397
7777
78* `b.build_root` (Directory) -> `b.root` (Path)78* `b.build_root` (Directory) -> `b.root` (Path)
79* `ConfigHeader.Options`: `include_guard_override` -> `include_guard`79* `ConfigHeader.Options`: `include_guard_override` -> `include_guard`
80
81### Perf Data Point: `zig build -h` (cached)
82
83```
84Benchmark 1 (34 runs): master/zig build -h
85 measurement mean ± σ min … max outliers delta
86 wall_time 150ms ± 5.52ms 145ms … 165ms 4 (12%) 0%
87 peak_rss 84.8MB ± 275KB 84.2MB … 85.1MB 0 ( 0%) 0%
88 cpu_cycles 593M ± 4.01M 588M … 608M 2 ( 6%) 0%
89 instructions 995M ± 52.5K 995M … 995M 0 ( 0%) 0%
90 cache_references 25.8M ± 165K 25.4M … 26.1M 0 ( 0%) 0%
91 cache_misses 651K ± 20.1K 619K … 697K 0 ( 0%) 0%
92 branch_misses 918K ± 7.44K 906K … 935K 0 ( 0%) 0%
93Benchmark 2 (348 runs): branch/zig build -h
94 measurement mean ± σ min … max outliers delta
95 wall_time 14.3ms ± 744us 13.2ms … 23.3ms 8 ( 2%) ⚡- 90.4% ± 0.4%
96 peak_rss 78.5MB ± 562KB 77.1MB … 81.4MB 7 ( 2%) ⚡- 7.4% ± 0.2%
97 cpu_cycles 24.1M ± 821K 22.8M … 27.1M 3 ( 1%) ⚡- 95.9% ± 0.1%
98 instructions 43.7M ± 23.8K 43.7M … 43.8M 56 (16%) ⚡- 95.6% ± 0.0%
99 cache_references 1.46M ± 14.6K 1.40M … 1.50M 19 ( 5%) ⚡- 94.3% ± 0.1%
100 cache_misses 142K ± 4.87K 127K … 157K 2 ( 1%) ⚡- 78.1% ± 0.4%
101 branch_misses 126K ± 1.37K 120K … 129K 12 ( 3%) ⚡- 86.3% ± 0.1%
102```
lib/compiler/Maker.zig+3
...@@ -446,6 +446,9 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -446,6 +446,9 @@ pub fn main(init: process.Init.Minimal) !void {
446 else => {},446 else => {},
447 }447 }
448 }448 }
449 for (c.search_prefixes) |search_prefix| {
450 try graph.search_prefixes.append(arena, search_prefix.slice(c));
451 }
449 break :sc .{452 break :sc .{
450 .configuration = configuration,453 .configuration = configuration,
451 .top_level_steps = top_level_steps,454 .top_level_steps = top_level_steps,
lib/compiler/Maker/ScannedConfig.zig+6
...@@ -20,6 +20,12 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {...@@ -20,6 +20,12 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {
20 var serializer: Serializer = .{ .writer = w };20 var serializer: Serializer = .{ .writer = w };
21 var s = try serializer.beginStruct(.{});21 var s = try serializer.beginStruct(.{});
2222
23 {
24 var tf = try s.beginTupleField("search_prefixes", .{});
25 for (c.search_prefixes) |string| try tf.field(string.slice(c), .{});
26 try tf.end();
27 }
28
23 try s.field("default_step", @intFromEnum(c.default_step), .{});29 try s.field("default_step", @intFromEnum(c.default_step), .{});
24 {30 {
25 var sf = try s.beginStructField("top_level_steps", .{});31 var sf = try s.beginStructField("top_level_steps", .{});
lib/std/Build.zig+15-9
...@@ -295,12 +295,12 @@ fn createChild(...@@ -295,12 +295,12 @@ fn createChild(
295 pkg_deps: AvailableDeps,295 pkg_deps: AvailableDeps,
296 user_input_options: UserInputOptionsMap,296 user_input_options: UserInputOptionsMap,
297) error{OutOfMemory}!*Build {297) error{OutOfMemory}!*Build {
298 const allocator = parent.allocator;298 const arena = parent.graph.arena;
299 const child = try allocator.create(Build);299 const child = try arena.create(Build);
300 child.* = .{300 child.* = .{
301 .graph = parent.graph,301 .graph = parent.graph,
302 .root = root,302 .root = root,
303 .allocator = allocator,303 .allocator = arena,
304 .install_tls = .{304 .install_tls = .{
305 .step = .init(.{305 .step = .init(.{
306 .tag = .top_level,306 .tag = .top_level,
...@@ -334,8 +334,8 @@ fn createChild(...@@ -334,8 +334,8 @@ fn createChild(
334 .pkg_hash = pkg_hash,334 .pkg_hash = pkg_hash,
335 .available_deps = pkg_deps,335 .available_deps = pkg_deps,
336 };336 };
337 try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls);337 try child.top_level_steps.put(arena, child.install_tls.step.name, &child.install_tls);
338 try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls);338 try child.top_level_steps.put(arena, child.uninstall_tls.step.name, &child.uninstall_tls);
339 child.default_step = &child.install_tls.step;339 child.default_step = &child.install_tls.step;
340 return child;340 return child;
341}341}
...@@ -1773,10 +1773,16 @@ pub fn run(b: *Build, argv: []const []const u8) []u8 {...@@ -1773,10 +1773,16 @@ pub fn run(b: *Build, argv: []const []const u8) []u8 {
1773/// it is desirable to use that same information without requiring the user to1773/// it is desirable to use that same information without requiring the user to
1774/// provide it again.1774/// provide it again.
1775pub fn addSearchPrefix(b: *Build, search_prefix: []const u8) void {1775pub fn addSearchPrefix(b: *Build, search_prefix: []const u8) void {
1776 _ = b;1776 if (b.isRoot()) {
1777 _ = search_prefix;1777 const graph = b.graph;
1778 @panic("TODO");1778 const wc = &graph.wip_configuration;
1779 //b.search_prefixes.append(b.allocator, b.dupePath(search_prefix)) catch @panic("OOM");1779 const string = wc.addString(search_prefix) catch @panic("OOM");
1780 wc.search_prefixes.append(wc.gpa, string) catch @panic("OOM");
1781 }
1782}
1783
1784pub fn isRoot(b: *const Build) bool {
1785 return b.pkg_hash.len == 0;
1780}1786}
17811787
1782pub const Dependency = struct {1788pub const Dependency = struct {
lib/std/Build/Configuration.zig+8
...@@ -13,6 +13,7 @@ path_deps_sub: []String,...@@ -13,6 +13,7 @@ path_deps_sub: []String,
13unlazy_deps: []String,13unlazy_deps: []String,
14system_integrations: []SystemIntegration,14system_integrations: []SystemIntegration,
15available_options: []AvailableOption,15available_options: []AvailableOption,
16search_prefixes: []String,
16extra: []u32,17extra: []u32,
17default_step: Step.Index,18default_step: Step.Index,
18generated_files_len: u32,19generated_files_len: u32,
...@@ -26,6 +27,7 @@ pub const Header = extern struct {...@@ -26,6 +27,7 @@ pub const Header = extern struct {
26 unlazy_deps_len: u32,27 unlazy_deps_len: u32,
27 system_integrations_len: u32,28 system_integrations_len: u32,
28 available_options_len: u32,29 available_options_len: u32,
30 search_prefixes_len: u32,
29 extra_len: u32,31 extra_len: u32,
3032
31 default_step: Step.Index,33 default_step: Step.Index,
...@@ -47,6 +49,7 @@ pub const Wip = struct {...@@ -47,6 +49,7 @@ pub const Wip = struct {
47 available_options: std.ArrayList(AvailableOption) = .empty,49 available_options: std.ArrayList(AvailableOption) = .empty,
48 steps: std.ArrayList(Step) = .empty,50 steps: std.ArrayList(Step) = .empty,
49 path_deps: std.MultiArrayList(Path) = .empty,51 path_deps: std.MultiArrayList(Path) = .empty,
52 search_prefixes: std.ArrayList(String) = .empty,
50 extra: std.ArrayList(u32) = .empty,53 extra: std.ArrayList(u32) = .empty,
51 next_generated_file_index: u32 = 0,54 next_generated_file_index: u32 = 0,
5255
...@@ -126,6 +129,7 @@ pub const Wip = struct {...@@ -126,6 +129,7 @@ pub const Wip = struct {
126 wip.available_options.deinit(gpa);129 wip.available_options.deinit(gpa);
127 wip.steps.deinit(gpa);130 wip.steps.deinit(gpa);
128 wip.path_deps.deinit(gpa);131 wip.path_deps.deinit(gpa);
132 wip.search_prefixes.deinit(gpa);
129 wip.extra.deinit(gpa);133 wip.extra.deinit(gpa);
130 wip.* = undefined;134 wip.* = undefined;
131 }135 }
...@@ -143,6 +147,7 @@ pub const Wip = struct {...@@ -143,6 +147,7 @@ pub const Wip = struct {
143 .unlazy_deps_len = @intCast(wip.unlazy_deps.items.len),147 .unlazy_deps_len = @intCast(wip.unlazy_deps.items.len),
144 .system_integrations_len = @intCast(wip.system_integrations.items.len),148 .system_integrations_len = @intCast(wip.system_integrations.items.len),
145 .available_options_len = @intCast(wip.available_options.items.len),149 .available_options_len = @intCast(wip.available_options.items.len),
150 .search_prefixes_len = @intCast(wip.search_prefixes.items.len),
146 .extra_len = @intCast(wip.extra.items.len),151 .extra_len = @intCast(wip.extra.items.len),
147152
148 .default_step = static.default_step,153 .default_step = static.default_step,
...@@ -157,6 +162,7 @@ pub const Wip = struct {...@@ -157,6 +162,7 @@ pub const Wip = struct {
157 @ptrCast(wip.unlazy_deps.items),162 @ptrCast(wip.unlazy_deps.items),
158 @ptrCast(wip.system_integrations.items),163 @ptrCast(wip.system_integrations.items),
159 @ptrCast(wip.available_options.items),164 @ptrCast(wip.available_options.items),
165 @ptrCast(wip.search_prefixes.items),
160 @ptrCast(wip.extra.items),166 @ptrCast(wip.extra.items),
161 };167 };
162 try w.writeVecAll(&buffers);168 try w.writeVecAll(&buffers);
...@@ -3017,6 +3023,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -3017,6 +3023,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
3017 .unlazy_deps = try arena.alloc(String, header.unlazy_deps_len),3023 .unlazy_deps = try arena.alloc(String, header.unlazy_deps_len),
3018 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),3024 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),
3019 .available_options = try arena.alloc(AvailableOption, header.available_options_len),3025 .available_options = try arena.alloc(AvailableOption, header.available_options_len),
3026 .search_prefixes = try arena.alloc(String, header.search_prefixes_len),
3020 .extra = try arena.alloc(u32, header.extra_len),3027 .extra = try arena.alloc(u32, header.extra_len),
3021 .default_step = header.default_step,3028 .default_step = header.default_step,
3022 .generated_files_len = header.generated_files_len,3029 .generated_files_len = header.generated_files_len,
...@@ -3029,6 +3036,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -3029,6 +3036,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
3029 @ptrCast(result.unlazy_deps),3036 @ptrCast(result.unlazy_deps),
3030 @ptrCast(result.system_integrations),3037 @ptrCast(result.system_integrations),
3031 @ptrCast(result.available_options),3038 @ptrCast(result.available_options),
3039 @ptrCast(result.search_prefixes),
3032 @ptrCast(result.extra),3040 @ptrCast(result.extra),
3033 };3041 };
3034 try reader.readVecAll(&vecs);3042 try reader.readVecAll(&vecs);