authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 14:50:56-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:37-07:00
log19c63406d4acded72966a66ac369ccceb69173a2
treebaeaf86a646caef1c123a8abb84180e016956ac1
parent860d5ab9c41fd64c5150bd7d9f5b87cbcda9f281

LazyPath: store relative paths as actual strings


6 files changed, 46 insertions(+), 53 deletions(-)

lib/compiler/configurer.zig+1-1
......@@ -208,7 +208,7 @@ const Serialize = struct {
208208 .relative => |relative| i: {
209209 break :i try wc.addExtraErased(Configuration.LazyPath.Relative, .{
210210 .flags = .{ .base = relative.base },
211 .sub_path = relative.sub_path,
211 .sub_path = try wc.addString(relative.sub_path),
212212 });
213213 },
214214 .dependency => |dependency| i: {
lib/std/Build.zig+40-47
......@@ -166,10 +166,9 @@ pub const Graph = struct {
166166 /// A path whose components and contents are known at some point during
167167 /// `Step` resolution, relative to the provided base directory.
168168 pub fn path(graph: *Graph, base: Configuration.Path.Base, sub_path: []const u8) LazyPath {
169 const wc = &graph.wip_configuration;
170169 return .{ .relative = .{
171170 .base = base,
172 .sub_path = wc.addString(sub_path) catch @panic("OOM"),
171 .sub_path = @This().dupePath(graph, sub_path),
173172 } };
174173 }
175174
......@@ -974,12 +973,12 @@ pub fn dupe(b: *Build, bytes: []const u8) []const u8 {
974973 return b.graph.dupeString(bytes);
975974}
976975
977/// Duplicates an array of strings without the need to handle out of memory.
976/// Deprecated, call `Graph.dupeStrings` instead.
978977pub fn dupeStrings(b: *Build, strings: []const []const u8) []const []const u8 {
979978 return b.graph.dupeStrings(strings);
980979}
981980
982/// Duplicates a path, canonicalizing path separators.
981/// Deprecated, call `Graph.dupePath` instead.
983982pub fn dupePath(b: *Build, bytes: []const u8) []const u8 {
984983 return b.graph.dupePath(bytes);
985984}
......@@ -1536,7 +1535,7 @@ pub fn addUserInputFlag(b: *Build, name_raw: []const u8) error{OutOfMemory}!bool
15361535 return true;
15371536 },
15381537 .lazy_path => |lp| {
1539 log.err("Flag '-D{s}' conflicts with option '-D{s}={f}'.", .{ name, name, lp.fmt(graph) });
1538 log.err("Flag '-D{s}' conflicts with option '-D{s}={f}'.", .{ name, name, lp });
15401539 return true;
15411540 },
15421541
......@@ -2381,10 +2380,10 @@ pub const LazyPath = union(enum) {
23812380
23822381 relative: struct {
23832382 base: Configuration.Path.Base,
2384 sub_path: Configuration.String = .empty,
2383 sub_path: []const u8 = "",
23852384
23862385 pub fn eql(a: @This(), b: @This()) bool {
2387 return a.base == b.base and a.sub_path == b.sub_path;
2386 return a.base == b.base and mem.eql(u8, a.sub_path, b.sub_path);
23882387 }
23892388 },
23902389
......@@ -2398,11 +2397,11 @@ pub const LazyPath = union(enum) {
23982397
23992398 /// Returns a lazy path referring to the directory containing this path.
24002399 ///
2401 /// The dirname is not allowed to escape the logical root for underlying path.
2402 /// For example, if the path is relative to the build root,
2403 /// the dirname is not allowed to traverse outside of the build root.
2404 /// Similarly, if the path is a generated file inside zig-cache,
2405 /// the dirname is not allowed to traverse outside of zig-cache.
2400 /// The dirname is not allowed to escape the logical root for underlying
2401 /// path. For example, if the path is relative to the build root, the
2402 /// dirname is not allowed to traverse outside of the build root.
2403 /// Similarly, if the path is a generated file inside zig-cache, the
2404 /// dirname is not allowed to traverse outside of zig-cache.
24062405 pub fn dirname(lazy_path: LazyPath) LazyPath {
24072406 return switch (lazy_path) {
24082407 .src_path => |sp| .{ .src_path = .{
......@@ -2444,9 +2443,13 @@ pub const LazyPath = union(enum) {
24442443 }
24452444 },
24462445 },
2447 .relative => .{
2448 .relative = @panic("TODO"),
2449 },
2446 .relative => |r| .{ .relative = .{
2447 .base = r.base,
2448 .sub_path = dirnameAllowEmpty(r.sub_path) orelse {
2449 dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the base path\n", .{}) catch {};
2450 @panic("misconfigured build script");
2451 },
2452 } },
24502453 .dependency => |dep| .{ .dependency = .{
24512454 .dependency = dep.dependency,
24522455 .sub_path = dirnameAllowEmpty(dep.sub_path) orelse {
......@@ -2480,9 +2483,10 @@ pub const LazyPath = union(enum) {
24802483 .cwd_relative => |cwd_relative| .{
24812484 .cwd_relative = try fs.path.resolve(arena, &.{ cwd_relative, sub_path }),
24822485 },
2483 .relative => .{
2484 .relative = @panic("TODO"),
2485 },
2486 .relative => |r| .{ .relative = .{
2487 .base = r.base,
2488 .sub_path = try fs.path.resolve(arena, &.{ r.sub_path, sub_path }),
2489 } },
24862490 .dependency => |dep| .{ .dependency = .{
24872491 .dependency = dep.dependency,
24882492 .sub_path = try fs.path.resolve(arena, &.{ dep.sub_path, sub_path }),
......@@ -2490,27 +2494,25 @@ pub const LazyPath = union(enum) {
24902494 };
24912495 }
24922496
2493 pub const Format = struct {
2494 graph: *const Graph,
2495 lazy_path: *const LazyPath,
2496
2497 pub fn format(f: Format, w: *Io.Writer) Io.Writer.Error!void {
2498 switch (f.lazy_path.*) {
2499 .src_path => |sp| try w.writeAll(sp.sub_path),
2500 .cwd_relative => |p| try w.writeAll(p),
2501 .generated => try w.writeAll("generated"),
2502 .dependency => try w.writeAll("dependency"),
2503 .relative => |r| {
2504 const wc = &f.graph.wip_configuration;
2505 try w.writeAll(@tagName(r.base));
2506 try w.writeAll(wc.stringSlice(r.sub_path));
2507 },
2508 }
2509 }
2510 };
2497 /// Deprecated, use `format` instead.
2498 pub fn getDisplayName(lazy_path: LazyPath) []const u8 {
2499 return switch (lazy_path) {
2500 .src_path => |sp| sp.sub_path,
2501 .cwd_relative => |p| p,
2502 .generated => "generated",
2503 .dependency => "dependency",
2504 .relative => |r| @tagName(r.base),
2505 };
2506 }
25112507
2512 pub fn fmt(lp: *const LazyPath, graph: *const Graph) Format {
2513 return .{ .graph = graph, .lazy_path = lp };
2508 pub fn format(lp: LazyPath, w: *Io.Writer) Io.Writer.Error!void {
2509 switch (lp) {
2510 .src_path => |sp| try w.writeAll(sp.sub_path),
2511 .cwd_relative => |p| try w.writeAll(p),
2512 .generated => try w.writeAll("generated"),
2513 .dependency => try w.writeAll("dependency"),
2514 .relative => |r| try w.print("{t} {s}", .{ r.base, r.sub_path }),
2515 }
25142516 }
25152517
25162518 /// Adds dependencies this file source implies to the given step.
......@@ -2525,15 +2527,6 @@ pub const LazyPath = union(enum) {
25252527 }
25262528 }
25272529
2528 pub fn basename(lazy_path: LazyPath) []const u8 {
2529 return fs.path.basename(switch (lazy_path) {
2530 .src_path => |sp| sp.sub_path,
2531 .cwd_relative => |sub_path| sub_path,
2532 .generated => |gen| gen.sub_path,
2533 .dependency => |dep| dep.sub_path,
2534 });
2535 }
2536
25372530 /// Copies the internal strings.
25382531 ///
25392532 /// The `graph` parameter is only used for the global arena allocator.
lib/std/Build/Step/ConfigHeader.zig+2-2
......@@ -73,7 +73,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
7373 .src_path => |sp| sp.sub_path,
7474 .generated => break :default,
7575 .cwd_relative => |sub_path| sub_path,
76 .relative => |r| wc.stringSlice(r.sub_path),
76 .relative => |r| r.sub_path,
7777 .dependency => |dependency| dependency.sub_path,
7878 };
7979 const basename = Io.Dir.path.basename(sub_path);
......@@ -85,7 +85,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
8585
8686 const name = if (options.style.getPath()) |s|
8787 allocPrint(arena, "configure {t} header {f} to {s}", .{
88 options.style, s.fmt(graph), include_path,
88 options.style, s, include_path,
8989 }) catch @panic("OOM")
9090 else
9191 allocPrint(arena, "configure {t} header to {s}", .{
lib/std/Build/Step/InstallDir.zig+1-1
......@@ -47,7 +47,7 @@ pub fn create(owner: *std.Build, options: Options) *InstallDir {
4747 install_dir.* = .{
4848 .step = Step.init(.{
4949 .tag = base_tag,
50 .name = owner.fmt("install {f}/", .{options.source_dir.fmt(graph)}),
50 .name = owner.fmt("install {f}/", .{options.source_dir}),
5151 .owner = owner,
5252 }),
5353 .options = options.dupe(graph),
lib/std/Build/Step/InstallFile.zig+1-1
......@@ -26,7 +26,7 @@ pub fn create(
2626 install_file.* = .{
2727 .step = Step.init(.{
2828 .tag = base_tag,
29 .name = owner.fmt("install {f} to {s}", .{ source.fmt(graph), dest_rel_path }),
29 .name = owner.fmt("install {f} to {s}", .{ source, dest_rel_path }),
3030 .owner = owner,
3131 }),
3232 .source = source.dupe(graph),
lib/std/Build/Step/ObjCopy.zig+1-1
......@@ -63,7 +63,7 @@ pub fn create(owner: *std.Build, input_file: std.Build.LazyPath, options: Option
6363 oc.* = .{
6464 .step = .init(.{
6565 .tag = base_tag,
66 .name = owner.fmt("objcopy {f}", .{input_file.fmt(graph)}),
66 .name = owner.fmt("objcopy {f}", .{input_file}),
6767 .owner = owner,
6868 }),
6969 .input_file = input_file,