make
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();
}