Zig, Libc and SysCalls

What is the relationship between Zig and C libraries (libc, glibc, musl-libc etc) and direct sys calls on different Oses?

Do zig always use a C library?

If so what determines the C library Zig uses?

Can I override the default C library Zig uses?

Can I force Zig to not use any C library and only go things via Sys calls?

By default zig will not link the C standard library.
All of the code inside the Zig standard library uses direct syscalls.

You can link the C standard library by passing -lc to the command or using .linkLibC() inside the build.zig.

The C library is determined by the target as far as I know. So if you target x86_64-linux-gnu it will use glibc. If you target x86_64-linux-musl it will use musl libc. You can change the target either from the command -Dtarget=... or inside of the build.zig file.

5 Likes

I think I read somewhere that by default, on MacOs, Zig uses libc.

How would one confirm this?

To look at target specific defaults you can use:

zig build-exe -target aarch64-macos --show-builtin > builtin.zig

Here we find:

pub const link_libc = true;
4 Likes

Yes I confirmed link_libc = true

So I guess this confirms that by default on MacOs, direct syscalls are not used but libc is used instead.

Outside of Linux, most operating systems don’t guarantee a stable system call ABI for making system calls directly through the assembly instruction. They intend for you to use the OS userspace libraries (e.g. libc or the various windows libraries) to make system calls.

3 Likes

This is correct, but I encourage you to use the build.zig version, .linkLibC(). There are changes in the pipeline to separate out the LLVM and C-compiling parts of Zig, and that version is more likely to survive those changes intact.

2 Likes