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 {...@@ -208,7 +208,7 @@ const Serialize = struct {
208 .relative => |relative| i: {208 .relative => |relative| i: {
209 break :i try wc.addExtraErased(Configuration.LazyPath.Relative, .{209 break :i try wc.addExtraErased(Configuration.LazyPath.Relative, .{
210 .flags = .{ .base = relative.base },210 .flags = .{ .base = relative.base },
211 .sub_path = relative.sub_path,211 .sub_path = try wc.addString(relative.sub_path),
212 });212 });
213 },213 },
214 .dependency => |dependency| i: {214 .dependency => |dependency| i: {
lib/std/Build.zig+40-47
...@@ -166,10 +166,9 @@ pub const Graph = struct {...@@ -166,10 +166,9 @@ pub const Graph = struct {
166 /// A path whose components and contents are known at some point during166 /// A path whose components and contents are known at some point during
167 /// `Step` resolution, relative to the provided base directory.167 /// `Step` resolution, relative to the provided base directory.
168 pub fn path(graph: *Graph, base: Configuration.Path.Base, sub_path: []const u8) LazyPath {168 pub fn path(graph: *Graph, base: Configuration.Path.Base, sub_path: []const u8) LazyPath {
169 const wc = &graph.wip_configuration;
170 return .{ .relative = .{169 return .{ .relative = .{
171 .base = base,170 .base = base,
172 .sub_path = wc.addString(sub_path) catch @panic("OOM"),171 .sub_path = @This().dupePath(graph, sub_path),
173 } };172 } };
174 }173 }
175174
...@@ -974,12 +973,12 @@ pub fn dupe(b: *Build, bytes: []const u8) []const u8 {...@@ -974,12 +973,12 @@ pub fn dupe(b: *Build, bytes: []const u8) []const u8 {
974 return b.graph.dupeString(bytes);973 return b.graph.dupeString(bytes);
975}974}
976975
977/// Duplicates an array of strings without the need to handle out of memory.976/// Deprecated, call `Graph.dupeStrings` instead.
978pub fn dupeStrings(b: *Build, strings: []const []const u8) []const []const u8 {977pub fn dupeStrings(b: *Build, strings: []const []const u8) []const []const u8 {
979 return b.graph.dupeStrings(strings);978 return b.graph.dupeStrings(strings);
980}979}
981980
982/// Duplicates a path, canonicalizing path separators.981/// Deprecated, call `Graph.dupePath` instead.
983pub fn dupePath(b: *Build, bytes: []const u8) []const u8 {982pub fn dupePath(b: *Build, bytes: []const u8) []const u8 {
984 return b.graph.dupePath(bytes);983 return b.graph.dupePath(bytes);
985}984}
...@@ -1536,7 +1535,7 @@ pub fn addUserInputFlag(b: *Build, name_raw: []const u8) error{OutOfMemory}!bool...@@ -1536,7 +1535,7 @@ pub fn addUserInputFlag(b: *Build, name_raw: []const u8) error{OutOfMemory}!bool
1536 return true;1535 return true;
1537 },1536 },
1538 .lazy_path => |lp| {1537 .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 });
1540 return true;1539 return true;
1541 },1540 },
15421541
...@@ -2381,10 +2380,10 @@ pub const LazyPath = union(enum) {...@@ -2381,10 +2380,10 @@ pub const LazyPath = union(enum) {
23812380
2382 relative: struct {2381 relative: struct {
2383 base: Configuration.Path.Base,2382 base: Configuration.Path.Base,
2384 sub_path: Configuration.String = .empty,2383 sub_path: []const u8 = "",
23852384
2386 pub fn eql(a: @This(), b: @This()) bool {2385 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);
2388 }2387 }
2389 },2388 },
23902389
...@@ -2398,11 +2397,11 @@ pub const LazyPath = union(enum) {...@@ -2398,11 +2397,11 @@ pub const LazyPath = union(enum) {
23982397
2399 /// Returns a lazy path referring to the directory containing this path.2398 /// Returns a lazy path referring to the directory containing this path.
2400 ///2399 ///
2401 /// The dirname is not allowed to escape the logical root for underlying path.2400 /// The dirname is not allowed to escape the logical root for underlying
2402 /// For example, if the path is relative to the build root,2401 /// path. For example, if the path is relative to the build root, the
2403 /// the dirname is not allowed to traverse outside of the build root.2402 /// dirname is not allowed to traverse outside of the build root.
2404 /// Similarly, if the path is a generated file inside zig-cache,2403 /// Similarly, if the path is a generated file inside zig-cache, the
2405 /// the dirname is not allowed to traverse outside of zig-cache.2404 /// dirname is not allowed to traverse outside of zig-cache.
2406 pub fn dirname(lazy_path: LazyPath) LazyPath {2405 pub fn dirname(lazy_path: LazyPath) LazyPath {
2407 return switch (lazy_path) {2406 return switch (lazy_path) {
2408 .src_path => |sp| .{ .src_path = .{2407 .src_path => |sp| .{ .src_path = .{
...@@ -2444,9 +2443,13 @@ pub const LazyPath = union(enum) {...@@ -2444,9 +2443,13 @@ pub const LazyPath = union(enum) {
2444 }2443 }
2445 },2444 },
2446 },2445 },
2447 .relative => .{2446 .relative => |r| .{ .relative = .{
2448 .relative = @panic("TODO"),2447 .base = r.base,
2449 },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 } },
2450 .dependency => |dep| .{ .dependency = .{2453 .dependency => |dep| .{ .dependency = .{
2451 .dependency = dep.dependency,2454 .dependency = dep.dependency,
2452 .sub_path = dirnameAllowEmpty(dep.sub_path) orelse {2455 .sub_path = dirnameAllowEmpty(dep.sub_path) orelse {
...@@ -2480,9 +2483,10 @@ pub const LazyPath = union(enum) {...@@ -2480,9 +2483,10 @@ pub const LazyPath = union(enum) {
2480 .cwd_relative => |cwd_relative| .{2483 .cwd_relative => |cwd_relative| .{
2481 .cwd_relative = try fs.path.resolve(arena, &.{ cwd_relative, sub_path }),2484 .cwd_relative = try fs.path.resolve(arena, &.{ cwd_relative, sub_path }),
2482 },2485 },
2483 .relative => .{2486 .relative => |r| .{ .relative = .{
2484 .relative = @panic("TODO"),2487 .base = r.base,
2485 },2488 .sub_path = try fs.path.resolve(arena, &.{ r.sub_path, sub_path }),
2489 } },
2486 .dependency => |dep| .{ .dependency = .{2490 .dependency => |dep| .{ .dependency = .{
2487 .dependency = dep.dependency,2491 .dependency = dep.dependency,
2488 .sub_path = try fs.path.resolve(arena, &.{ dep.sub_path, sub_path }),2492 .sub_path = try fs.path.resolve(arena, &.{ dep.sub_path, sub_path }),
...@@ -2490,27 +2494,25 @@ pub const LazyPath = union(enum) {...@@ -2490,27 +2494,25 @@ pub const LazyPath = union(enum) {
2490 };2494 };
2491 }2495 }
24922496
2493 pub const Format = struct {2497 /// Deprecated, use `format` instead.
2494 graph: *const Graph,2498 pub fn getDisplayName(lazy_path: LazyPath) []const u8 {
2495 lazy_path: *const LazyPath,2499 return switch (lazy_path) {
24962500 .src_path => |sp| sp.sub_path,
2497 pub fn format(f: Format, w: *Io.Writer) Io.Writer.Error!void {2501 .cwd_relative => |p| p,
2498 switch (f.lazy_path.*) {2502 .generated => "generated",
2499 .src_path => |sp| try w.writeAll(sp.sub_path),2503 .dependency => "dependency",
2500 .cwd_relative => |p| try w.writeAll(p),2504 .relative => |r| @tagName(r.base),
2501 .generated => try w.writeAll("generated"),2505 };
2502 .dependency => try w.writeAll("dependency"),2506 }
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 };
25112507
2512 pub fn fmt(lp: *const LazyPath, graph: *const Graph) Format {2508 pub fn format(lp: LazyPath, w: *Io.Writer) Io.Writer.Error!void {
2513 return .{ .graph = graph, .lazy_path = lp };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 }
2514 }2516 }
25152517
2516 /// Adds dependencies this file source implies to the given step.2518 /// Adds dependencies this file source implies to the given step.
...@@ -2525,15 +2527,6 @@ pub const LazyPath = union(enum) {...@@ -2525,15 +2527,6 @@ pub const LazyPath = union(enum) {
2525 }2527 }
2526 }2528 }
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
2537 /// Copies the internal strings.2530 /// Copies the internal strings.
2538 ///2531 ///
2539 /// The `graph` parameter is only used for the global arena allocator.2532 /// 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 {...@@ -73,7 +73,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
73 .src_path => |sp| sp.sub_path,73 .src_path => |sp| sp.sub_path,
74 .generated => break :default,74 .generated => break :default,
75 .cwd_relative => |sub_path| sub_path,75 .cwd_relative => |sub_path| sub_path,
76 .relative => |r| wc.stringSlice(r.sub_path),76 .relative => |r| r.sub_path,
77 .dependency => |dependency| dependency.sub_path,77 .dependency => |dependency| dependency.sub_path,
78 };78 };
79 const basename = Io.Dir.path.basename(sub_path);79 const basename = Io.Dir.path.basename(sub_path);
...@@ -85,7 +85,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {...@@ -85,7 +85,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
8585
86 const name = if (options.style.getPath()) |s|86 const name = if (options.style.getPath()) |s|
87 allocPrint(arena, "configure {t} header {f} to {s}", .{87 allocPrint(arena, "configure {t} header {f} to {s}", .{
88 options.style, s.fmt(graph), include_path,88 options.style, s, include_path,
89 }) catch @panic("OOM")89 }) catch @panic("OOM")
90 else90 else
91 allocPrint(arena, "configure {t} header to {s}", .{91 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 {...@@ -47,7 +47,7 @@ pub fn create(owner: *std.Build, options: Options) *InstallDir {
47 install_dir.* = .{47 install_dir.* = .{
48 .step = Step.init(.{48 .step = Step.init(.{
49 .tag = base_tag,49 .tag = base_tag,
50 .name = owner.fmt("install {f}/", .{options.source_dir.fmt(graph)}),50 .name = owner.fmt("install {f}/", .{options.source_dir}),
51 .owner = owner,51 .owner = owner,
52 }),52 }),
53 .options = options.dupe(graph),53 .options = options.dupe(graph),
lib/std/Build/Step/InstallFile.zig+1-1
...@@ -26,7 +26,7 @@ pub fn create(...@@ -26,7 +26,7 @@ pub fn create(
26 install_file.* = .{26 install_file.* = .{
27 .step = Step.init(.{27 .step = Step.init(.{
28 .tag = base_tag,28 .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 }),
30 .owner = owner,30 .owner = owner,
31 }),31 }),
32 .source = source.dupe(graph),32 .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...@@ -63,7 +63,7 @@ pub fn create(owner: *std.Build, input_file: std.Build.LazyPath, options: Option
63 oc.* = .{63 oc.* = .{
64 .step = .init(.{64 .step = .init(.{
65 .tag = base_tag,65 .tag = base_tag,
66 .name = owner.fmt("objcopy {f}", .{input_file.fmt(graph)}),66 .name = owner.fmt("objcopy {f}", .{input_file}),
67 .owner = owner,67 .owner = owner,
68 }),68 }),
69 .input_file = input_file,69 .input_file = input_file,