Repository navigation
Stop forcing libc: direct system calls on Linux - #8
Merged
Merged
Conversation
The library module set link_libc, which made every consumer link a libc. src/sys.zig now provides the 17 POSIX calls the framework makes outside the Windows transport, with libc's signatures and errno convention: std.c when libc is linked (and on every system but Linux), direct std.os.linux system calls otherwise. failFast keeps _exit semantics: std.c._exit with libc, std.process.exit without (exit_group on Linux, no atexit handlers). The demo and the embedding example no longer link libc; macOS still links libSystem automatically. A Linux consumer now builds as one static executable with no interpreter and no dynamic section, for the native target, musl or none. The transport, server and sys tests also run without libc. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The library module set
.link_libc = true, so every consumer linked a libc even though the framework is pure Zig. Consumers such as omajot want one static Linux binary with no interpreter and no shared libraries.What
src/sys.zig: the 17 POSIX calls the framework makes outside the Windows transport (socket,setsockopt,bind,listen,getsockname,fcntl,close,connect,send,recv,poll,shutdown,pipe,read,write,clock_gettime,nanosleep) with libc's signatures and-1/errnoconvention. With libc linked (and on every OS but Linux) they arestd.c; on Linux without libc they are directstd.os.linuxsystem calls with a thread-local errno. Call sites inserver.zig,transport.zigandtransport_linux.zigchanged fromc.tosys.;transport_macos.zigkeepsstd.c(macOS always links libSystem).failFastkeeps_exitsemantics:std.c._exitwith libc, elsestd.process.exit, which in Zig 0.16 isexit_groupon Linux (RtlExitUserProcesson Windows) without atexit handlers or unwinding. With libc,std.process.exitwould callexit(3)and run atexit handlers, hence_exitthere.link_libc. The demo's stall usessys.nanosleep; the example's fatal path usesfailFast.transport.zig,server.zigandsys.zig(part ofverify).Evidence (exact Zig 0.16.0)
Linux (omarx1, io_uring), under the measurement lock:
zig build verify: 24/24 steps, 207/211 tests (4 skipped), incl. no-libc runs (transport 9, server 71 + 2 skipped, sys 1).x86_64-linux-muslandx86_64-linux-none:statically linked, noPT_INTERP, "There is no dynamic section in this file." The-linux-nonebinary servesHTTP/1.1 200 OKwith a correctDateheader (clock_gettimevia direct syscall).macOS (maxross, kqueue, native):
zig build verify18/18 steps, 124/128 tests (4 skipped); integration 30; continuation 24 groups;otool -Lshows onlylibSystem.B.dylib.Windows:
zig build check -Dtarget=x86_64-windows-gnuand a ReleaseSafe cross build pass here; native Windows runs in CI.🤖 Generated with Claude Code