Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusing linker error when library specified by extern declaration is not found #19815

Open
sbancuz opened this issue Apr 30, 2024 · 5 comments
Labels
bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@sbancuz
Copy link

sbancuz commented Apr 30, 2024

Zig Version

0.12.0

Steps to Reproduce and Observed Behavior

I tried to use a function that's not accessible through the omp.h header ( or any other accessible header file for that matter ) that is declared here __kmpc_push_proc_bind(). I have rewritten in zig the function declaration, like when doing binary patching, and I get an error when using the self-hosted linker.

// repro.zig
pub fn main() void {
    var id = ident_t{ .psource = "" };
    __kmpc_push_proc_bind(&id, 0, 1); // This is just a random function that I picked, i behaves the same with other functions
}

// This isn't important, it's just to match as much as possible the function declaration of the original function
pub const ident_t = extern struct {
    reserved_1: c_int = 0,
    flags: c_int = 0,
    reserved_2: c_int = 0,
    reserved_3: c_int = 0x1a,
    psource: [*:0]const u8,
};

extern "C" fn __kmpc_push_proc_bind(loc: *ident_t, global_tid: c_int, proc_binds: c_int) void;

Command : zig build-exe repro.zig -fno-llvm -fno-lld -lc -lomp
Result:
error: unexpected error: parsing library failed with error FileNotFound
note: while parsing

Command : zig build-exe repro.zig -fllvm -fno-lld -lc -lomp
Result:
error: unexpected error: parsing library failed with error FileNotFound
note: while parsing

When using the llvm backend normally it compiles
Command : zig build-exe repro.zig -lc -lomp
Result: no error

This doesn't happen if I try to call a function using @cImport("omp.h");, like for example

const c = @cImport({
    @cInclude("omp.h");
});

pub fn main() void {
    c.omp_get_max_num_thread();
}

I haven't tested with other libraries if I can replicate the same result and this was tested with llvm version of openmp, not the gnu one.

Expected Behavior

They both compile.

@sbancuz sbancuz added the bug Observed behavior contradicts documented or intended behavior label Apr 30, 2024
@rohlem
Copy link
Contributor

rohlem commented Apr 30, 2024

I'm pretty sure the library name (after extern) is case sensitive, and the usual system c library uses lowercase, i.e. extern "c".
There's also the option of instead specifying the library name (f.e. extern "kernel32"),
so it seems pretty likely that Zig tries to look for a library named "C" instead of realizing you're talking about a system c library function.
That would also explain the FileNotFound error, because there's (probably) no library named "C" in any of the default or provided library search paths.

@Vexu Vexu added error message This issue points out an error message that is unhelpful and should be improved. and removed bug Observed behavior contradicts documented or intended behavior labels Apr 30, 2024
@Vexu Vexu added this to the 0.13.0 milestone Apr 30, 2024
@Vexu Vexu changed the title Linker error when linking a function directly with export "C" Confusing linker error when library specified by extern declaration is not found Apr 30, 2024
@sbancuz
Copy link
Author

sbancuz commented May 1, 2024

Don't know if it actually is case sensitive, but even if it were, the llvm backend wouldn't crash.

Regardless i tested with extern "c" all of the examples above and I get the same results.

@sbancuz
Copy link
Author

sbancuz commented May 1, 2024

@Vexu I think you may have misunderstood, it's a bug not a weird error message. This function declaration exists, you can call it and it works like any other function when using the LLVM backend.

It's just that when you use the self-hosted backend it doesn't compile giving this error message. But the expected behaviour should be that the program compiles and runs normally.

@Vexu
Copy link
Member

Vexu commented May 1, 2024

I was testing with a release build of Zig, when using a debug build it panics if the library is not specified on the command line. I am able to build it with the self-hosted backend when using extern "omp".

Stack trace

thread 274647 panic: attempt to use null value
/home/vexu/Documents/zig/zig/src/link/Elf.zig:1174:93: 0xa52b93a in flushModule (zig)
        system_libs.appendAssumeCapacity(.{ .needed = lib_info.needed, .path = lib_info.path.? });
                                                                                            ^
/home/vexu/Documents/zig/zig/src/link/Elf.zig:1072:25: 0xa1ee444 in flush (zig)
    try self.flushModule(arena, prog_node);
                        ^
/home/vexu/Documents/zig/zig/src/link.zig:566:77: 0x9f5a46d in flush (zig)
                return @as(*tag.Type(), @fieldParentPtr("base", base)).flush(arena, prog_node);
                                                                            ^
/home/vexu/Documents/zig/zig/src/Compilation.zig:2262:17: 0x9f59b0f in flush (zig)
        lf.flush(arena, prog_node) catch |err| switch (err) {
                ^
/home/vexu/Documents/zig/zig/src/Compilation.zig:2253:22: 0x9f5d63e in update (zig)
            try flush(comp, arena, main_progress_node);
                     ^
/home/vexu/Documents/zig/zig/src/main.zig:4483:24: 0x9f8da9f in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/vexu/Documents/zig/zig/src/main.zig:3405:17: 0x9ff63d2 in buildOutputType (zig)
    updateModule(comp, color) catch |err| switch (err) {
                ^

@Vexu Vexu added bug Observed behavior contradicts documented or intended behavior and removed error message This issue points out an error message that is unhelpful and should be improved. labels May 1, 2024
@sbancuz
Copy link
Author

sbancuz commented May 1, 2024

I tried it too with the 0.12.0 version but I'm getting different results. Using extern "omp" and building with zig build-exe repro.zig -fno-llvm -fno-lld -lc -lomp works.

I also tried to omit the library in the command line and it doesn't crash, but it gives the FileNotFound error, which I guess has to be expected since I told him not to look for libomp. Weirdly enough if I omit only -lc it compiles and if I omit both -lc and -lomp it gives me a nice error message

repro.zig:16:8: error: dependency on dynamic library 'omp' requires enabling Position Independent Code. Fixed by '-lomp' or '-fPIC'.
extern "omp" fn __kmpc_push_proc_bind(loc: *ident_t, global_tid: c_int, proc_binds: c_int) void;
       ^~~~~
referenced by:
    main: repro.zig:4:5
    callMain: /nix/store/ymq0w17q7vy4xf2phd74pqhsyfdmam3s-zig-0.12.0/lib/zig/std/start.zig:501:17
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

3 participants