feat(dist): bundled-zig link backend for hermetic macOS/Linux/Windows builds
Drive a bundled `zig` as `zig cc` for the AOT link step, supplying lld + CRT + libc (musl/glibc/mingw) so `sx build` produces native binaries with no host toolchain. Default Linux output is static musl (portable-anywhere). - src/zig_backend.zig: discover zig ($SX_ZIG / bundled-next-to-exe / PATH); bundled-vs-PATH provenance gates auto-activation. - src/target.zig: selectZigLinker + emitZigLinkArgv + zigTargetTriple, dispatched before the per-OS branches; macOS/Linux/Windows in scope. - src/ir/emit_llvm.zig: LLVMNormalizeTargetTriple so vendor-less zig triples (e.g. x86_64-windows-gnu) parse to the correct OS/object format (COFF not ELF). - src/main.zig: --self-contained / --no-self-contained; linux-musl, linux-musl-arm, windows-gnu shorthands; de-vendor linux/linux-arm to match the corpus runner. - examples/1660: Windows Win32 print-42 + exit(0) via kernel32 (ir-only off-Windows). Auto-activates only for a bundled zig; a PATH-only zig engages under --self-contained, so native dev/CI builds are never silently rerouted. Docs: readme Cross-Compilation, design/bundled-zig-link-backend-design.md, current/PLAN-DIST.md.
This commit is contained in:
29
examples/1660-platform-windows-win32-print.sx
Normal file
29
examples/1660-platform-windows-win32-print.sx
Normal file
@@ -0,0 +1,29 @@
|
||||
// Windows x86_64 — print "42" and exit(0) through the Win32 system-call
|
||||
// boundary. The Windows analog of the Linux raw-`syscall` write (see
|
||||
// 1651): Windows has no stable raw syscall ABI (NtWriteFile's ordinal
|
||||
// shifts between OS builds), so the documented boundary IS kernel32 —
|
||||
// `GetStdHandle` + `WriteFile` to print, `ExitProcess` to terminate.
|
||||
//
|
||||
// Exercises the bundled-`zig` link backend end to end: built with
|
||||
// `--target windows-gnu --self-contained`, zig cc (mingw) auto-resolves
|
||||
// kernel32, producing a PE32+ that prints "42\n" and exits 0.
|
||||
//
|
||||
// Pinned `x86_64-windows-gnu` via `.build`: ir-only on this non-Windows
|
||||
// host (the `.ir` snapshot locks the Win64-ABI lowering of the three
|
||||
// extern calls); runs end-to-end on a Windows x86_64 runner.
|
||||
|
||||
kernel32 :: #library "kernel32";
|
||||
|
||||
// DWORD = u32, HANDLE/LPVOID = *void, BOOL = i32.
|
||||
GetStdHandle :: (n_std_handle: u32) -> *void extern;
|
||||
WriteFile :: (file: *void, buf: *u8, n: u32, written: *u32, overlapped: *void) -> i32 extern;
|
||||
ExitProcess :: (code: u32) -> void extern;
|
||||
|
||||
main :: () {
|
||||
// STD_OUTPUT_HANDLE = (DWORD)-11 = 0xFFFFFFF5.
|
||||
out := GetStdHandle(0xFFFFFFF5);
|
||||
msg : [3]u8 = .[52, 50, 10]; // "42\n"
|
||||
written : u32 = 0;
|
||||
WriteFile(out, @msg[0], 3, @written, null);
|
||||
ExitProcess(0);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{ "target": "x86_64-windows-gnu" }
|
||||
1
examples/expected/1660-platform-windows-win32-print.exit
Normal file
1
examples/expected/1660-platform-windows-win32-print.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
26
examples/expected/1660-platform-windows-win32-print.ir
Normal file
26
examples/expected/1660-platform-windows-win32-print.ir
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @GetStdHandle(i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @WriteFile(ptr, ptr, i32, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @ExitProcess(i32) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%call = call ptr @GetStdHandle(i32 -11)
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %call, ptr %alloca, align 8
|
||||
%allocaN = alloca [3 x i8], align 1
|
||||
store [3 x i8] c"42\0A", ptr %allocaN, align 1
|
||||
%allocaN = alloca i32, align 4
|
||||
store i32 0, ptr %allocaN, align 4
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%igp.ptr = getelementptr i8, ptr %allocaN, i64 0
|
||||
%callN = call i32 @WriteFile(ptr %load, ptr %igp.ptr, i32 3, ptr %allocaN, ptr null)
|
||||
call void @ExitProcess(i32 0)
|
||||
ret i32 0
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
42
|
||||
Reference in New Issue
Block a user