--target: windows, linux, arm64, macos or a triple, in the compiler written in Finch

Targets, the target's C compiler (FINCH_CC) for linking, C import for the target (--target to libclang, its
headers), the AAPCS64 and Microsoft x64 ways of passing structs by value (and the System V one),
dllexport for libraries on Windows, .exe names, and running the program through wine or qemu-aarch64.
std/ gets time_windows.fch and proc_windows.fch: a module has a version per system (name_windows.fch,
name_macos.fch, name_linux.fch) that wins over name.fch. stdin, stdout and stderr work where C makes them macros.

Run for real: all 27 programs under tests/run and tests/new pass on ARM64 Linux under qemu and on Windows
under Wine (MinGW), structs by value and callbacks included. macOS is only checked as far as clang accepts the
IR; there is no emulator for it here.
This commit is contained in:
Nexoniarz 2026-10-25 21:33:19 +01:00
commit 750eca3e85
10 changed files with 426 additions and 52 deletions

View file

@ -99,10 +99,10 @@ fn fixed(ast.Type elem, int count) -> ast.Type {
// ---------- the system's header folders ----------
// Ask the system C compiler where it looks for headers, so we find the same stdio.h it would.
fn systemIncludeArgs() -> []str {
fn systemIncludeArgs(str cc) -> []str {
[]str dirs
tmp := "/tmp/finch_cc_dirs.txt"
shell("cc -E -v -x c /dev/null 2> '" + tmp + "' > /dev/null")
shell(cc + " -E -v -x c /dev/null 2> '" + tmp + "' > /dev/null")
if !file_exists(tmp) {
return dirs
}
@ -504,16 +504,23 @@ fn visit(ptr[Importer] imp, CXCursor c) {
}
// Read every header in `headers`; `dirs` are searched first for "local.h" headers.
fn importHeaders([]Header headers, []str dirs) -> CImports! {
// `target` is the LLVM triple the program is built for ("" = this system): sizes and headers depend on it.
fn importHeaders([]Header headers, []str dirs, str target, bool windows, str ccFor) -> CImports! {
imp := Importer()
if headers.len == 0 {
return imp.out
}
[]str args = ["-x", "c", "-std=gnu11"]
if target.len > 0 {
args.push("--target=" + target)
}
if windows {
args.push("-D_USE_MATH_DEFINES") // M_PI and friends, as on Linux
}
for d in dirs {
args.push("-I" + d)
}
for d in systemIncludeArgs() {
for d in systemIncludeArgs(ccFor) {
args.push(d)
}
[]ptr[char] argv