Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

LazyPath

A reference to an existing or future path.

Build.LazyPath
pub const LazyPath = union(enum)

File

lib/std/Build.zig:2455

Code

pub const LazyPath = union(enum) {
    /// A source file path relative to build root.
    src_path: struct {
        owner: *std.Build,
        sub_path: []const u8,
    },

    generated: struct {
        index: Configuration.GeneratedFileIndex,

        /// The number of parent directories to go up.
        /// 0 means the generated file itself.
        /// 1 means the directory of the generated file.
        /// 2 means the parent of that directory, and so on.
        up: usize = 0,

        /// Applied after `up`.
        sub_path: []const u8 = "",
    },

    /// Deprecated; call `Graph.cwdRelativePath` instead.
    cwd_relative: []const u8,

    dependency: struct {
        dependency: *Dependency,
        sub_path: []const u8,
    },

    relative: struct {
        base: Configuration.LazyPath.Relative.Base,
        sub_path: []const u8 = "",

        pub fn eql(a: @This(), b: @This()) bool {
            return a.base == b.base and mem.eql(u8, a.sub_path, b.sub_path);
        }
    },

    /// Path to the Zig executable being used to execute "zig build".
    pub const zig_exe: LazyPath = .{ .relative = .{ .base = .zig_exe } };
    /// Path to the "lib/" directory from the Zig installation being used to
    /// execute "zig build".
    pub const zig_lib: LazyPath = .{ .relative = .{ .base = .zig_lib } };
    /// Path to the project's local cache directory (usually called ".zig-cache").
    pub const cache_root: LazyPath = .{ .relative = .{ .base = .local_cache } };

    /// Returns a lazy path referring to the directory containing this path.
    ///
    /// The dirname is not allowed to escape the logical root for underlying
    /// path. For example, if the path is relative to the build root, the
    /// dirname is not allowed to traverse outside of the build root.
    /// Similarly, if the path is a generated file inside zig-cache, the
    /// dirname is not allowed to traverse outside of zig-cache.
    pub fn dirname(lazy_path: LazyPath) LazyPath {
        return switch (lazy_path) {
            .src_path => |sp| .{ .src_path = .{
                .owner = sp.owner,
                .sub_path = dirnameAllowEmpty(sp.sub_path) orelse {
                    dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the build root\n", .{}) catch {};
                    @panic("misconfigured build script");
                },
            } },
            .generated => |generated| .{ .generated = if (dirnameAllowEmpty(generated.sub_path)) |sub_dirname| .{
                .index = generated.index,
                .up = generated.up,
                .sub_path = sub_dirname,
            } else .{
                .index = generated.index,
                .up = generated.up + 1,
                .sub_path = "",
            } },
            .cwd_relative => |rel_path| .{
                .cwd_relative = dirnameAllowEmpty(rel_path) orelse {
                    // If we get null, it means one of two things:
                    // - rel_path was absolute, and is now root
                    // - rel_path was relative, and is now ""
                    // In either case, the build script tried to go too far
                    // and we should panic.
                    if (fs.path.isAbsolute(rel_path)) {
                        dumpBadDirnameHelp(null, null,
                            \\dirname() attempted to traverse outside the root.
                            \\No more directories left to go up.
                            \\
                        , .{}) catch {};
                        @panic("misconfigured build script");
                    } else {
                        dumpBadDirnameHelp(null, null,
                            \\dirname() attempted to traverse outside the current working directory.
                            \\
                        , .{}) catch {};
                        @panic("misconfigured build script");
                    }
                },
            },
            .relative => |r| .{ .relative = .{
                .base = r.base,
                .sub_path = dirnameAllowEmpty(r.sub_path) orelse {
                    dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the base path\n", .{}) catch {};
                    @panic("misconfigured build script");
                },
            } },
            .dependency => |dep| .{ .dependency = .{
                .dependency = dep.dependency,
                .sub_path = dirnameAllowEmpty(dep.sub_path) orelse {
                    dumpBadDirnameHelp(null, null,
                        \\dirname() attempted to traverse outside the dependency root.
                        \\
                    , .{}) catch {};
                    @panic("misconfigured build script");
                },
            } },
        };
    }

    pub fn path(lazy_path: LazyPath, b: *Build, sub_path: []const u8) LazyPath {
        const graph = b.graph;
        const arena = graph.arena;
        return lazy_path.join(arena, sub_path) catch @panic("OOM");
    }

    pub fn join(lazy_path: LazyPath, arena: Allocator, sub_path: []const u8) Allocator.Error!LazyPath {
        return switch (lazy_path) {
            .src_path => |src| .{ .src_path = .{
                .owner = src.owner,
                .sub_path = try fs.path.resolve(arena, &.{ src.sub_path, sub_path }),
            } },
            .generated => |gen| .{ .generated = .{
                .index = gen.index,
                .up = gen.up,
                .sub_path = try fs.path.resolve(arena, &.{ gen.sub_path, sub_path }),
            } },
            .cwd_relative => |cwd_relative| .{
                .cwd_relative = try fs.path.resolve(arena, &.{ cwd_relative, sub_path }),
            },
            .relative => |r| .{ .relative = .{
                .base = r.base,
                .sub_path = try fs.path.resolve(arena, &.{ r.sub_path, sub_path }),
            } },
            .dependency => |dep| .{ .dependency = .{
                .dependency = dep.dependency,
                .sub_path = try fs.path.resolve(arena, &.{ dep.sub_path, sub_path }),
            } },
        };
    }

    /// Deprecated, use `format` instead.
    pub fn getDisplayName(lazy_path: LazyPath) []const u8 {
        return switch (lazy_path) {
            .src_path => |sp| sp.sub_path,
            .cwd_relative => |p| p,
            .generated => "generated",
            .dependency => "dependency",
            .relative => |r| @tagName(r.base),
        };
    }

    pub fn format(lp: LazyPath, w: *Io.Writer) Io.Writer.Error!void {
        switch (lp) {
            .src_path => |sp| try w.writeAll(sp.sub_path),
            .cwd_relative => |p| try w.writeAll(p),
            .generated => try w.writeAll("generated"),
            .dependency => try w.writeAll("dependency"),
            .relative => |r| try w.print("{t} {s}", .{ r.base, r.sub_path }),
        }
    }

    /// Adds dependencies this file source implies to the given step.
    pub fn addStepDependencies(lazy_path: LazyPath, other_step: *Step) void {
        switch (lazy_path) {
            .src_path, .cwd_relative, .relative, .dependency => {},
            .generated => |gen| {
                const graph = other_step.owner.graph;
                const generated_owner_step = graph.generated_files.items[@backingInt(gen.index)];
                other_step.dependOn(generated_owner_step);
            },
        }
    }

    /// Copies the internal strings.
    ///
    /// The `graph` parameter is only used for the global arena allocator.
    pub fn dupe(lazy_path: LazyPath, graph: *const Graph) LazyPath {
        return dupeInner(lazy_path, graph.arena);
    }

    /// Copies the slice of paths and all internal strings.
    ///
    /// The `graph` parameter is only used for the global arena allocator.
    pub fn dupeList(lazy_paths: []const LazyPath, graph: *const Graph) []const LazyPath {
        const arena = graph.arena;
        const result = graph.alloc(LazyPath, lazy_paths.len);
        for (result, lazy_paths) |*d, s| d.* = dupeInner(s, arena);
        return result;
    }

    fn dupeInner(lazy_path: LazyPath, arena: Allocator) LazyPath {
        return switch (lazy_path) {
            .src_path => |sp| .{ .src_path = .{ .owner = sp.owner, .sub_path = sp.owner.dupePath(sp.sub_path) } },
            .cwd_relative => |p| .{ .cwd_relative = Graph.dupePathInner(arena, p) },
            .relative => |r| .{ .relative = r },
            .generated => |gen| .{ .generated = .{
                .index = gen.index,
                .up = gen.up,
                .sub_path = Graph.dupePathInner(arena, gen.sub_path),
            } },
            .dependency => |dep| .{ .dependency = .{
                .dependency = dep.dependency,
                .sub_path = Graph.dupePathInner(arena, dep.sub_path),
            } },
        };
    }
}