zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 7e6be7ee6ee4223a4ef2b247002358cbfc714854 (tree)
parent f158262b30665b22c571373907a14f11eec809f7
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Fri,  8 May 2026 14:31:37 -0700

configurer: serialize Step.ObjCopy

Diffstat:
Mlib/compiler/Maker/Step/ObjCopy.zig | 4+---
Mlib/compiler/configurer.zig | 47++++++++++++++++++++++++++++++++++++++++++++++-
Mlib/std/Build/Configuration.zig | 7+++++++
Mlib/std/Build/Step/ObjCopy.zig | 108++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
4 files changed, 120 insertions(+), 46 deletions(-)

diff --git a/lib/compiler/Maker/Step/ObjCopy.zig b/lib/compiler/Maker/Step/ObjCopy.zig @@ -137,9 +137,7 @@ pub fn make( } const f = update.flags.section_flags; - const default_flags: Configuration.Step.ObjCopy.SectionFlags = .{}; - - if (f != default_flags) { + if (f != Configuration.Step.ObjCopy.SectionFlags.default) { // trailing comma is allowed argv.appendAssumeCapacity("--set-section-flags"); argv.appendAssumeCapacity(try allocPrint(arena, "{s}={s}{s}{s}{s}{s}{s}{s}{s}{s}", .{ diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig @@ -1065,7 +1065,52 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { }))); }, .config_header => @panic("TODO"), - .obj_copy => @panic("TODO"), + .obj_copy => e: { + const oc: *Step.ObjCopy = @fieldParentPtr("step", step); + + const debug_basename: ?Configuration.String = if (oc.debug_file) |df| + df.basename.unwrap() + else + null; + + const debug_file: ?Configuration.GeneratedFileIndex = if (oc.debug_file) |df| + df.output_file + else + null; + + const add_sections = try arena.alloc( + Configuration.Step.ObjCopy.AddSection, + oc.add_sections.items.len, + ); + for (add_sections, oc.add_sections.items) |*dest, src| dest.* = .{ + .section_name = src.section_name, + .file_path = try s.addLazyPath(src.file_path), + }; + + break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.ObjCopy, .{ + .flags = .{ + .basename = oc.basename != .none, + .debug_file = debug_file != null, + .debug_basename = debug_basename != null, + .format = .init(oc.format), + .strip = oc.strip, + .compress_debug = oc.compress_debug, + .only_section = oc.only_section != .none, + .pad_to = oc.pad_to != null, + .add_section = add_sections.len != 0, + .update_section = oc.update_sections.items.len != 0, + }, + .input_file = try s.addLazyPath(oc.input_file), + .output_file = oc.output_file, + .basename = .{ .value = oc.basename.unwrap() }, + .debug_file = .{ .value = debug_file }, + .debug_basename = .{ .value = debug_basename }, + .only_section = .{ .value = oc.only_section.unwrap() }, + .pad_to = .{ .value = oc.pad_to }, + .add_section = .{ .slice = add_sections }, + .update_section = .{ .slice = oc.update_sections.items }, + }))); + }, .options => e: { const so: *Step.Options = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig @@ -1170,6 +1170,8 @@ pub const Step = extern struct { merge: bool = false, /// add SHF_STRINGS strings: bool = false, + + pub const default: @This() = .{}; }; pub const Flags = packed struct(u32) { @@ -1776,6 +1778,11 @@ pub const Alignment = enum(u6) { none = std.math.maxInt(u6), _, + pub fn init(optional_alignment: ?std.mem.Alignment) @This() { + const a = optional_alignment orelse return .none; + return @enumFromInt(@intFromEnum(a)); + } + pub fn toBytes(a: @This()) ?u64 { return switch (a) { .none => null, diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig @@ -6,19 +6,18 @@ const Configuration = std.Build.Configuration; step: Step, input_file: std.Build.LazyPath, -basename: ?[]const u8, +basename: Configuration.OptionalString, output_file: Configuration.GeneratedFileIndex, -output_file_debug: Configuration.OptionalGeneratedFileIndex, +debug_file: ?DebugFile, format: ?Format, -only_section: ?[]const u8, +only_section: Configuration.OptionalString, pad_to: ?u64, strip: Strip, compress_debug: bool, -add_section: ?AddSection, -set_section_alignment: ?SetSectionAlignment, -set_section_flags: ?SetSectionFlags, +add_sections: std.ArrayList(AddSection) = .empty, +update_sections: std.ArrayList(Configuration.Step.ObjCopy.UpdateSection) = .empty, pub const base_tag: Step.Tag = .obj_copy; @@ -27,18 +26,13 @@ pub const Strip = Configuration.Step.ObjCopy.Strip; pub const SectionFlags = Configuration.Step.ObjCopy.SectionFlags; pub const AddSection = struct { - section_name: []const u8, + section_name: Configuration.String, file_path: std.Build.LazyPath, }; -pub const SetSectionAlignment = struct { - section_name: []const u8, - alignment: u32, -}; - -pub const SetSectionFlags = struct { - section_name: []const u8, - flags: SectionFlags, +pub const DebugFile = struct { + basename: Configuration.OptionalString, + output_file: Configuration.GeneratedFileIndex, }; pub const Options = struct { @@ -53,50 +47,80 @@ pub const Options = struct { /// Put the stripped out debug sections in a separate file. /// note: the `basename` is baked into the elf file to specify the link to the separate debug file. /// see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html - extract_to_separate_file: bool = false, + /// + /// Makes `getOutputSeparatedDebug` return non-null. + separate_debug_file: ?SeparateDebugFile = null, - add_section: ?AddSection = null, - set_section_alignment: ?SetSectionAlignment = null, - set_section_flags: ?SetSectionFlags = null, + pub const SeparateDebugFile = struct { + basename: ?[]const u8, + }; }; -pub fn create( - owner: *std.Build, - input_file: std.Build.LazyPath, - options: Options, -) *ObjCopy { +pub fn create(owner: *std.Build, input_file: std.Build.LazyPath, options: Options) *ObjCopy { const graph = owner.graph; - const obj_copy = graph.create(ObjCopy); - obj_copy.* = .{ + const wc = &graph.wip_configuration; + const oc = graph.create(ObjCopy); + oc.* = .{ .step = .init(.{ .tag = base_tag, .name = owner.fmt("objcopy {f}", .{input_file.fmt(graph)}), .owner = owner, }), .input_file = input_file, - .basename = options.basename, - .output_file = graph.addGeneratedFile(&obj_copy.step), - .output_file_debug = if (options.strip != .none and options.extract_to_separate_file) - .init(graph.addGeneratedFile(&obj_copy.step)) - else - .none, + .basename = if (options.basename) |s| .init(wc.addString(s) catch @panic("OOM")) else .none, + .output_file = graph.addGeneratedFile(&oc.step), + .debug_file = if (options.separate_debug_file) |df| .{ + .basename = if (df.basename) |s| .init(wc.addString(s) catch @panic("OOM")) else .none, + .output_file = graph.addGeneratedFile(&oc.step), + } else null, .format = options.format, - .only_section = options.only_section, + .only_section = if (options.only_section) |s| .init(wc.addString(s) catch @panic("OOM")) else .none, .pad_to = options.pad_to, .strip = options.strip, .compress_debug = options.compress_debug, - .add_section = options.add_section, - .set_section_alignment = options.set_section_alignment, - .set_section_flags = options.set_section_flags, }; - input_file.addStepDependencies(&obj_copy.step); - return obj_copy; + input_file.addStepDependencies(&oc.step); + return oc; +} + +pub const UpdateSectionOptions = struct { + alignment: ?std.mem.Alignment = null, + flags: SectionFlags = .default, +}; + +pub fn updateSection(oc: *ObjCopy, section_name: []const u8, options: UpdateSectionOptions) void { + const graph = oc.owner.graph; + const arena = graph.arena; + const wc = &graph.wip_configuration; + oc.update_sections.append(arena, .{ + .flags = .{ + .section_flags = options.flags, + .alignment = .init(options.alignment), + }, + .section_name = wc.addString(section_name) catch @panic("OOM"), + }) catch @panic("OOM"); +} + +pub const AddSectionOptions = struct { + file_path: std.Build.LazyPath, +}; + +pub fn addSection(oc: *ObjCopy, section_name: []const u8, options: AddSectionOptions) void { + const graph = oc.owner.graph; + const arena = graph.arena; + const wc = &graph.wip_configuration; + oc.add_sections.append(arena, .{ + .section_name = wc.addString(section_name) catch @panic("OOM"), + .file_path = options.file_path, + }) catch @panic("OOM"); + options.file_path.addStepDependencies(&oc.step); } -pub fn getOutput(obj_copy: *const ObjCopy) std.Build.LazyPath { - return .{ .generated = .{ .index = obj_copy.output_file } }; +pub fn getOutput(oc: *const ObjCopy) std.Build.LazyPath { + return .{ .generated = .{ .index = oc.output_file } }; } -pub fn getOutputSeparatedDebug(obj_copy: *const ObjCopy) ?std.Build.LazyPath { - return if (obj_copy.output_file_debug.unwrap()) |index| .{ .generated = .{ .index = index } } else null; +pub fn getOutputSeparatedDebug(oc: *const ObjCopy) ?std.Build.LazyPath { + const df = oc.debug_file orelse return null; + return .{ .generated = .{ .index = df.output_file } }; }