zig

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

commit c698e55754748fa9e97fed4fe279c604d3b381cd (tree)
parent f60fe4dcb667cc638f4f8ea8fb20d11de3440671
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date:   Wed, 27 May 2026 16:28:52 +0100

Compilation: don't update C inputs on incremental updates

...at least, for now, so that the use case of performing incremental
updates to the *Zig* source code works without crashing the linker.
This works around https://codeberg.org/ziglang/zig/issues/32081.

Diffstat:
Msrc/Compilation.zig | 20++++++++++++++++----
Msrc/link.zig | 3+++
2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/Compilation.zig b/src/Compilation.zig @@ -3008,10 +3008,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE // For compiling C objects, we rely on the cache hash system to avoid duplicating work. // Add a Job for each C object. - try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_object_table.count()); - for (comp.c_object_table.keys()) |c_object| { - comp.c_object_work_queue.pushBackAssumeCapacity(c_object); - try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path})); + if (comp.bin_file != null and comp.bin_file.?.post_prelink) { + assert(comp.config.incremental); + // TODO: this indicates that we are using incremental compilation and this is not the first + // incremental update. The incremental linkers do not (currently?) support updating C inputs + // incrementally. The frontend needs to learn to trigger a full rebuild if a C link input + // changes. For now, to avoid crashing the linker in this case, don't kick off C object + // updates if we've done prelink already. https://codeberg.org/ziglang/zig/issues/32081 + } else { + try comp.c_object_work_queue.ensureUnusedCapacity(gpa, comp.c_object_table.count()); + for (comp.c_object_table.keys()) |c_object| { + comp.c_object_work_queue.pushBackAssumeCapacity(c_object); + try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path})); + } } for (comp.link_inputs) |input| if (input.path()) |path| { @@ -7595,6 +7604,9 @@ pub fn queuePrelinkTaskMode(comp: *Compilation, path: Cache.Path, must_link: boo /// Only valid to call during `update`. pub fn queuePrelinkTasks(comp: *Compilation, tasks: []const link.PrelinkTask) Io.Cancelable!void { + if (tasks.len > 0) { + if (comp.bin_file) |lf| assert(!lf.post_prelink); + } comp.link_prog_node.increaseEstimatedTotalItems(tasks.len); try comp.link_queue.enqueuePrelink(comp, tasks); } diff --git a/src/link.zig b/src/link.zig @@ -1205,6 +1205,7 @@ pub const File = struct { pub fn loadInput(base: *File, input: Input) anyerror!void { if (base.tag == .lld) return; + assert(!base.post_prelink); switch (base.tag) { inline .elf, .elf2, .wasm => |tag| { dev.check(tag.devFeature()); @@ -1424,6 +1425,8 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { return; }; + assert(!base.post_prelink); + var timer = comp.startTimer(); defer if (timer.finish(io)) |ns| { comp.mutex.lockUncancelable(io);