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.

Step

Configuration.Step
pub const Step = extern struct

File

lib/std/Build/Configuration.zig:477

Code

pub const Step = extern struct {
    name: String,
    owner: Package.Index,
    deps: Deps.Index,
    max_rss: MaxRss,
    extended: Storage.Extended(Flags, union(Tag) {
        check_file: CheckFile,
        compile: Compile,
        config_header: ConfigHeader,
        fail: Fail,
        find_program: FindProgram,
        fmt: Fmt,
        install_artifact: InstallArtifact,
        install_dir: InstallDir,
        install_file: InstallFile,
        obj_copy: ObjCopy,
        options: Options,
        run: Run,
        top_level: TopLevel,
        translate_c: TranslateC,
        update_source_files: UpdateSourceFiles,
        write_file: WriteFile,
    }),

    /// Points into `steps`.
    pub const Index = enum(u32) {
        _,

        pub fn ptr(i: Index, c: *const Configuration) *const Step {
            return &c.steps[@backingInt(i)];
        }
    };

    /// Shared by all steps.
    pub const Flags = packed struct(u32) {
        tag: Tag,
        _: u27 = 0,
    };

    pub const Tag = enum(u5) {
        check_file,
        compile,
        config_header,
        fail,
        find_program,
        fmt,
        install_artifact,
        install_dir,
        install_file,
        obj_copy,
        options,
        run,
        top_level,
        translate_c,
        update_source_files,
        write_file,
    };

    pub const TopLevel = struct {
        flags: @This().Flags = .{},
        description: String,

        pub const Flags = packed struct(u32) {
            tag: Tag = .top_level,
            _: u27 = 0,
        };
    };

    /// The first dependency step index will be the compile step whose
    /// artifacts are being installed with this step.
    pub const InstallArtifact = struct {
        flags: @This().Flags,
        bin_dir: Storage.FlagOptional(.flags, .bin_dir, InstallDestDir),
        implib_dir: Storage.FlagOptional(.flags, .implib_dir, InstallDestDir),
        pdb_dir: Storage.FlagOptional(.flags, .pdb_dir, InstallDestDir),
        h_dir: Storage.FlagOptional(.flags, .h_dir, InstallDestDir),
        bin_sub_path: Storage.FlagOptional(.flags, .bin_sub_path, String),

        pub const Flags = packed struct(u32) {
            tag: Tag = .install_artifact,
            dylib_symlinks: bool,
            bin_dir: bool,
            implib_dir: bool,
            pdb_dir: bool,
            h_dir: bool,
            bin_sub_path: bool,
            _: u21 = 0,
        };
    };

    pub const Run = struct {
        flags: @This().Flags,
        flags2: Flags2,
        args: Storage.LengthPrefixedList(Arg.Index),
        cwd: Storage.FlagOptional(.flags, .cwd, LazyPath.Index),
        preopen_names: Storage.LengthPrefixedList(String),
        preopen_paths: Storage.LengthPrefixedList(LazyPath.Index),
        captured_stdout: Storage.FlagOptional(.flags, .captured_stdout, CapturedStream),
        captured_stderr: Storage.FlagOptional(.flags, .captured_stderr, CapturedStream),
        file_inputs: Storage.LengthPrefixedList(LazyPath.Index),
        stdio_limit: Storage.FlagOptional(.flags, .stdio_limit, u64),
        /// Always a compile step.
        producer: Storage.FlagOptional(.flags, .producer, Step.Index),
        /// First half is keys, second half is values.
        environ_map: Storage.FlagOptional(.flags, .environ_map, EnvironMap.Index),
        stdin: Storage.FlagUnion(.flags, .stdin, StdIn),
        expect_stderr_exact: Storage.FlagOptional(.flags2, .expect_stderr_exact, Bytes),
        expect_stdout_exact: Storage.FlagOptional(.flags2, .expect_stdout_exact, Bytes),
        expect_stderr_match: Storage.FlagLengthPrefixedList(.flags2, .expect_stderr_match, Bytes),
        expect_stdout_match: Storage.FlagLengthPrefixedList(.flags2, .expect_stdout_match, Bytes),
        expect_term_value: Storage.FlagOptional(.flags2, .expect_term, u32),
        expect_stdout_snapshot: Storage.FlagOptional(.flags2, .expect_stdout_snapshot, LazyPath.Index),
        expect_stderr_snapshot: Storage.FlagOptional(.flags2, .expect_stderr_snapshot, LazyPath.Index),

        pub const CapturedStream = extern struct {
            generated_file: GeneratedFileIndex,
            basename: String,
        };

        pub const Arg = struct {
            flags: @This().Flags,
            prefix: Storage.FlagOptional(.flags, .prefix, String),
            suffix: Storage.FlagOptional(.flags, .suffix, String),
            basename: Storage.FlagOptional(.flags, .basename, String),
            path: Storage.FlagOptional(.flags, .path, LazyPath.Index),
            /// Always a compile step.
            producer: Storage.FlagOptional(.flags, .producer, Step.Index),
            generated: Storage.FlagOptional(.flags, .generated, GeneratedFileIndex),

            pub const Flags = packed struct(u32) {
                tag: Arg.Tag,
                prefix: bool,
                suffix: bool,
                basename: bool,
                path: bool,
                producer: bool,
                generated: bool,
                dep_file: bool,
                make_absolute: bool,
                _: u20 = 0,
            };

            pub const Tag = enum(u4) {
                artifact,
                /// `path` contains the file.
                path_file,
                path_directory,
                /// `prefix` contains the string.
                string,
                file_content,
                output_file,
                output_directory,
                passthru,
            };

            pub const Index = IndexType(@This());
        };

        pub const Color = enum(u4) {
            /// `CLICOLOR_FORCE` is set, and `NO_COLOR` is unset.
            enable,
            /// `NO_COLOR` is set, and `CLICOLOR_FORCE` is unset.
            disable,
            /// If the build runner is using color, equivalent to `.enable`. Otherwise, equivalent to `.disable`.
            inherit,
            /// If stderr is captured or checked, equivalent to `.disable`. Otherwise, equivalent to `.inherit`.
            auto,
            /// The build runner does not modify the `CLICOLOR_FORCE` or `NO_COLOR` environment variables.
            /// They are treated like normal variables, so can be controlled through `setEnvironmentVariable`.
            manual,
        };

        pub const StdIn = union(@This().Tag) {
            none: void,
            bytes: Bytes,
            lazy_path: LazyPath.Index,

            pub const Tag = enum(u2) { none, bytes, lazy_path };
        };
        pub const TrimWhitespace = enum(u2) { none, all, leading, trailing };
        pub const StdIo = enum(u2) { infer_from_args, inherit, check, zig_test };

        pub const ExpectTermStatus = enum(u2) { exited, signal, stopped, unknown };

        pub const Flags = packed struct(u32) {
            tag: Tag = .run,
            disable_zig_progress: bool,
            skip_foreign_checks: bool,
            failing_to_execute_foreign_is_an_error: bool,
            has_side_effects: bool,
            test_runner_mode: bool,
            color: Color,
            stdin: StdIn.Tag,
            stdio: StdIo,
            stdout_trim_whitespace: TrimWhitespace,
            stderr_trim_whitespace: TrimWhitespace,
            stdio_limit: bool,
            producer: bool,
            cwd: bool,
            captured_stdout: bool,
            captured_stderr: bool,
            environ_map: bool,
            _: u4 = 0,
        };

        pub const Flags2 = packed struct(u32) {
            expect_stderr_exact: bool,
            expect_stdout_exact: bool,
            expect_stderr_match: bool,
            expect_stdout_match: bool,
            expect_term: bool,
            expect_term_status: ExpectTermStatus,
            expect_stdout_snapshot: bool,
            expect_stderr_snapshot: bool,
            _: u23 = 0,
        };
    };

    pub const Compile = struct {
        flags: @This().Flags,
        flags2: Flags2,
        flags3: Flags3,
        flags4: Flags4,

        root_module: Module.Index,
        root_name: String,

        filters: Storage.FlagLengthPrefixedList(.flags, .filters_len, String),
        installed_headers: Storage.FlagLengthPrefixedList(.flags, .installed_headers_len, Storage.Extended(InstalledHeader.Flags, InstalledHeader)),
        force_undefined_symbols: Storage.FlagLengthPrefixedList(.flags, .force_undefined_symbols_len, String),
        expect_errors: Storage.FlagUnion(.flags4, .expect_errors, ExpectErrors),
        linker_script: Storage.FlagOptional(.flags4, .linker_script, LazyPath.Index),
        version_script: Storage.FlagOptional(.flags4, .version_script, LazyPath.Index),
        zig_lib_dir: Storage.FlagOptional(.flags3, .zig_lib_dir, LazyPath.Index),
        libc_file: Storage.FlagOptional(.flags4, .libc_file, LazyPath.Index),
        win32_manifest: Storage.FlagOptional(.flags3, .win32_manifest, LazyPath.Index),
        win32_module_definition: Storage.FlagOptional(.flags3, .win32_module_definition, LazyPath.Index),
        entitlements: Storage.FlagOptional(.flags4, .entitlements, LazyPath.Index),
        version: Storage.FlagOptional(.flags3, .version, String), // semantic version string
        entry: Storage.EnumOptional(.flags3, .entry, .symbol_name, String),
        install_name: Storage.FlagOptional(.flags4, .install_name, String),
        initial_memory: Storage.FlagOptional(.flags3, .initial_memory, u64),
        max_memory: Storage.FlagOptional(.flags3, .max_memory, u64),
        global_base: Storage.FlagOptional(.flags3, .global_base, u64),
        image_base: Storage.FlagOptional(.flags3, .image_base, u64),
        link_z_common_page_size: Storage.FlagOptional(.flags4, .link_z_common_page_size, u64),
        link_z_max_page_size: Storage.FlagOptional(.flags4, .link_z_max_page_size, u64),
        pagezero_size: Storage.FlagOptional(.flags4, .pagezero_size, u64),
        stack_size: Storage.FlagOptional(.flags4, .stack_size, u64),
        headerpad_size: Storage.FlagOptional(.flags4, .headerpad_size, u32),
        error_limit: Storage.FlagOptional(.flags4, .error_limit, u32),
        build_id: Storage.EnumOptional(.flags3, .build_id, .hexstring, String),
        test_runner: Storage.FlagUnion(.flags3, .test_runner, TestRunner),

        emit_directory: Storage.FlagOptional(.flags4, .emit_directory, GeneratedFileIndex),
        generated_docs: Storage.FlagOptional(.flags4, .generated_docs, GeneratedFileIndex),
        generated_asm: Storage.FlagOptional(.flags4, .generated_asm, GeneratedFileIndex),
        generated_bin: Storage.FlagOptional(.flags4, .generated_bin, GeneratedFileIndex),
        generated_pdb: Storage.FlagOptional(.flags4, .generated_pdb, GeneratedFileIndex),
        generated_implib: Storage.FlagOptional(.flags4, .generated_implib, GeneratedFileIndex),
        generated_llvm_bc: Storage.FlagOptional(.flags4, .generated_llvm_bc, GeneratedFileIndex),
        generated_llvm_ir: Storage.FlagOptional(.flags4, .generated_llvm_ir, GeneratedFileIndex),
        generated_h: Storage.FlagOptional(.flags4, .generated_h, GeneratedFileIndex),

        pub const InstalledHeader = union(@This().Tag) {
            file: File,
            directory: Directory,

            pub const Flags = packed struct(u32) {
                tag: InstalledHeader.Tag,
                _: u24 = 0,
            };

            pub const Tag = enum(u8) {
                file,
                directory,
            };

            pub const File = struct {
                flags: @This().Flags = .{},
                source: LazyPath.Index,
                dest_sub_path: String,

                pub const Flags = packed struct(u32) {
                    tag: InstalledHeader.Tag = .file,
                    _: u24 = 0,
                };
            };

            pub const Directory = struct {
                flags: @This().Flags,
                source: LazyPath.Index,
                dest_sub_path: String,
                exclude_extensions: Storage.FlagLengthPrefixedList(.flags, .exclude_extensions, String),
                include_extensions: Storage.FlagLengthPrefixedList(.flags, .include_extensions, String),

                pub const Flags = packed struct(u32) {
                    tag: InstalledHeader.Tag = .directory,
                    exclude_extensions: bool,
                    include_extensions: bool,
                    _: u22 = 0,
                };
            };
        };
        pub const ExpectErrors = union(@This().Tag) {
            pub const Tag = enum(u3) { contains, exact, starts_with, stderr_contains, none };

            contains: String,
            exact: Storage.LengthPrefixedList(String),
            starts_with: String,
            stderr_contains: String,
            none: void,
        };
        pub const TestRunner = union(@This().Tag) {
            pub const Tag = enum(u2) { default, simple, server };

            default: void,
            simple: LazyPath.Index,
            server: LazyPath.Index,
        };
        pub const Entry = enum(u2) { default, disabled, enabled, symbol_name };

        pub const Lto = enum(u2) {
            none,
            full,
            thin,
            default,

            pub fn init(lto: ?std.zig.LtoMode) Lto {
                return switch (lto orelse return .default) {
                    .none => .none,
                    .full => .full,
                    .thin => .thin,
                };
            }
        };

        pub const BuildId = enum(u3) {
            none,
            fast,
            uuid,
            sha1,
            md5,
            hexstring,
            default,

            pub fn init(build_id: ?std.zig.BuildId) BuildId {
                return switch (build_id orelse return .default) {
                    .none => .none,
                    .fast => .fast,
                    .uuid => .uuid,
                    .sha1 => .sha1,
                    .md5 => .md5,
                    .hexstring => .hexstring,
                };
            }

            pub fn unwrap(this: @This(), hexstring: ?String, c: *const Configuration) ?std.zig.BuildId {
                if (hexstring) |h| {
                    assert(this == .hexstring);
                    return .initHexString(h.slice(c));
                }
                return switch (this) {
                    .none => .none,
                    .fast => .fast,
                    .uuid => .uuid,
                    .sha1 => .sha1,
                    .md5 => .md5,
                    .hexstring => unreachable,
                    .default => null,
                };
            }
        };
        pub const WasiExecModel = enum(u2) {
            default,
            command,
            reactor,

            pub fn init(wasi_exec_model: ?std.builtin.WasiExecModel) WasiExecModel {
                return switch (wasi_exec_model orelse return .default) {
                    .command => .command,
                    .reactor => .reactor,
                };
            }
        };
        pub const Linkage = enum(u2) {
            static,
            dynamic,
            default,

            pub fn init(link_mode: ?std.builtin.LinkMode) Linkage {
                return switch (link_mode orelse return .default) {
                    .static => .static,
                    .dynamic => .dynamic,
                };
            }

            pub fn unwrap(this: @This()) ?std.builtin.LinkMode {
                return switch (this) {
                    .static => .static,
                    .dynamic => .dynamic,
                    .default => null,
                };
            }
        };
        pub const Kind = enum(u3) {
            exe,
            lib,
            obj,
            @"test",
            test_obj,

            pub fn isTest(kind: Kind) bool {
                return switch (kind) {
                    .exe, .lib, .obj => false,
                    .@"test", .test_obj => true,
                };
            }

            pub fn toOutputMode(kind: Kind) std.builtin.OutputMode {
                return switch (kind) {
                    .exe, .@"test" => .Exe,
                    .lib => .Lib,
                    .obj, .test_obj => .Obj,
                };
            }
        };
        pub const Subsystem = enum(u4) {
            console,
            windows,
            posix,
            native,
            efi_application,
            efi_boot_service_driver,
            efi_rom,
            efi_runtime_driver,
            default,

            pub fn init(subsystem: ?std.zig.Subsystem) Subsystem {
                return switch (subsystem orelse return .default) {
                    .console => .console,
                    .windows => .windows,
                    .posix => .posix,
                    .native => .native,
                    .efi_application => .efi_application,
                    .efi_boot_service_driver => .efi_boot_service_driver,
                    .efi_rom => .efi_rom,
                    .efi_runtime_driver => .efi_runtime_driver,
                };
            }
        };

        pub const Flags = packed struct(u32) {
            tag: Tag = .compile,

            filters_len: bool,
            installed_headers_len: bool,
            force_undefined_symbols_len: bool,

            verbose_link: bool,
            verbose_cc: bool,
            rdynamic: bool,
            import_memory: bool,
            export_memory: bool,
            import_symbols: bool,
            import_table: bool,
            export_table: bool,
            shared_memory: bool,
            link_eh_frame_hdr: bool,
            link_emit_relocs: bool,
            link_function_sections: bool,
            link_data_sections: bool,
            linker_dynamicbase: bool,
            link_z_notext: bool,
            link_z_relro: bool,
            link_z_lazy: bool,
            link_z_defs: bool,
            headerpad_max_install_names: bool,
            dead_strip_dylibs: bool,
            force_load_objc: bool,
            discard_local_symbols: bool,
            mingw_unicode_entry_point: bool,
            _: u1 = 0,
        };

        pub const Flags2 = packed struct(u32) {
            pie: DefaultingBool,
            formatted_panics: DefaultingBool,
            bundle_compiler_rt: DefaultingBool,
            bundle_ubsan_rt: DefaultingBool,
            each_lib_rpath: DefaultingBool,
            link_gc_sections: DefaultingBool,
            linker_allow_shlib_undefined: DefaultingBool,
            linker_allow_undefined_version: DefaultingBool,
            linker_enable_new_dtags: DefaultingBool,
            dll_export_fns: DefaultingBool,
            use_llvm: DefaultingBool,
            use_lld: DefaultingBool,
            use_new_linker: DefaultingBool,
            allow_so_scripts: DefaultingBool,
            sanitize_coverage_trace_pc_guard: DefaultingBool,
            linkage: Linkage,
        };

        pub const Flags3 = packed struct(u32) {
            is_linking_libc: bool,
            is_linking_libcpp: bool,
            version: bool,
            initial_memory: bool,
            max_memory: bool,
            kind: Kind,
            compress_debug_sections: std.zig.CompressDebugSections,
            global_base: bool,
            test_runner: TestRunner.Tag,
            wasi_exec_model: WasiExecModel,
            win32_manifest: bool,
            win32_module_definition: bool,
            zig_lib_dir: bool,
            rc_includes: std.zig.RcIncludes,
            image_base: bool,
            build_id: BuildId,
            entry: Entry,
            lto: Lto,
            subsystem: Subsystem,
        };

        pub const Flags4 = packed struct(u32) {
            libc_file: bool,
            link_z_common_page_size: bool,
            link_z_max_page_size: bool,
            pagezero_size: bool,
            stack_size: bool,
            headerpad_size: bool,
            error_limit: bool,
            install_name: bool,
            entitlements: bool,
            expect_errors: ExpectErrors.Tag,
            linker_script: bool,
            version_script: bool,
            emit_directory: bool,
            generated_docs: bool,
            generated_asm: bool,
            generated_bin: bool,
            generated_pdb: bool,
            generated_implib: bool,
            generated_llvm_bc: bool,
            generated_llvm_ir: bool,
            generated_h: bool,
            incremental: DefaultingBool,
            _: u7 = 0,
        };

        pub fn isDynamicLibrary(compile: *const Compile) bool {
            return compile.flags3.kind == .lib and compile.flags2.linkage == .dynamic;
        }

        pub fn isStaticLibrary(compile: *const Compile) bool {
            return compile.flags3.kind == .lib and compile.flags2.linkage != .dynamic;
        }

        pub fn producesImplib(compile: *const Compile, c: *const Configuration) bool {
            return isDll(compile, c);
        }

        pub fn isDll(compile: *const Compile, c: *const Configuration) bool {
            return isDynamicLibrary(compile) and rootModuleTarget(compile, c).flags.os_tag == .windows;
        }

        pub fn rootModuleTarget(compile: *const Compile, c: *const Configuration) TargetQuery {
            return compile.root_module.get(c).resolved_target.get(c).?.result.get(c);
        }
    };

    pub const CheckFile = struct {
        flags: @This().Flags,
        file: LazyPath.Index,
        expected_exact: Storage.FlagOptional(.flags, .expected_exact, Bytes),
        expected_matches: Storage.FlagLengthPrefixedList(.flags, .expected_matches, Bytes),
        max_bytes: Storage.FlagOptional(.flags, .max_bytes, u32),

        pub const Flags = packed struct(u32) {
            tag: Tag = .check_file,
            expected_exact: bool,
            expected_matches: bool,
            max_bytes: bool,
            _: u24 = 0,
        };
    };

    pub const ConfigHeader = struct {
        flags: @This().Flags,
        template_file: Storage.FlagOptional(.flags, .template_file, LazyPath.Index),
        generated_dir: GeneratedFileIndex,
        input_size_limit: Storage.FlagOptional(.flags, .input_size_limit, u64),
        include_path: String,
        include_guard: Storage.FlagOptional(.flags, .include_guard, String),
        values: Storage.LengthPrefixedList(Value.Pair),

        pub const Style = enum(u3) {
            autoconf_undef,
            autoconf_at,
            cmake,
            blank,
            nasm,

            pub fn init(s: std.Build.Step.ConfigHeader.Style) Style {
                return switch (s) {
                    .autoconf_undef => .autoconf_undef,
                    .autoconf_at => .autoconf_at,
                    .cmake => .cmake,
                    .blank => .blank,
                    .nasm => .nasm,
                };
            }
        };

        pub const Value = struct {
            flags: @This().Flags,
            i64: Storage.EnumOptional(.flags, .tag, .i64, i64),
            u64: Storage.EnumOptional(.flags, .tag, .u64, u64),
            ident: Storage.EnumOptional(.flags, .tag, .ident, String),
            string: Storage.EnumOptional(.flags, .tag, .string, String),

            pub const Flags = packed struct(u32) {
                tag: Value.Tag,
                small: u29,
            };

            pub const Tag = enum(u3) {
                ident,
                string,
                small_unsigned,
                small_signed,
                i64,
                u64,
            };

            pub const Pair = extern struct {
                key: String,
                index: Value.Index,
            };

            pub const Index = enum(u32) {
                int_0 = max_u32 - 5,
                int_1 = max_u32 - 4,
                bool_false = max_u32 - 3,
                bool_true = max_u32 - 2,
                undef = max_u32 - 1,
                defined = max_u32,
                _,

                pub fn unpack(this: @This(), c: *const Configuration) Unpacked {
                    return switch (this) {
                        .int_0 => .{ .u64 = 0 },
                        .int_1 => .{ .u64 = 1 },
                        .bool_false => .{ .bool = false },
                        .bool_true => .{ .bool = true },
                        .undef => .undef,
                        .defined => .defined,
                        _ => {
                            const value = extraData(c, Value, @backingInt(this));
                            return switch (value.flags.tag) {
                                .ident => .{ .ident = value.ident.value.?.slice(c) },
                                .string => .{ .string = value.string.value.?.slice(c) },
                                .small_unsigned => .{ .u64 = value.flags.small },
                                .small_signed => .{ .i64 = @as(i29, @bitCast(value.flags.small)) },
                                .i64 => .{ .i64 = value.i64.value.? },
                                .u64 => .{ .u64 = value.u64.value.? },
                            };
                        },
                    };
                }
            };

            pub const Unpacked = union(enum) {
                bool: bool,
                undef,
                defined,
                i64: i64,
                u64: u64,
                ident: []const u8,
                string: []const u8,
            };

            pub fn initSigned(x: i64) @This() {
                return switch (x) {
                    0 => unreachable, // should have been an Index
                    1 => unreachable, // should have been an Index
                    2...std.math.maxInt(u29) => .{
                        .flags = .{
                            .tag = .small_unsigned,
                            .small = @intCast(x),
                        },
                        .i64 = .{ .value = null },
                        .u64 = .{ .value = null },
                        .ident = .{ .value = null },
                        .string = .{ .value = null },
                    },
                    std.math.minInt(i29)...-1 => .{
                        .flags = .{
                            .tag = .small_signed,
                            .small = @bitCast(@as(i29, @intCast(x))),
                        },
                        .i64 = .{ .value = null },
                        .u64 = .{ .value = null },
                        .ident = .{ .value = null },
                        .string = .{ .value = null },
                    },
                    else => .{
                        .flags = .{
                            .tag = .i64,
                            .small = 0,
                        },
                        .i64 = .{ .value = x },
                        .u64 = .{ .value = null },
                        .ident = .{ .value = null },
                        .string = .{ .value = null },
                    },
                };
            }
        };

        pub const Flags = packed struct(u32) {
            tag: Tag = .config_header,
            template_file: bool,
            style: Style,
            input_size_limit: bool,
            include_guard: bool,
            _: u21 = 0,
        };
    };

    pub const Fail = struct {
        flags: @This().Flags = .{},
        msg: String,

        pub const Flags = packed struct(u32) {
            tag: Tag = .fail,
            _: u27 = 0,
        };
    };

    pub const Fmt = struct {
        flags: @This().Flags,
        paths: Storage.FlagLengthPrefixedList(.flags, .paths, LazyPath.Index),
        exclude_paths: Storage.FlagLengthPrefixedList(.flags, .exclude_paths, LazyPath.Index),

        pub const Flags = packed struct(u32) {
            tag: Tag = .fmt,
            paths: bool,
            exclude_paths: bool,
            check: bool,
            _: u24 = 0,
        };
    };

    pub const FindProgram = struct {
        flags: @This().Flags = .{},
        names: StringList,
        found_path: GeneratedFileIndex,

        pub const Flags = packed struct(u32) {
            tag: Tag = .find_program,
            _: u27 = 0,
        };
    };

    pub const InstallDir = struct {
        flags: @This().Flags,
        source_dir: LazyPath.Index,
        dest_dir: InstallDestDir,
        dest_sub_path: Storage.FlagOptional(.flags, .dest_sub_path, String),
        exclude_extensions: Storage.FlagLengthPrefixedList(.flags, .exclude_extensions, String),
        include_extensions: Storage.FlagLengthPrefixedList(.flags, .include_extensions, String),
        blank_extensions: Storage.FlagLengthPrefixedList(.flags, .blank_extensions, String),

        pub const Flags = packed struct(u32) {
            tag: Tag = .install_dir,
            dest_sub_path: bool,
            exclude_extensions: bool,
            include_extensions: bool,
            include_extensions_active: bool,
            blank_extensions: bool,
            _: u22 = 0,
        };
    };

    pub const InstallFile = struct {
        flags: @This().Flags = .{},
        source: LazyPath.Index,
        dest_dir: InstallDestDir,
        dest_sub_path: String,

        pub const Flags = packed struct(u32) {
            tag: Tag = .install_file,
            _: u27 = 0,
        };
    };

    pub const ObjCopy = struct {
        flags: @This().Flags,
        input_file: LazyPath.Index,
        output_file: GeneratedFileIndex,
        basename: Storage.FlagOptional(.flags, .basename, String),
        debug_file: Storage.FlagOptional(.flags, .debug_file, GeneratedFileIndex),
        debug_basename: Storage.FlagOptional(.flags, .debug_basename, String),
        only_section: Storage.FlagOptional(.flags, .only_section, String),
        pad_to: Storage.FlagOptional(.flags, .pad_to, u64),
        add_section: Storage.FlagLengthPrefixedList(.flags, .add_section, AddSection),
        update_section: Storage.FlagLengthPrefixedList(.flags, .update_section, UpdateSection),

        pub const Format = enum(u2) {
            binary,
            hex,
            elf,
            default,

            pub fn init(f: ?std.Build.Step.ObjCopy.Format) @This() {
                return switch (f orelse return .default) {
                    .binary => .binary,
                    .hex => .hex,
                    .elf => .elf,
                };
            }
        };

        pub const Strip = enum(u2) {
            none,
            debug,
            debug_and_symbols,
        };

        pub const AddSection = extern struct {
            section_name: String,
            file_path: LazyPath.Index,
        };

        pub const UpdateSection = extern struct {
            section_name: String,
            flags: @This().Flags,

            pub const Flags = packed struct(u32) {
                section_flags: SectionFlags,
                alignment: Alignment,
                _: u17 = 0,
            };
        };

        pub const SectionFlags = packed struct(u9) {
            /// add SHF_ALLOC
            alloc: bool = false,
            /// if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing
            contents: bool = false,
            /// if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing (same as contents)
            load: bool = false,
            /// readonly: clear default SHF_WRITE flag
            readonly: bool = false,
            /// add SHF_EXECINSTR
            code: bool = false,
            /// add SHF_EXCLUDE
            exclude: bool = false,
            /// add SHF_X86_64_LARGE. Fatal error if target is not x86_64
            large: bool = false,
            /// add SHF_MERGE
            merge: bool = false,
            /// add SHF_STRINGS
            strings: bool = false,

            pub const default: @This() = .{};
        };

        pub const Flags = packed struct(u32) {
            tag: Tag = .obj_copy,
            basename: bool,
            debug_file: bool,
            debug_basename: bool,
            format: Format,
            strip: Strip,
            compress_debug: bool,
            only_section: bool,
            pad_to: bool,
            add_section: bool,
            update_section: bool,
            _: u15 = 0,
        };
    };

    pub const Options = struct {
        flags: @This().Flags,
        generated_file: GeneratedFileIndex,
        contents: Bytes,
        args: Storage.FlagLengthPrefixedList(.flags, .args, Arg),

        pub const Arg = extern struct {
            name: String,
            path: LazyPath.Index,
        };

        pub const Flags = packed struct(u32) {
            tag: Tag = .options,
            args: bool,
            _: u26 = 0,
        };
    };

    pub const TranslateC = struct {
        flags: @This().Flags,
        src_path: LazyPath.Index,
        output_file: GeneratedFileIndex,
        include_dirs: Storage.UnionList(.flags, .include_dirs, Module.IncludeDir),
        system_libs: Storage.FlagLengthPrefixedList(.flags, .system_libs, SystemLib.Index),
        c_macros: Storage.FlagLengthPrefixedList(.flags, .c_macros, String),
        target: ResolvedTarget.OptionalIndex,

        pub const Flags = packed struct(u32) {
            tag: Tag = .translate_c,
            include_dirs: bool,
            system_libs: bool,
            c_macros: bool,
            link_libc: bool,
            optimize: Module.Optimize,
            _: u20 = 0,
        };
    };

    pub const UpdateSourceFiles = struct {
        flags: @This().Flags,
        embeds: Storage.FlagLengthPrefixedList(.flags, .embeds, Embed),
        copies: Storage.FlagLengthPrefixedList(.flags, .copies, Copy),

        pub const Embed = WriteFile.Embed;
        pub const Copy = WriteFile.Copy;

        pub const Flags = packed struct(u32) {
            tag: Tag = .update_source_files,
            embeds: bool,
            copies: bool,
            _: u25 = 0,
        };
    };

    pub const WriteFile = struct {
        flags: @This().Flags,
        generated_directory: GeneratedFileIndex,
        embeds: Storage.FlagLengthPrefixedList(.flags, .embeds, Embed),
        copies: Storage.FlagLengthPrefixedList(.flags, .copies, Copy),
        directories: Storage.FlagLengthPrefixedList(.flags, .directories, Directory),
        mutate_path: Storage.EnumOptional(.flags, .mode, .mutate, LazyPath.Index),

        pub const Embed = extern struct {
            sub_path: String,
            contents: Bytes,
        };

        pub const Copy = extern struct {
            sub_path: String,
            src_file: LazyPath.Index,
        };

        pub const Directory = extern struct {
            sub_path: String,
            src_path: LazyPath.Index,
            exclude_extensions: OptionalStringList,
            include_extensions: OptionalStringList,
        };

        pub const Mode = enum(u2) {
            whole_cached,
            tmp,
            mutate,
        };

        pub const Flags = packed struct(u32) {
            tag: Tag = .write_file,
            embeds: bool,
            copies: bool,
            directories: bool,
            mode: Mode,
            _: u22 = 0,
        };
    };

    pub fn flags(s: *const Step, c: *const Configuration) Flags {
        return @bitCast(c.extra[@backingInt(s.extended)]);
    }
}