feature. See also
. The project being documented here (as the example) is the Zig library itself.
ConfigHeader.make
pub fn make(
config_header: *ConfigHeader,
step_index: Configuration.Step.Index,
maker: *Maker,
progress_node: std.Progress.Node,
) Step.ExtendedMakeError!void
File
Code
pub fn make(
config_header: *ConfigHeader,
step_index: Configuration.Step.Index,
maker: *Maker,
progress_node: std.Progress.Node,
) Step.ExtendedMakeError!void {
_ = config_header;
const graph = maker.graph;
const step = maker.stepByIndex(step_index);
const io = graph.io;
const arena = graph.arena;
const conf = &maker.scanned_config.configuration;
const conf_step = step_index.ptr(conf);
const conf_ch = conf_step.extended.get(conf.extra).config_header;
const cache_root = graph.local_cache_root;
const input_size_limit: Io.Limit = if (conf_ch.input_size_limit.value) |x| .limited64(x) else .unlimited;
const include_guard_override: ?[]const u8 = if (conf_ch.include_guard.value) |s| s.slice(conf) else null;
const include_path: []const u8 = conf_ch.include_path.slice(conf);
const template_file = if (conf_ch.template_file.value) |lp|
try maker.resolveLazyPathIndex(arena, lp, step_index)
else
null;
const value_pairs = conf_ch.values.slice;
if (conf_ch.template_file.value) |lp| try step.singleUnchangingWatchInput(maker, arena, lp.get(conf));
var value_map: ValueMap = .empty;
try value_map.ensureTotalCapacity(arena, value_pairs.len);
for (value_pairs) |pair| value_map.putAssumeCapacityNoClobber(pair.key.slice(conf), false);
var man = graph.cache.obtain();
defer man.deinit();
// random bytes when ConfigHeader implementation is modified in a
// non-backwards-compatible way.
man.hash.add(@as(u32, 0xdef08d23));
man.hash.add(@as(u32, @bitCast(conf_ch.flags)));
man.hash.addBytes(include_path);
man.hash.addOptionalBytes(include_guard_override);
var aw: Writer.Allocating = .init(arena);
defer aw.deinit();
switch (conf_ch.flags.style) {
.autoconf_undef => {
const tf = template_file.?;
const contents = tf.root_dir.handle.readFileAlloc(io, tf.sub_path, arena, input_size_limit) catch |err|
return step.fail(maker, "unable to read autoconf input file {f}: {t}", .{ tf, err });
renderAutoConfUndef(maker, step, contents, &aw.writer, value_pairs, &value_map, tf) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
else => |e| return e,
};
},
.autoconf_at => {
const tf = template_file.?;
const contents = tf.root_dir.handle.readFileAlloc(io, tf.sub_path, arena, input_size_limit) catch |err|
return step.fail(maker, "unable to read autoconf input file {f}: {t}", .{ tf, err });
renderAutoconfAt(maker, step, contents, &aw, value_pairs, &value_map, tf) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
else => |e| return e,
};
},
.cmake => {
const tf = template_file.?;
const contents = tf.root_dir.handle.readFileAlloc(io, tf.sub_path, arena, input_size_limit) catch |err|
return step.fail(maker, "unable to read cmake input file {f}: {t}", .{ tf, err });
renderCmake(arena, maker, step, contents, &aw.writer, value_pairs, &value_map, tf) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
else => |e| return e,
};
},
.blank => {
renderBlank(conf, &aw.writer, value_pairs, &value_map, include_path, include_guard_override) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
else => |e| return e,
};
},
.nasm => {
renderNasm(conf, &aw.writer, value_pairs, &value_map) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
else => |e| return e,
};
},
}
const output = aw.written();
man.hash.addBytes(output);
if (try step.cacheHit(maker, &man, progress_node)) {
const digest = man.final();
maker.generatedPath(conf_ch.generated_dir).* = .{
.root_dir = cache_root,
.sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
};
return;
}
const digest = man.final();
// 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 out_path: Path = .{
.root_dir = cache_root,
.sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, conf_ch.include_path.slice(conf) }),
};
const out_path_dirname = out_path.dirname().?;
out_path_dirname.root_dir.handle.createDirPath(io, out_path_dirname.sub_path) catch |err|
return step.fail(maker, "unable to make path {f}: {t}", .{ out_path_dirname, err });
out_path.root_dir.handle.writeFile(io, .{ .sub_path = out_path.sub_path, .data = output }) catch |err|
return step.fail(maker, "unable to write file {f}: {t}", .{ out_path, err });
maker.generatedPath(conf_ch.generated_dir).* = .{
.root_dir = cache_root,
.sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
};
try step.writeManifest(maker, &man);
}