Closed ityonemo closed 1 day ago
Probably the documenation (#1596) should be finished first. Just curious: Is identifying manually the header files, which dont depend on libc, that difficult?
Yeah, it gets tricky (but not impossible) if you want cross-compilation to be possible.
As a workaround, use musl.
Appaerntly, if you don't link to libc, but just have some -I
entry, it works?
Here's my "C" library with a header file which doesn't really depend on libc at runtime:
λ bat mylib.h
#include <stdint.h>
int64_t get_number();
λ bat mylib.zig
export fn get_number() u64 {
return 92;
}
λ zig build-lib mylib.zig
Here's the Zig code which imports the header
λ bat main.zig
const std = @import("std");
const c = @cImport(@cInclude("./mylib.h"));
pub fn main() void {
std.debug.print("{}", .{c.get_number()});
}
If I just try to compile it, I get the error I expect to get given this issue:
λ zig build-exe main.zig libmylib.a.o
main.zig:2:11: error: C import failed
const c = @cImport(@cInclude("./mylib.h"));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.zig:2:11: note: libc headers not available; compilation does not link against libc
That is: no cImport if you don't link libc!
But, if I add -I
for my header, this somehow gets it to work!
λ zig build-exe main.zig libmylib.a.o -I. && ./main
92
λ ldd ./main
not a dynamic executable
Notably, not only Zig is able to find my mylib.h
, but internal clang is able to find <stdint.h>
. looking at --verbose-cimport
, it seems that it uses the correct stint.h:
λ bat /home/matklad/tmp/.zig-cache/o/e4d0a93094219ef8a9216d4c64d1b94a/cimport.h.d
cimport.o: \
/home/matklad/tmp/.zig-cache/o/e4d0a93094219ef8a9216d4c64d1b94a/cimport.h \
mylib.h /home/matklad/p/tb/work/zig/lib/include/stdint.h
So it looks like this might have been mostly fixed as of Zig 0.13, and only the error message needs to be adjusted: it's not about libc
headers, it's about the parcitular header you try to cImport
EDIT: further investigation shows that <stdint.h>
works, but <stdio.h>
doesn't (it fails with libc headers not available
). This seems precisely the behavior we want here, but I am very puzzled about how this could work, I thought that C headers don't make distinction between "this is a stand-alone headers" and "this requires a c runtime library"?
Expected to be solved by #20630
For FFIs which use C ABI as a least common denominator, but I'm sure also some header-only C libraries, may not use any stdlib externs, but might still need accoutrements of the C stdlib headers (e.g. types.h). It might be nice to provide a way to leverage zig's header resolution logic without doing
linkSystemLibrary("c")
which would unnecessarily bring in libc into the project.