Configuration: serialize remaining CSourceFiles information

This commit is contained in:
Andrew Kelley 2026-03-04 17:40:17 -08:00
parent f320c56a74
commit 0d64a0ff55
3 changed files with 74 additions and 24 deletions

View file

@ -103,6 +103,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi
.enum_optional => comptime unreachable,
.union_list => comptime unreachable,
.length_prefixed_list => comptime unreachable,
.flag_list => comptime unreachable,
.flag_union => comptime unreachable,
.multi_list => comptime unreachable,
} else if (std.enums.tagName(Field, field_value)) |name| {
@ -128,7 +129,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi
try s.value(null, .{});
}
},
.length_prefixed_list, .flag_length_prefixed_list => {
.length_prefixed_list, .flag_length_prefixed_list, .flag_list => {
try printValue(sc, s, @TypeOf(field_value.slice), field_value.slice);
},
.extended => @compileError("TODO"),

View file

@ -308,40 +308,54 @@ const Serialize = struct {
}
fn addCSourceFile(s: *Serialize, csf: *const std.Build.Module.CSourceFile) !Configuration.CSourceFile.Index {
log.err("TODO addCSourceFile trailing data", .{});
const wc = s.wc;
const args = try initStringList(s, csf.flags);
return @enumFromInt(try wc.addExtra(@as(Configuration.CSourceFile, .{
.flags = .{
.args_len = @intCast(csf.flags.len),
.args_len = @intCast(args.len),
.lang = .init(csf.language),
},
.file = try addLazyPath(s, csf.file),
.args = .{ .slice = args },
})));
}
fn addCSourceFiles(s: *Serialize, csf: *const std.Build.Module.CSourceFiles) !Configuration.CSourceFiles.Index {
log.err("TODO addCSourceFiles trailing data", .{});
const wc = s.wc;
const sub_paths = try initStringList(s, csf.files);
const args = try initStringList(s, csf.flags);
return @enumFromInt(try wc.addExtra(@as(Configuration.CSourceFiles, .{
.flags = .{
.args_len = @intCast(csf.flags.len),
.args_len = @intCast(args.len),
.lang = .init(csf.language),
},
.root = try addLazyPath(s, csf.root),
.files_len = @intCast(csf.files.len),
.sub_paths = .{ .slice = sub_paths },
.args = .{ .slice = args },
})));
}
fn addRcSourceFile(s: *Serialize, rsf: *const std.Build.Module.RcSourceFile) !Configuration.RcSourceFile.Index {
log.err("TODO addRcSourceFile trailing data", .{});
const wc = s.wc;
const include_paths = try initLazyPathList(s, rsf.include_paths);
const args = try initStringList(s, rsf.flags);
return @enumFromInt(try wc.addExtra(@as(Configuration.RcSourceFile, .{
.flags = .{
.args_len = @intCast(args.len),
.include_paths = include_paths.len != 0,
},
.file = try addLazyPath(s, rsf.file),
.args_len = @intCast(rsf.flags.len),
.include_paths_len = @intCast(rsf.include_paths.len),
.include_paths = .{ .slice = include_paths },
.args = .{ .slice = args },
})));
}
fn initLazyPathList(s: *Serialize, list: []const std.Build.LazyPath) ![]const Configuration.LazyPath {
const result = try s.arena.alloc(Configuration.LazyPath, list.len);
for (result, list) |*dest, src| dest.* = try addLazyPath(s, src);
return result;
}
fn initStringList(s: *Serialize, list: []const []const u8) ![]const Configuration.String {
const wc = s.wc;
const result = try s.arena.alloc(Configuration.String, list.len);
@ -400,9 +414,7 @@ const Serialize = struct {
.name = try wc.addString(name),
};
const lib_paths = try arena.alloc(Configuration.LazyPath, m.lib_paths.items.len);
for (lib_paths, m.lib_paths.items) |*dest, src| dest.* = try addLazyPath(s, src);
const lib_paths = try initLazyPathList(s, m.lib_paths.items);
const c_macros = try initStringList(s, m.c_macros.items);
const export_symbol_names = try initStringList(s, m.export_symbol_names);

View file

@ -1388,13 +1388,11 @@ pub const SystemLib = struct {
pub const SearchStrategy = enum(u2) { paths_first, mode_first, no_fallback };
};
/// Trailing:
/// * arg: String, // for each args_len
/// * sub_path: String, // for each files_len
pub const CSourceFiles = struct {
flags: Flags,
root: LazyPath,
files_len: u32,
args: Storage.FlagList(.flags, .args_len, String),
sub_paths: Storage.LengthPrefixedList(String),
pub const Index = enum(u32) {
_,
@ -1407,11 +1405,10 @@ pub const CSourceFiles = struct {
};
};
/// Trailing:
/// * arg: String, // for each args_len
pub const CSourceFile = struct {
flags: Flags,
file: LazyPath,
args: Storage.FlagList(.flags, .args_len, String),
pub const Index = enum(u32) {
_,
@ -1424,17 +1421,21 @@ pub const CSourceFile = struct {
};
};
/// Trailing:
/// * arg: String, // for each args_len
/// * include_path: String, // for each include_paths_len
pub const RcSourceFile = struct {
flags: Flags,
file: LazyPath,
args_len: u32,
include_paths_len: u32,
args: Storage.FlagList(.flags, .args_len, String),
include_paths: Storage.FlagLengthPrefixedList(.flags, .include_paths, LazyPath),
pub const Index = enum(u32) {
_,
};
pub const Flags = packed struct(u32) {
/// C compiler CLI flags.
args_len: u31,
include_paths: bool,
};
};
pub const OptionalCSourceLanguage = enum(u3) {
@ -1779,6 +1780,7 @@ pub const Storage = enum {
union_list,
flag_union,
multi_list,
flag_list,
/// The presence of the field is determined by a boolean within a packed
/// struct.
@ -1887,6 +1889,26 @@ pub const Storage = enum {
};
}
/// The field is a list whose length is an integer inside flags.
pub fn FlagList(
comptime flags_arg: @EnumLiteral(),
comptime flag_arg: @EnumLiteral(),
comptime ElemArg: type,
) type {
return struct {
slice: []const Elem,
pub const storage: Storage = .flag_list;
pub const flags = flags_arg;
pub const flag = flag_arg;
pub const Elem = ElemArg;
pub fn initErased(s: []const u32) @This() {
return .{ .slice = @ptrCast(s) };
}
};
}
/// The field contains a u32 length followed by that many items for the
/// first field, that many items for the second field, etc.
pub fn MultiList(comptime ElemArg: type) type {
@ -2059,6 +2081,13 @@ pub const Storage = enum {
defer i.* = data_start + len;
return .{ .slice = @ptrCast(buffer[data_start..][0..len]) };
},
.flag_list => {
const flags = @field(container, @tagName(Field.flags));
const len: u32 = @field(flags, @tagName(Field.flag));
const data_start = i.*;
defer i.* = data_start + len;
return .{ .slice = @ptrCast(buffer[data_start..][0..len]) };
},
.multi_list => {
const data_start = i.* + 1;
const len = buffer[data_start - 1];
@ -2122,7 +2151,10 @@ pub const Storage = enum {
},
.auto => switch (Field.storage) {
.flag_optional, .enum_optional, .extended => 1,
.length_prefixed_list, .flag_length_prefixed_list => 1 + @divExact(@sizeOf(Field.Elem), @sizeOf(u32)) * field.slice.len,
.length_prefixed_list,
.flag_length_prefixed_list,
.flag_list,
=> 1 + @divExact(@sizeOf(Field.Elem), @sizeOf(u32)) * field.slice.len,
.multi_list => 1 + field.mal.len * @typeInfo(Field.Elem).@"struct".fields.len,
.union_list => Field.extraLen(field.len),
.flag_union => switch (field.u) {
@ -2195,6 +2227,11 @@ pub const Storage = enum {
@memcpy(buffer[i + 1 ..][0..len], @as([]const u32, @ptrCast(value.slice)));
return len + 1;
},
.flag_list => {
const len: u32 = @intCast(value.slice.len);
@memcpy(buffer[i..][0..len], @as([]const u32, @ptrCast(value.slice)));
return len;
},
.multi_list => {
const len: u32 = @intCast(value.mal.len);
if (len == 0) return 0;