zig icon indicating copy to clipboard operation
zig copied to clipboard

zig build doesn't notice the missing exe after lld-link fails

Open kcbanner opened this issue 1 year ago • 1 comments

Zig Version

0.11.0-dev.11+0d192ee9e

Steps to Reproduce and Observed Behavior

I noticed this as part of investigating the build issues on MSVC https://github.com/ziglang/zig/issues/12703#issuecomment-1299605706

When there is a linker error, zig build behaves incorrectly in two ways:

  • It still tries to copy the nonexistant exe from the cache to the output directory after a linker failure
  • On subsequent zig build runs, it does not try to relink the exe and still tries to copy the missing exe

Test case:

build.zig:

const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    const target = b.standardTargetOptions(.{});
    const mode = b.standardReleaseOptions();

    const exe = b.addExecutable("zig_link_problem", "src/main.zig");
    exe.setTarget(target);
    exe.setBuildMode(mode);
    exe.install();
}

src/main.zig:

const std = @import("std");

extern fn add(a: i32, b: i32) i32;

pub fn main() void {
    const result = add(1, 2);
    std.debug.print("add: {}", .{ result });
}

First run, hits the linker error (starting with no zig-cache):

C:\cygwin64\home\kcbanner\temp\zig_link_problem>zig build --verbose
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\zig.exe build-exe C:\cygwin64\home\kcbanner\temp\zig_link_problem\src\main.zig --cache-dir C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache --global-cache-dir C:\Users\kcbanner\AppData\Local\zig --name zig_link_problem --enable-cache
LLD Link... lld-link: error: undefined symbol: add
>>> referenced by C:\cygwin64\home\kcbanner\temp\zig_link_problem\src\main.zig:6
>>>               C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache\o\42c298dfef92d87a2a7f32b81df16c92\zig_link_problem.exe.obj:(main.main)
info: cp C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache\o\42c298dfef92d87a2a7f32b81df16c92\zig_link_problem.exe C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-out\bin\zig_link_problem.exe
error: FileNotFound
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\os\windows.zig:126:35: 0x7ff693bc1ce9 in OpenFile (build.exe.obj)
        .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
                                  ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\fs.zig:1224:23: 0x7ff693bc5383 in openFileW (build.exe.obj)
            .handle = try w.OpenFile(sub_path_w, .{
                      ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\fs.zig:1096:13: 0x7ff693ba2dce in openFile (build.exe.obj)
            return self.openFileW(path_w.span(), flags);
            ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\fs.zig:2532:24: 0x7ff693c279e2 in updateFile (build.exe.obj)
        var src_file = try source_dir.openFile(source_path, .{});
                       ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:1089:29: 0x7ff693c30edd in updateFile (build.exe.obj)
        const prev_status = try fs.Dir.updateFile(cwd, source_path, cwd, dest_path, .{});
                            ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:3417:9: 0x7ff693c174f2 in make (build.exe.obj)
        try builder.updateFile(self.artifact.getOutputSource().getPath(builder), full_dest_path);
        ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:3649:9: 0x7ff693b8e079 in make (build.exe.obj)
        try self.makeFn(self);
        ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:509:9: 0x7ff693b7c5bc in makeOneStep (build.exe.obj)
        try s.make();
        ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:503:17: 0x7ff693b7c535 in makeOneStep (build.exe.obj)
                return err;
                ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:464:13: 0x7ff693b7c288 in make (build.exe.obj)
            try self.makeOneStep(s);
            ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\build_runner.zig:223:21: 0x7ff693b7f1e0 in main (build.exe.obj)
            else => return err,
                    ^
error: the following build command failed with exit code 1:
C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache\o\3f57706d3ff6e63f50e1e9ab753dbf4f\build.exe E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\zig.exe C:\cygwin64\home\kcbanner\temp\zig_link_problem C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache C:\Users\kcbanner\AppData\Local\zig --verbose

Second run:

C:\cygwin64\home\kcbanner\temp\zig_link_problem>zig build --verbose
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\zig.exe build-exe C:\cygwin64\home\kcbanner\temp\zig_link_problem\src\main.zig --cache-dir C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache --global-cache-dir C:\Users\kcbanner\AppData\Local\zig --name zig_link_problem --enable-cache
info: cp C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache\o\42c298dfef92d87a2a7f32b81df16c92\zig_link_problem.exe C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-out\bin\zig_link_problem.exe
error: FileNotFound
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\os\windows.zig:126:35: 0x7ff689711ce9 in OpenFile (build.exe.obj)
        .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
                                  ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\fs.zig:1224:23: 0x7ff689715383 in openFileW (build.exe.obj)
            .handle = try w.OpenFile(sub_path_w, .{
                      ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\fs.zig:1096:13: 0x7ff6896f2dce in openFile (build.exe.obj)
            return self.openFileW(path_w.span(), flags);
            ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\fs.zig:2532:24: 0x7ff6897779e2 in updateFile (build.exe.obj)
        var src_file = try source_dir.openFile(source_path, .{});
                       ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:1089:29: 0x7ff689780edd in updateFile (build.exe.obj)
        const prev_status = try fs.Dir.updateFile(cwd, source_path, cwd, dest_path, .{});
                            ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:3417:9: 0x7ff6897674f2 in make (build.exe.obj)
        try builder.updateFile(self.artifact.getOutputSource().getPath(builder), full_dest_path);
        ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:3649:9: 0x7ff6896de079 in make (build.exe.obj)
        try self.makeFn(self);
        ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:509:9: 0x7ff6896cc5bc in makeOneStep (build.exe.obj)
        try s.make();
        ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:503:17: 0x7ff6896cc535 in makeOneStep (build.exe.obj)
                return err;
                ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\std\build.zig:464:13: 0x7ff6896cc288 in make (build.exe.obj)
            try self.makeOneStep(s);
            ^
E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\lib\build_runner.zig:223:21: 0x7ff6896cf1e0 in main (build.exe.obj)
            else => return err,
                    ^
error: the following build command failed with exit code 1:
C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache\o\3f57706d3ff6e63f50e1e9ab753dbf4f\build.exe E:\dev\zig-windows-x86_64-0.11.0-dev.11+0d192ee9e\zig.exe C:\cygwin64\home\kcbanner\temp\zig_link_problem C:\cygwin64\home\kcbanner\temp\zig_link_problem\zig-cache C:\Users\kcbanner\AppData\Local\zig --verbose

Expected Behavior

  1. The build exits after the linker failure, and doesn't try to copy missing artifacts - the file not found error is confusing if you aren't using --verbose.
  2. The build tries to re-link if the artifact is missing.

kcbanner avatar Nov 03 '22 17:11 kcbanner

Related #13235

jacobly0 avatar Nov 05 '22 02:11 jacobly0