DoxigAlpha

Function parameters

Parameters

#
step:*Step
options:Step.MakeOptions

Type definitions in this namespace

Types

#

Functions in this namespace

Functions

#
getOutput
Deprecated; use `getOutputFile`.

= .config_header

Values

#
base_id
= .config_header

Source

Implementation

#
fn make(step: *Step, options: Step.MakeOptions) !void {
    _ = options;
    const b = step.owner;
    const config_header: *ConfigHeader = @fieldParentPtr("step", step);
    if (config_header.style.getPath()) |lp| try step.singleUnchangingWatchInput(lp);

    const gpa = b.allocator;
    const arena = b.allocator;

    var man = b.graph.cache.obtain();
    defer man.deinit();

    // Random bytes to make ConfigHeader unique. Refresh this with new
    // random bytes when ConfigHeader implementation is modified in a
    // non-backwards-compatible way.
    man.hash.add(@as(u32, 0xdef08d23));
    man.hash.addBytes(config_header.include_path);
    man.hash.addOptionalBytes(config_header.include_guard_override);

    var aw: std.io.Writer.Allocating = .init(gpa);
    defer aw.deinit();
    const bw = &aw.writer;

    const header_text = "This file was generated by ConfigHeader using the Zig Build System.";
    const c_generated_line = "/* " ++ header_text ++ " */\n";
    const asm_generated_line = "; " ++ header_text ++ "\n";

    switch (config_header.style) {
        .autoconf_undef, .autoconf_at => |file_source| {
            try bw.writeAll(c_generated_line);
            const src_path = file_source.getPath2(b, step);
            const contents = std.fs.cwd().readFileAlloc(arena, src_path, config_header.max_bytes) catch |err| {
                return step.fail("unable to read autoconf input file '{s}': {s}", .{
                    src_path, @errorName(err),
                });
            };
            switch (config_header.style) {
                .autoconf_undef => try render_autoconf_undef(step, contents, bw, config_header.values, src_path),
                .autoconf_at => try render_autoconf_at(step, contents, &aw, config_header.values, src_path),
                else => unreachable,
            }
        },
        .cmake => |file_source| {
            try bw.writeAll(c_generated_line);
            const src_path = file_source.getPath2(b, step);
            const contents = std.fs.cwd().readFileAlloc(arena, src_path, config_header.max_bytes) catch |err| {
                return step.fail("unable to read cmake input file '{s}': {s}", .{
                    src_path, @errorName(err),
                });
            };
            try render_cmake(step, contents, bw, config_header.values, src_path);
        },
        .blank => {
            try bw.writeAll(c_generated_line);
            try render_blank(gpa, bw, config_header.values, config_header.include_path, config_header.include_guard_override);
        },
        .nasm => {
            try bw.writeAll(asm_generated_line);
            try render_nasm(bw, config_header.values);
        },
    }

    const output = aw.written();
    man.hash.addBytes(output);

    if (try step.cacheHit(&man)) {
        const digest = man.final();
        config_header.generated_dir.path = try b.cache_root.join(arena, &.{ "o", &digest });
        return;
    }

    const digest = man.final();

    // If output_path has directory parts, deal with them.  Example:
    // output_dir is zig-cache/o/HASH
    // output_path is libavutil/avconfig.h
    // We want to open directory zig-cache/o/HASH/libavutil/
    // but keep output_dir as zig-cache/o/HASH for -I include
    const sub_path = b.pathJoin(&.{ "o", &digest, config_header.include_path });
    const sub_path_dirname = std.fs.path.dirname(sub_path).?;

    b.cache_root.handle.makePath(sub_path_dirname) catch |err| {
        return step.fail("unable to make path '{f}{s}': {s}", .{
            b.cache_root, sub_path_dirname, @errorName(err),
        });
    };

    b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = output }) catch |err| {
        return step.fail("unable to write file '{f}{s}': {s}", .{
            b.cache_root, sub_path, @errorName(err),
        });
    };

    config_header.generated_dir.path = try b.cache_root.join(arena, &.{ "o", &digest });
    try man.writeManifest();
}