← 文章 / 开源项目
Hacker News 7小时前 · 2026-08-03 17:45:29 · 0 阅读

Kakehashi:在 Linux ARM 上运行 macOS 二进制文件的实验性用户态翻译层

用户态 macOS ARM64 → Linux aarch64 翻译层(CLI 优先,无 JIT)。

在 Linux aarch64 上加载 Darwin Mach-O,映射一个独立的 libSystem,翻译 BSD 系统调用,并运行真实的客户程序(clang 探测、7-Zip 7zzcurl、线程)。

实时执行 Linux aarch64(裸机、虚拟机、Colima/Docker)
静态加载/检查 任意主机(包括 macOS)
设计参考 docs/

可运行内容

已在 Docker/ColimaUTM(Linux aarch64)上验证。安装一次即可:

cargo install kakehashi
# 或从代码检出安装:
cargo install --path crates/kh-cli --force

kh bottle ensure
kh install 7zip    # Darwin 7zz → 客户机 /usr/local/bin/7zz
kh install curl    # Darwin curl → 客户机 /usr/local/bin/curl

相对路径 -o / 归档路径相对于 kh 进程的主机当前工作目录解析(自行创建父目录,或依赖 O_CREAT 的自动创建目录功能)。通过 bottle,/Volumes/linux/… 桥接到主机根目录(/ → 主机 /)。

7-Zip (7zz)

# 版本/帮助
kh run 7zz --
kh run 7zz -- --help

# 创建归档(相对于当前工作目录)
kh run 7zz -- a demo.7z README.md
kh run 7zz -- t demo.7z
kh run 7zz -- l demo.7z
kh run 7zz -- x -o./out demo.7z

# 多线程压缩(正确性验证)
kh run 7zz -- a -t7z -m0=lzma2 -mx=5 -mmt=4 mt.7z README.md
kh run 7zz -- t mt.7z
# 预期:Everything is Ok,退出码 0

Docker 辅助脚本(产物位于主机 .tmp/kh-out/ 下):

./scripts/docker-7zz.sh --help
./scripts/docker-7zz.sh a /Volumes/linux/out/demo.7z /Volumes/linux/src/README.md
ls -lh .tmp/kh-out/demo.7z

KAKEHASHI_HYPERCALL=1 ./scripts/docker-7zz.sh a -t7z -m0=lzma2 -mx=5 -mmt=4 \
  /Volumes/linux/out/mt.7z /Volumes/linux/src/README.md
./scripts/docker-7zz.sh t /Volumes/linux/out/mt.7z

curl

# Banner (G1)
kh run curl -- --version

# HTTP GET → 文件 (G3 / G5)。如果 -o 指定的父目录不存在,会自动创建。
kh run curl -- -sS -o .tmp/kh-out/body http://example.com/
# 预期:退出码 0,约 559 字节,HTML 包含 "Example Domain"
wc -c .tmp/kh-out/body
head -c 80 .tmp/kh-out/body; echo

# HTTP 输出到标准输出
kh run curl -- -sS http://example.com/ | head -c 80; echo

# HTTPS GET (G4) — OpenSSL + 瓶装 CA(来自主机或 curl.se 下载)
kh run curl -- -sS -o .tmp/kh-out/https-body https://example.com/
wc -c .tmp/kh-out/https-body

# 负面测试:错误/自签名证书必须失败(返回码 ≠ 0)
kh run curl -- -sS -o /dev/null https://self-signed.badssl.com/; echo exit:$?

Docker 辅助工具:

./scripts/docker-curl.sh --version
./scripts/docker-curl.sh -sS -o /Volumes/linux/out/body http://example.com/
./scripts/docker-curl.sh -sS -o /Volumes/linux/out/https-body https://example.com/
ls -lh .tmp/kh-out/body .tmp/kh-out/https-body

# 首次追踪探针日志 → .tmp/kh-curl-probe/
./scripts/docker-curl-probe.sh --version

# 选项矩阵(大型层级)→ .tmp/kh-curl-options/
./scripts/docker-curl-options.sh tier1
./scripts/docker-curl-options.sh tier9-10
./scripts/docker-curl-options.sh all          # tier1..10

多次运行中无害的噪音:

  • kh: open fail ENOENT(openat) path=/etc/ssl/openssl.cnf — OpenSSL 可选配置;通过种子 CA 包,HTTP/HTTPS 仍可正常工作。
  • WARN … skip dylib … Security/CoreFoundation — 瓶装中不含 Apple 框架;软桩覆盖了加载路径。
  • unresolved strong symbol; bound to named missing trampoline — 正常路径中未命中的符号。

详情和关卡:docs/curl.md

其他通过项

测试面 备注
Clang / 固定探针 tests/clang-probe/tests/fixtures/
多线程 7zz -mmt=4 Docker + UTM
瓶装 + 独立 libSystem kh bottle ensure 嵌入 dylib
单元测试 + clippy cargo test / clippy 工作区(不含 kh-libsystem

尚未作为产品声明

完整的 curl 功能集(POST 请求体、代理、端到端 HTTP/3、所有协议), 真正的 Apple Security.framework,git / CLT,GUI,代码签名。下一个产品切片: 通过 kh install xcode-tools 安装 git — 详见 docs/git.md

Crates

Crate 角色
kakehashi 二进制文件 kh(安装此包)
kh-loader Mach-O 解析、映射、执行
kh-runtime 内存、陷阱、BSD 系统调用、bottle;内嵌独立的 libSystem.B.dylib
kh-libsystem 该 dylib 的源码(仅限 aarch64-apple-darwin;不是 Linux 宿主 crate)

客户 dylib 位于 crates/kh-runtime/resources/libSystem.B.dylib,通过 include_bytes! 编译进运行时。发布 kh-runtime 时会附带该 dylib;最终用户无需单独下载。

系统要求

  • Rust 1.88+
  • 运行 kh run / kh trace 需要 Linux aarch64
  • 页面大小:4 KiB(容器)和 16 KiB(Asahi 级别)
  • 可选:kh install 7zip / kh install curl 需要 curl/wget + tar

安装

cargo install kakehashi
# 或从检出目录安装:cargo install --path crates/kh-cli

kh bottle ensure
kh install 7zip
kh install curl

Bottle 目录结构

默认根目录:~/.local/share/kakehashi/bottle/(可通过 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(主机 CA 或下载的 Mozilla 证书)
…/Volumes/linux/… /Volumes/linux/… → 主机文件系统

性能(实话实说)

Kakehashi 在 CPU 上原生运行客户代码。性能开销来自系统调用边界(TLS 切换、备用栈、NEON 保存/恢复、Rust 调度),具体取决于客户程序的调用频率——它不是指令模拟器。

实测差距

在 Ubuntu aarch64 裸机(UTM)上,多文件 7zz 压缩(-t7z -m0=lzma2 -mx=5 -mmt=4,约 8k 文件 / 约 240 MiB 目录树):

原生 Linux 7zz Darwin 7zzkh 比例
实际时间 约 22.5 秒 约 118 秒 约 ×5.2

在压缩密集、文件数少的场景下,差距通常小得多(约 ×1.1–1.2)。多文件场景下的大差距主要来自路径遍历 + 每次系统调用的边界开销,而非“LZMA 算法错误”。

Hypercall 默认对所有客户线程开启。仅在调试时设置 KAKEHASHI_HYPERCALL=0 关闭(残留的 svcbrk / SIGTRAP)。

为什么 ×5 在 CI 中仍有价值

CI 的产品目标不是“和原生 macOS 一样快”,而是在廉价的 Linux aarch64 运行器上运行 Darwin CLI/工具,从而替代稀缺且昂贵的 macOS 资源。

GitHub Actions 托管运行器(私有仓库超额费率,美元/分钟;参见 Actions 运行器定价):

运行器 每分钟费率
Linux 2 核 arm64 $0.005
Linux 2 核 x64 $0.006
macOS 3–4 核(M1/Intel) $0.062
macOS 更大规格(如 12 核 / M2 Pro) $0.077–$0.102

macOS 的标准费率大约是 Linux arm64 每分钟计费的 ×10–×12 倍(不计实际耗时差异)。即使某个任务在 Linux arm64 上用 kh 运行比在 macOS runner 上慢 5 倍,计费成本仍可能更低,因为 macOS 每分钟的价格贵了一个数量级(举例:5 × $0.005 ≈ $0.025 对比 1 × $0.062)。公共仓库的免费分钟数和自托管 Linux 会进一步放大这一优势;macOS 托管容量也往往排队更久,并且在 GitLab SaaS 上受 Premium/Ultimate 或 beta 权限限制。

macOS runner 仍然胜出的场景: GUI、代码签名/公证、Xcode UI 测试,或任何无法在独立 libSystem 下作为纯 CLI Darwin 二进制运行的工作负载。

关注功能门,而非跑分: CI 正确性由 cargo test / 冒烟测试 / 7zz -mmt=4 验证,而不是“匹配原生时钟时间”。性能工作记录在 docs/roadmap.md 中。

快速开始(Apple Silicon 上的 Docker / Colima)

docker build -t kakehashi:dev -f Dockerfile.dev .
docker run --rm -v "$PWD":/src -w /src kakehashi:dev \
  cargo test --workspace --exclude kh-libsystem

# 完整冒烟测试(构建 + clippy + 测试 + 微运行)
./scripts/docker-smoke.sh

构建

cargo build -p kakehashi --release
cargo test --workspace --exclude kh-libsystem
cargo clippy --workspace --exclude kh-libsystem --all-targets -- -D warnings

# 维护者:在独立 ABI 变更后刷新嵌入内容
cargo build -p kh-libsystem --release --target aarch64-apple-darwin
./scripts/stage-libsystem.sh   # → crates/kh-runtime/resources/libSystem.B.dylib

libSystem 发现顺序:--libsystemKAKEHASHI_LIBSYSTEMkh 旁边的路径 → crate resources/kh-runtime 中的嵌入字节。

测试映射

目标 命令 产物
单元测试 cargo test --workspace --exclude kh-libsystem 终端输出
Docker 冒烟测试 ./scripts/docker-smoke.sh smoke ok 结束
测试夹具 kh run --expect-code … tests/fixtures/… 参见 tests/fixtures/README.md
Clang 探针 kh run --root tests/fixtures/bottle tests/clang-probe/puts_hello 标准输出 hello
真实 Darwin 7zz ./scripts/docker-7zz.sh … 宿主机 .tmp/kh-out/
真实 Darwin curl ./scripts/docker-curl.sh … 宿主机 .tmp/kh-out/;探针 → .tmp/kh-curl-probe/
公平 CPU 基准测试 ./scripts/bench-fair-local.sh 宿主机 .tmp/kh-bench-fair/

.tmp/.kh/target/ 已被 gitignore 忽略。

客户机路径 ↔ 宿主机路径(Docker 辅助工具)

Bottle 将 Linux 文件系统桥接为 /Volumes/linux/…

客户机路径 宿主机
/Volumes/linux/src/README.md <repo>/README.md
/Volumes/linux/out/demo.7z <repo>/.tmp/kh-out/demo.7z(持久化;docker-7zz.sh 的默认路径)
/Volumes/linux/tmp/… 容器 /tmp/… — 执行 docker run --rm 后**消失**

脚本

脚本 用途
scripts/stage-libsystem.sh 构建产物 → crates/kh-runtime/resources/
scripts/install-linux.sh 本地构建 + 安装 kh + bottle ensure
scripts/docker-smoke.sh Dockerfile 镜像内运行冒烟测试套件
scripts/docker-7zz.sh kh 下运行 Darwin 7zz(输出 → .tmp/kh-out
scripts/docker-curl.sh kh 下运行 Darwin curl(结构与 docker-7zz 相同)
scripts/docker-curl-probe.sh KH_CURL_PROBE=1 包装脚本(日志 → .tmp/kh-curl-probe
scripts/docker-curl-options.sh 分层 curl 参数冒烟测试(tier1tier10tier9-10all.tmp/kh-curl-options
scripts/docker-git.sh kh 下运行 CLT 中的 Apple git(swscan + .kh/data 缓存)
scripts/bench-fair-local.sh 原生 vs kh 压缩对比(产物 → .tmp/kh-bench-fair

许可证

Apache License 2.0。详见 LICENSE.txtNOTICE

本项目并非衍生自 Darling。请勿引入专有的 Apple SDK 或二进制 blob。

原始来源: Hacker News

评论 (0)