Finch/src/host.fch
Nexoniarz b53e0910d8 The compiler runs on Windows (and has seeds for macOS)
Windows: the compiler made from bootstrap/windows-x86_64.ll runs under Wine, compiles itself to the same IR, builds an
exe of itself, and every test program passes through it. It needed: Windows-sized unsigned long for libclang's unsaved
file, no 'cross' when Windows builds for Windows, --target passed to libclang (libclang.dll assumes MSVC), the MinGW
triple always in the IR, FINCH_LDFLAGS, .exe names and FINCH_LLVM_INCLUDE in bootstrap/build.sh, winseed.sh/winbuild.sh.
macOS: seeds for arm64 and x86-64 made with the 11.3 SDK; IR is accepted by clang, nothing has run on a Mac yet.
CI gets a windows and a macos job. UNTESTED on real Windows/macOS runners.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015f73FesGZGYPkmDvUcj6QX
2026-10-26 00:37:06 +01:00

83 lines
1.8 KiB
Text

// What differs between the systems the compiler itself runs on: how a command line is quoted and run,
// where temporary files go, making and removing files. This one is for Linux and macOS (name_windows.fch has
// the Windows one).
import "stdlib.h"
import "unistd.h"
import "clang-c/Index.h"
// libclang's description of a file that isn't on disk: its Length is C's `unsigned long`, which is 64 bits here
fn unsavedFile(str name, str contents) -> CXUnsavedFile {
return CXUnsavedFile(Filename: name.ptr, Contents: contents.ptr, Length: u64(contents.len))
}
fn quote(str a) -> str {
return "'" + a.replace("'", "'\\''") + "'"
}
// run a command line through the shell; its exit code
fn run(str cmd) -> int {
return shell(cmd)
}
fn nullDevice() -> str {
return "/dev/null"
}
// the folder for temporary files
fn tempDir() -> str {
t := getenv("TMPDIR")
if t.len > 0 {
if t.ends_with("/") {
return t.sub(0, t.len - 1)
}
return t
}
return "/tmp"
}
fn pathSeparator() -> str {
return ":"
}
fn pid() -> int {
return int(getpid())
}
// the folder the compiler was started in
fn cwd() -> str {
return getenv("PWD")
}
// where files that are made once and kept go
fn cacheDir() -> str {
x := getenv("XDG_CACHE_HOME")
if x.len > 0 {
return x + "/finch"
}
h := getenv("HOME")
if h.len > 0 {
return h + "/.cache/finch"
}
return tempDir() + "/finch-cache"
}
// the editor protocol is bytes, not text lines
fn binaryStdio() {
}
fn makeDirs(str path) {
shell("mkdir -p " + quote(path))
}
fn remove(str path) {
delete_file(path)
}
fn removeTree(str path) {
shell("rm -rf " + quote(path))
}
// move a file over another
fn move(str from, str to) {
shell("mv " + quote(from) + " " + quote(to))
}