I’m using the Zig toolchain to cross-compile a Rust project. To guarantee ABI compatibility, I need to obtain the exact libc headers that come with Zig for a specific target. I currently do this by running:
zig libc -includes -target aarch64-linux-gnu
Then I use those include paths with bindgen to generate FFI bindings.
However, there’s a problem:
When I disable system paths using -nostdinc and rely solely on Zig’s include paths, bindgen fails with:
unknown type name 'size_t'
Apparently, Zig’s stddef.h does not define size_t as expected, and I’m not sure what the correct way to include it is.
Have you encountered this issue before?
Do you know a better way to ensure ABI-correct bindings using Zig’s libc?
After some investigation, it appears that glibc expects each C compiler to provide freestanding headers (stddef.h, stdarg.h, etc) that conform to its requirements. So stddef.h doesn’t exist in any of the directories output from that zig libc command when the target is gnu. The LLVM freestanding headers (along with many other headers) are provided in the Zig lib/include directory, not in one of the lib/libc/include/... directories.
Musl, on the other hand, appears to provide its own freestanding headers. I don’t know any of the history here…