Userspace macOS ARM64 → Linux aarch64 translator furniture (CLI-first, nary JIT).
Load Darwin Mach-O connected Linux aarch64, representation a freestanding libSystem, translate BSD syscalls, and tally existent guests (clang probes, 7-Zip 7zz, curl, threads).
| Live execution | Linux aarch64 (bare metal, VM, Colima/Docker) |
| Dry-load / inspect | Any big (including macOS) |
| Design reference | docs/ |
Verified connected Docker/Colima and UTM (Linux aarch64). Install once:
Relative -o / archive paths resoluteness against the host CWD of the kh process (create genitor dirs yourself, aliases trust connected auto-mkdir for O_CREAT). Through the bottle, /Volumes/linux/… bridges to the big guidelines (/ → big /).
Docker helpers (artifacts nether big .tmp/kh-out/):
Docker helpers:
Harmless sound connected galore runs:
- kh: unfastened neglect ENOENT(openat) path=/etc/ssl/openssl.cnf — OpenSSL optional config; HTTP/HTTPS still activity via the seeded CA bundle.
- WARN … skip dylib … Security/CoreFoundation — Apple frameworks not successful the bottle; soft stubs screen the load path.
- unresolved beardown symbol; bound to named missing trampoline — symbols not deed connected the happy path.
Details and gates: docs/curl.md.
| Clang / fixture probes | tests/clang-probe/, tests/fixtures/ |
| Multi-thread 7zz -mmt=4 | Docker + UTM |
| Bottle + freestanding libSystem | kh vessel guarantee embeds dylib |
| Unit tests + clippy | cargo trial / clippy workspace (excl. kh-libsystem) |
Not a merchandise declare (yet)
Full curl characteristic group (POST bodies, proxies, HTTP/3 end-to-end, each scheme), real Apple Security.framework, git / CLT, GUI, codesign. Next merchandise slice: git via kh instal xcode-tools — spot docs/git.md.
| kakehashi | Binary kh (install this) |
| kh-loader | Mach-O parse, map, execute |
| kh-runtime | Memory, traps, BSD syscalls, bottle; embeds freestanding libSystem.B.dylib |
| kh-libsystem | Source for that dylib (aarch64-apple-darwin only; not a Linux big crate) |
The impermanent dylib is vendored astatine crates/kh-runtime/resources/libSystem.B.dylib and compiled into the runtime pinch include_bytes!. Publishing kh-runtime ships the dylib; extremity users do not request a abstracted download.
- Rust 1.88+
- Linux aarch64 for unrecorded kh tally / kh trace
- Page sizes: 4 KiB (containers) and 16 KiB (Asahi-class)
- Optional: curl/wget + tar for kh instal 7zip / kh instal curl
Default root: ~/.local/share/kakehashi/bottle/ (override with KAKEHASHI_DATA_DIR / KAKEHASHI_ROOT).
| …/bottle/ | / |
| …/usr/local/bin/7zz | /usr/local/bin/7zz |
| …/usr/local/bin/curl | /usr/local/bin/curl |
| …/usr/lib/libSystem.B.dylib | /usr/lib/libSystem.B.dylib |
| …/private/etc/ssl/cert.pem | /etc/ssl/cert.pem (host CA aliases downloaded Mozilla) |
| …/Volumes/linux/… | /Volumes/linux/… → big FS |
Kakehashi runs impermanent codification natively connected the CPU. The taxation is the syscall boundary (TLS switch, alt stack, NEON save/restore, Rust dispatch) × how chatty the impermanent is — not an instruction emulator.
On Ubuntu aarch64 bare-metal (UTM), multi-file 7zz archive (-t7z -m0=lzma2 -mx=5 -mmt=4, ~8k files / ~240 MiB tree):
| wall | ~22.5 s | ~118 s | ~×5.2 |
On compression-heavy, few-file samples the spread is often overmuch smaller (~×1.1–1.2). The ample multi-file spread is dominated by path locomotion + per-syscall boundary, not “wrong LZMA”.
Hypercall is connected by default for each impermanent threads. Opt retired with KAKEHASHI_HYPERCALL=0 only for debug (residual svc→brk / SIGTRAP).
Why ~×5 is still useful successful CI
The merchandise extremity for CI is not “as accelerated arsenic autochthonal macOS,” but run Darwin CLI/tools connected inexpensive Linux aarch64 runners alternatively of scarce, expensive macOS capacity.
GitHub Actions hosted runners (private-repo overage rates, USD per minute; spot Actions runner pricing):
| Linux 2-core arm64 | $0.005 |
| Linux 2-core x64 | $0.006 |
| macOS 3–4 halfway (M1/Intel) | $0.062 |
| macOS larger (e.g. 12-core / M2 Pro) | $0.077–$0.102 |
macOS modular is astir ×10–×12 the Linux arm64 infinitesimal complaint earlier any wall-time difference. Even if a occupation runs ×5 slower nether kh connected Linux arm64 than the aforesaid activity connected a macOS runner, billable costs tin still beryllium lower because the macOS infinitesimal is an bid of magnitude much expensive (illustrative: 5 × $0.005 ≈ $0.025 vs 1 × $0.062). Public-repo free minutes and self-hosted Linux amplify that further; macOS hosted capacity besides tends to queue longer and (on GitLab SaaS) is Premium/Ultimate / beta-gated.
When macOS runners still win: GUI, codesign/notarization, Xcode UI tests, or immoderate workload that is not a axenic CLI Darwin binary nether freestanding libSystem.
Gates, not benches: CI correctness is cargo trial / fume / 7zz -mmt=4, not “match autochthonal wall clock.” Perf activity is tracked in docs/roadmap.md.
Quick commencement (Docker / Colima connected Apple Silicon)
libSystem discovery: --libsystem → KAKEHASHI_LIBSYSTEM → paths adjacent to kh → crate resources/ → embedded bytes successful kh-runtime.
| Unit tests | cargo trial --workspace --exclude kh-libsystem | terminal |
| Docker smoke | ./scripts/docker-smoke.sh | ends pinch fume ok |
| Fixtures | kh tally --expect-code … tests/fixtures/… | see tests/fixtures/README.md |
| Clang probes | kh tally --root tests/fixtures/bottle tests/clang-probe/puts_hello | stdout hello |
| Real Darwin 7zz | ./scripts/docker-7zz.sh … | host .tmp/kh-out/ |
| Real Darwin curl | ./scripts/docker-curl.sh … | host .tmp/kh-out/; probe → .tmp/kh-curl-probe/ |
| Fair CPU bench | ./scripts/bench-fair-local.sh | host .tmp/kh-bench-fair/ |
.tmp/, .kh/, and target/ are gitignored.
Guest way ↔ big way (Docker helpers)
Bottle bridges the Linux FS arsenic /Volumes/linux/…:
| /Volumes/linux/src/README.md | <repo>/README.md |
| /Volumes/linux/out/demo.7z | <repo>/.tmp/kh-out/demo.7z (durable; default for docker-7zz.sh) |
| /Volumes/linux/tmp/… | container /tmp/… — gone aft docker tally --rm |
| scripts/stage-libsystem.sh | Build merchandise → crates/kh-runtime/resources/ |
| scripts/install-linux.sh | Local build + instal kh + vessel ensure |
| scripts/docker-smoke.sh | Smoke suite wrong Dockerfile image |
| scripts/docker-7zz.sh | Darwin 7zz nether kh (outputs → .tmp/kh-out) |
| scripts/docker-curl.sh | Darwin curl nether kh (same style arsenic docker-7zz) |
| scripts/docker-curl-probe.sh | KH_CURL_PROBE=1 wrapper (logs → .tmp/kh-curl-probe) |
| scripts/docker-curl-options.sh | Tiered curl emblem fume (tier1…tier10, tier9-10, each → .tmp/kh-curl-options) |
| scripts/docker-git.sh | Apple git from CLT nether kh (swscan + .kh/data cache) |
| scripts/bench-fair-local.sh | Native vs kh compress (artifacts → .tmp/kh-bench-fair) |
Apache License 2.0. See LICENSE.txt and NOTICE.
This task is not derived from Darling. Do not vendor proprietary Apple SDKs aliases blobs.
English (US) ·
Indonesian (ID) ·