From 0d64a0ff55e0d3dc468bce1beedfcc3309886dcc Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 4 Mar 2026 17:40:17 -0800 Subject: [PATCH] Configuration: serialize remaining CSourceFiles information --- lib/compiler/Maker/ScannedConfig.zig | 3 +- lib/compiler/configurer.zig | 34 +++++++++++----- lib/std/zig/Configuration.zig | 61 ++++++++++++++++++++++------ 3 files changed, 74 insertions(+), 24 deletions(-) diff --git a/lib/compiler/Maker/ScannedConfig.zig b/lib/compiler/Maker/ScannedConfig.zig index 1fae9762e6..3be476931a 100644 --- a/lib/compiler/Maker/ScannedConfig.zig +++ b/lib/compiler/Maker/ScannedConfig.zig @@ -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"), diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig index e8548d5aa9..d1178901ef 100644 --- a/lib/compiler/configurer.zig +++ b/lib/compiler/configurer.zig @@ -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); diff --git a/lib/std/zig/Configuration.zig b/lib/std/zig/Configuration.zig index a0d63a868d..f739dab11c 100644 --- a/lib/std/zig/Configuration.zig +++ b/lib/std/zig/Configuration.zig @@ -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;