authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-08 14:31:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:35-07:00
log7e6be7ee6ee4223a4ef2b247002358cbfc714854
tree4642a619dff8152d770a372177eb5a6f4bbeec90
parentf158262b30665b22c571373907a14f11eec809f7

configurer: serialize Step.ObjCopy


4 files changed, 120 insertions(+), 46 deletions(-)

lib/compiler/Maker/Step/ObjCopy.zig+1-3
...@@ -137,9 +137,7 @@ pub fn make(...@@ -137,9 +137,7 @@ pub fn make(
137 }137 }
138138
139 const f = update.flags.section_flags;139 const f = update.flags.section_flags;
140 const default_flags: Configuration.Step.ObjCopy.SectionFlags = .{};140 if (f != Configuration.Step.ObjCopy.SectionFlags.default) {
141
142 if (f != default_flags) {
143 // trailing comma is allowed141 // trailing comma is allowed
144 argv.appendAssumeCapacity("--set-section-flags");142 argv.appendAssumeCapacity("--set-section-flags");
145 argv.appendAssumeCapacity(try allocPrint(arena, "{s}={s}{s}{s}{s}{s}{s}{s}{s}{s}", .{143 argv.appendAssumeCapacity(try allocPrint(arena, "{s}={s}{s}{s}{s}{s}{s}{s}{s}{s}", .{
lib/compiler/configurer.zig+46-1
...@@ -1065,7 +1065,52 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -1065,7 +1065,52 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
1065 })));1065 })));
1066 },1066 },
1067 .config_header => @panic("TODO"),1067 .config_header => @panic("TODO"),
1068 .obj_copy => @panic("TODO"),1068 .obj_copy => e: {
1069 const oc: *Step.ObjCopy = @fieldParentPtr("step", step);
1070
1071 const debug_basename: ?Configuration.String = if (oc.debug_file) |df|
1072 df.basename.unwrap()
1073 else
1074 null;
1075
1076 const debug_file: ?Configuration.GeneratedFileIndex = if (oc.debug_file) |df|
1077 df.output_file
1078 else
1079 null;
1080
1081 const add_sections = try arena.alloc(
1082 Configuration.Step.ObjCopy.AddSection,
1083 oc.add_sections.items.len,
1084 );
1085 for (add_sections, oc.add_sections.items) |*dest, src| dest.* = .{
1086 .section_name = src.section_name,
1087 .file_path = try s.addLazyPath(src.file_path),
1088 };
1089
1090 break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.ObjCopy, .{
1091 .flags = .{
1092 .basename = oc.basename != .none,
1093 .debug_file = debug_file != null,
1094 .debug_basename = debug_basename != null,
1095 .format = .init(oc.format),
1096 .strip = oc.strip,
1097 .compress_debug = oc.compress_debug,
1098 .only_section = oc.only_section != .none,
1099 .pad_to = oc.pad_to != null,
1100 .add_section = add_sections.len != 0,
1101 .update_section = oc.update_sections.items.len != 0,
1102 },
1103 .input_file = try s.addLazyPath(oc.input_file),
1104 .output_file = oc.output_file,
1105 .basename = .{ .value = oc.basename.unwrap() },
1106 .debug_file = .{ .value = debug_file },
1107 .debug_basename = .{ .value = debug_basename },
1108 .only_section = .{ .value = oc.only_section.unwrap() },
1109 .pad_to = .{ .value = oc.pad_to },
1110 .add_section = .{ .slice = add_sections },
1111 .update_section = .{ .slice = oc.update_sections.items },
1112 })));
1113 },
1069 .options => e: {1114 .options => e: {
1070 const so: *Step.Options = @fieldParentPtr("step", step);1115 const so: *Step.Options = @fieldParentPtr("step", step);
10711116
lib/std/Build/Configuration.zig+7
...@@ -1170,6 +1170,8 @@ pub const Step = extern struct {...@@ -1170,6 +1170,8 @@ pub const Step = extern struct {
1170 merge: bool = false,1170 merge: bool = false,
1171 /// add SHF_STRINGS1171 /// add SHF_STRINGS
1172 strings: bool = false,1172 strings: bool = false,
1173
1174 pub const default: @This() = .{};
1173 };1175 };
11741176
1175 pub const Flags = packed struct(u32) {1177 pub const Flags = packed struct(u32) {
...@@ -1776,6 +1778,11 @@ pub const Alignment = enum(u6) {...@@ -1776,6 +1778,11 @@ pub const Alignment = enum(u6) {
1776 none = std.math.maxInt(u6),1778 none = std.math.maxInt(u6),
1777 _,1779 _,
17781780
1781 pub fn init(optional_alignment: ?std.mem.Alignment) @This() {
1782 const a = optional_alignment orelse return .none;
1783 return @enumFromInt(@intFromEnum(a));
1784 }
1785
1779 pub fn toBytes(a: @This()) ?u64 {1786 pub fn toBytes(a: @This()) ?u64 {
1780 return switch (a) {1787 return switch (a) {
1781 .none => null,1788 .none => null,
lib/std/Build/Step/ObjCopy.zig+66-42
...@@ -6,19 +6,18 @@ const Configuration = std.Build.Configuration;...@@ -6,19 +6,18 @@ const Configuration = std.Build.Configuration;
66
7step: Step,7step: Step,
8input_file: std.Build.LazyPath,8input_file: std.Build.LazyPath,
9basename: ?[]const u8,9basename: Configuration.OptionalString,
10output_file: Configuration.GeneratedFileIndex,10output_file: Configuration.GeneratedFileIndex,
11output_file_debug: Configuration.OptionalGeneratedFileIndex,11debug_file: ?DebugFile,
1212
13format: ?Format,13format: ?Format,
14only_section: ?[]const u8,14only_section: Configuration.OptionalString,
15pad_to: ?u64,15pad_to: ?u64,
16strip: Strip,16strip: Strip,
17compress_debug: bool,17compress_debug: bool,
1818
19add_section: ?AddSection,19add_sections: std.ArrayList(AddSection) = .empty,
20set_section_alignment: ?SetSectionAlignment,20update_sections: std.ArrayList(Configuration.Step.ObjCopy.UpdateSection) = .empty,
21set_section_flags: ?SetSectionFlags,
2221
23pub const base_tag: Step.Tag = .obj_copy;22pub const base_tag: Step.Tag = .obj_copy;
2423
...@@ -27,18 +26,13 @@ pub const Strip = Configuration.Step.ObjCopy.Strip;...@@ -27,18 +26,13 @@ pub const Strip = Configuration.Step.ObjCopy.Strip;
27pub const SectionFlags = Configuration.Step.ObjCopy.SectionFlags;26pub const SectionFlags = Configuration.Step.ObjCopy.SectionFlags;
2827
29pub const AddSection = struct {28pub const AddSection = struct {
30 section_name: []const u8,29 section_name: Configuration.String,
31 file_path: std.Build.LazyPath,30 file_path: std.Build.LazyPath,
32};31};
3332
34pub const SetSectionAlignment = struct {33pub const DebugFile = struct {
35 section_name: []const u8,34 basename: Configuration.OptionalString,
36 alignment: u32,35 output_file: Configuration.GeneratedFileIndex,
37};
38
39pub const SetSectionFlags = struct {
40 section_name: []const u8,
41 flags: SectionFlags,
42};36};
4337
44pub const Options = struct {38pub const Options = struct {
...@@ -53,50 +47,80 @@ pub const Options = struct {...@@ -53,50 +47,80 @@ pub const Options = struct {
53 /// Put the stripped out debug sections in a separate file.47 /// Put the stripped out debug sections in a separate file.
54 /// note: the `basename` is baked into the elf file to specify the link to the separate debug file.48 /// note: the `basename` is baked into the elf file to specify the link to the separate debug file.
55 /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html49 /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
56 extract_to_separate_file: bool = false,50 ///
51 /// Makes `getOutputSeparatedDebug` return non-null.
52 separate_debug_file: ?SeparateDebugFile = null,
5753
58 add_section: ?AddSection = null,54 pub const SeparateDebugFile = struct {
59 set_section_alignment: ?SetSectionAlignment = null,55 basename: ?[]const u8,
60 set_section_flags: ?SetSectionFlags = null,56 };
61};57};
6258
63pub fn create(59pub fn create(owner: *std.Build, input_file: std.Build.LazyPath, options: Options) *ObjCopy {
64 owner: *std.Build,
65 input_file: std.Build.LazyPath,
66 options: Options,
67) *ObjCopy {
68 const graph = owner.graph;60 const graph = owner.graph;
69 const obj_copy = graph.create(ObjCopy);61 const wc = &graph.wip_configuration;
70 obj_copy.* = .{62 const oc = graph.create(ObjCopy);
63 oc.* = .{
71 .step = .init(.{64 .step = .init(.{
72 .tag = base_tag,65 .tag = base_tag,
73 .name = owner.fmt("objcopy {f}", .{input_file.fmt(graph)}),66 .name = owner.fmt("objcopy {f}", .{input_file.fmt(graph)}),
74 .owner = owner,67 .owner = owner,
75 }),68 }),
76 .input_file = input_file,69 .input_file = input_file,
77 .basename = options.basename,70 .basename = if (options.basename) |s| .init(wc.addString(s) catch @panic("OOM")) else .none,
78 .output_file = graph.addGeneratedFile(&obj_copy.step),71 .output_file = graph.addGeneratedFile(&oc.step),
79 .output_file_debug = if (options.strip != .none and options.extract_to_separate_file)72 .debug_file = if (options.separate_debug_file) |df| .{
80 .init(graph.addGeneratedFile(&obj_copy.step))73 .basename = if (df.basename) |s| .init(wc.addString(s) catch @panic("OOM")) else .none,
81 else74 .output_file = graph.addGeneratedFile(&oc.step),
82 .none,75 } else null,
83 .format = options.format,76 .format = options.format,
84 .only_section = options.only_section,77 .only_section = if (options.only_section) |s| .init(wc.addString(s) catch @panic("OOM")) else .none,
85 .pad_to = options.pad_to,78 .pad_to = options.pad_to,
86 .strip = options.strip,79 .strip = options.strip,
87 .compress_debug = options.compress_debug,80 .compress_debug = options.compress_debug,
88 .add_section = options.add_section,
89 .set_section_alignment = options.set_section_alignment,
90 .set_section_flags = options.set_section_flags,
91 };81 };
92 input_file.addStepDependencies(&obj_copy.step);82 input_file.addStepDependencies(&oc.step);
93 return obj_copy;83 return oc;
84}
85
86pub const UpdateSectionOptions = struct {
87 alignment: ?std.mem.Alignment = null,
88 flags: SectionFlags = .default,
89};
90
91pub fn updateSection(oc: *ObjCopy, section_name: []const u8, options: UpdateSectionOptions) void {
92 const graph = oc.owner.graph;
93 const arena = graph.arena;
94 const wc = &graph.wip_configuration;
95 oc.update_sections.append(arena, .{
96 .flags = .{
97 .section_flags = options.flags,
98 .alignment = .init(options.alignment),
99 },
100 .section_name = wc.addString(section_name) catch @panic("OOM"),
101 }) catch @panic("OOM");
102}
103
104pub const AddSectionOptions = struct {
105 file_path: std.Build.LazyPath,
106};
107
108pub fn addSection(oc: *ObjCopy, section_name: []const u8, options: AddSectionOptions) void {
109 const graph = oc.owner.graph;
110 const arena = graph.arena;
111 const wc = &graph.wip_configuration;
112 oc.add_sections.append(arena, .{
113 .section_name = wc.addString(section_name) catch @panic("OOM"),
114 .file_path = options.file_path,
115 }) catch @panic("OOM");
116 options.file_path.addStepDependencies(&oc.step);
94}117}
95118
96pub fn getOutput(obj_copy: *const ObjCopy) std.Build.LazyPath {119pub fn getOutput(oc: *const ObjCopy) std.Build.LazyPath {
97 return .{ .generated = .{ .index = obj_copy.output_file } };120 return .{ .generated = .{ .index = oc.output_file } };
98}121}
99122
100pub fn getOutputSeparatedDebug(obj_copy: *const ObjCopy) ?std.Build.LazyPath {123pub fn getOutputSeparatedDebug(oc: *const ObjCopy) ?std.Build.LazyPath {
101 return if (obj_copy.output_file_debug.unwrap()) |index| .{ .generated = .{ .index = index } } else null;124 const df = oc.debug_file orelse return null;
125 return .{ .generated = .{ .index = df.output_file } };
102}126}