std.Build: enhancements to ConfigHeaderStep

Breaking API change to std.Build.addConfigHeader. It now uses an options
struct.

Introduce std.Build.CompileStep.installConfigHeader which also accepts
an options struct. This is used to add a generated config file into the
set of installed header files for a particular compilation artifact.

std.Build.ConfigHeaderStep now additionally supports a "blank" style
where a header is generated from scratch. It no longer exposes
`output_dir`. Instead it exposes a FileSource via `output_file`.
It now additionally accepts an `include_path` option which affects the
include path of CompileStep when using the `#include` directive, as well
as affecting the default installation subdirectory for header
installation purposes.

The hash used for the directory to store the generated config file now
includes the contents of the generated file. This fixes possible race
conditions when generating multiple header files simultaneously.

The values hash table is now an array hash map, to preserve order for
the "blank" use case.

I also took the opportunity to remove output_dir from TranslateCStep and
WriteFileStep. This is technically a breaking change, but it was always
naughty to access these fields.
This commit is contained in:
Andrew Kelley
2023-02-04 22:44:21 -07:00
parent b04e48566c
commit b29e3fa2cd
5 changed files with 181 additions and 158 deletions

View File

@@ -9,7 +9,6 @@ pub const base_id = .write_file;
step: Step,
builder: *std.Build,
output_dir: []const u8,
files: std.TailQueue(File),
pub const File = struct {
@@ -23,7 +22,6 @@ pub fn init(builder: *std.Build) WriteFileStep {
.builder = builder,
.step = Step.init(.write_file, "writefile", builder.allocator, make),
.files = .{},
.output_dir = undefined,
};
}
@@ -87,11 +85,11 @@ fn make(step: *Step) !void {
.{std.fmt.fmtSliceHexLower(&digest)},
) catch unreachable;
self.output_dir = try fs.path.join(self.builder.allocator, &[_][]const u8{
const output_dir = try fs.path.join(self.builder.allocator, &[_][]const u8{
self.builder.cache_root, "o", &hash_basename,
});
var dir = fs.cwd().makeOpenPath(self.output_dir, .{}) catch |err| {
std.debug.print("unable to make path {s}: {s}\n", .{ self.output_dir, @errorName(err) });
var dir = fs.cwd().makeOpenPath(output_dir, .{}) catch |err| {
std.debug.print("unable to make path {s}: {s}\n", .{ output_dir, @errorName(err) });
return err;
};
defer dir.close();
@@ -101,14 +99,14 @@ fn make(step: *Step) !void {
dir.writeFile(node.data.basename, node.data.bytes) catch |err| {
std.debug.print("unable to write {s} into {s}: {s}\n", .{
node.data.basename,
self.output_dir,
output_dir,
@errorName(err),
});
return err;
};
node.data.source.path = try fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir, node.data.basename },
&[_][]const u8{ output_dir, node.data.basename },
);
}
}