Show HN: Kakehashi – Linux ARM で macOS バイナリを実行するための実験的なユーザースペース

2026/08/03 1:26

Show HN: Kakehashi – Linux ARM で macOS バイナリを実行するための実験的なユーザースペース

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Kakehashi は、JIT コンパイルや Apple の専用 SDK に依存せず、Linux aarch64 上で実際の macOS ARM64 ゲストを実行するためのオープンソースで CLI ファーストのユーザースペース翻訳層です。中心となるクリート(

kh-loader
kh-runtime
、埋め込まれた
libSystem.B.dylib
)を中心に構成され、システムコールを翻訳するとともに、ゲストのファイルシステムをホストに
/Volumes/linux/…
を介して橋渡しします。具体的には、ゲストの
/usr/local/bin
をホストのバイナリに、
/etc/ssl/cert.pem
を CA バンドルにマッピングします。インストールは
cargo install kakehashi
(ソース:
crates/kh-cli
)で行い、事前に
kh bottle ensure
でボトルを確保します。ツールの追加は
kh install
、実行は
kh run
によって行われます(例:マルチスレッド圧縮用の
kh run 7zz -- -mmt=4
や、単に
kh run curl --
など)。Linux aarch64 ベアメタル、VM、Docker/Colima(ヘルパーがアーティファクトを
.tmp/kh-out/
に出力)上で動作し、Rust 1.88 以上(Linux aarch64)、コンテナの種類に応じて 4 KiB または 16 KiB のページサイズに対応します。ベンチマークの結果では、Linux 側のマルチファイル 7-Zip 圧縮とネイティブ実行を比較した場合の全実行数のギャップは約 5.2 倍ですが、単一ファイルまたは圧縮負荷の重いワークロードではオーバーヘッドは約 1.1〜1.2 倍に留まります。Darwin クライアントツールを高価な macOS ランナー($0.062〜$0.102/分)ではなく、低価格な Linux ARM64 ランナー($0.005/分)上で実行できるため、パフォーマンスのオーバーヘッドがあっても Kakehashi は多くの場合で費用対効果に優れています。Apache 2.0 ライセンスの下にあり、Darling から派生していない本ツールは、自動化された CLI ワークフローのためにエコシステムを橋渡しする無料の代替手段を提供します。

本文

Userspace macOS ARM64 → Linux aarch64 トランスレーションレイヤー

Linux aarch64 アーキテクチャ上で Darwin Mach-O ビナリを実行し、自立型の

libSystem
をマッピングして BSD システムコールを翻訳することで、実際のゲスト環境(
clang probes
,
7-Zip 7zz
,
curl
, スレッドなど)を動作させます。

概要

  • 実行中の処理 (Live execution):
    • Linux aarch64(ベアメタル、VM、Colima/Docker など)
  • 読み込み/検査のみ (Dry-load / inspect):
    • 任意のホスト(macOS を含む)
  • 設計参照:
    docs/

動作確認済み機能

Docker/Colima および UTM (Linux aarch64) 環境で検証済み。一度インストールするだけで以下が利用可能です。

cargo install kakehashi
# またはチェックアウトしたリポジトリから:
cargo install --path crates/kh-cli --force

ボトル(Bottle)の管理

kh bottle ensure

ゲストアプリのインストール

kh install 7zip    # Darwin の 7zz → ゲスト環境 /usr/local/bin/7zz
kh install curl    # Darwin の curl → ゲスト環境 /usr/local/bin/curl

注意: 相対パス

-o
とアーカイブのパスは、
kh
プロセスが実行されているホストの現在作業ディレクトリ(CWD)に対して解決されます。親ディレクトリを独自に作成するか、
O_CREAT
の自動作成機能を利用してください。

  • ボトルを通じて、
    /Volumes/linux/…
    はホストのルートディレクトリにブリッジされ、**
    / → /host
    **となります。

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

マルチスレッド圧縮の検証(正しさゲート)

# マルチスレッドで圧縮する (-mmt=4)
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/
下にアサート物が生成されます。 Hypercall はデフォルトで有効です(
KAKEHASHI_HYPERCALL=1
)。

./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

# Hypercall 有効状態での圧縮テスト
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 の使用方法

バナー表示 (G1)

kh run curl -- --version

HTTP GET → ファイルへ保存 (G3 / G5)

親ディレクトリが存在しない場合は自動作成されます。

  • 期待される動作: 終了コード 0、約 559 バイト、HTML が "Example Domain" を含む。
# ファイルへの保存
kh run curl -- -sS -o .tmp/kh-out/body http://example.com/
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 + Bottle CA

ホストまたは

curl.se
からダウンロードして使用します。

kh run curl -- -sS -o .tmp/kh-out/https-body https://example.com/
wc -c .tmp/kh-out/https-body

負のケース:不正な証明書

失敗する必要があります(

rc ≠ 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 のオプション構成ファイル;HTTP/HTTPS はシードされた CA バンドルを通じて引き続き動作します。
  • WARN … skip dylib … Security/CoreFoundation
    — ボトルに含まれていない Apple フレームワーク;ロードパスをカバーするための**ソフトステブ(スタブライブラリ)**が機能します。
  • unresolved strong symbol; bound to named missing trampoline
    — ハッピーパス(正常な場合)では触られないシンボルです。

詳細とゲート:

docs/curl.md
を参照してください。


プロジェクト構造と検証ゲート (Gates)

表面層 (Surface)備考
Clang / フィキスチャープローブ
tests/clang-probe/
,
tests/fixtures/
マルチスレッド 7zz -mmt=4Docker および UTM で検証済み
ボトル + 自立型 libSystem
kh bottle ensure
を使用して dylib を埋め込みます
単体テスト + clippyワークスペース全体でのテスト(
kh-libsystem
は除外)

まだ製品としての保証ではありません

  • curl の完全な機能セット(POST ボディ、プロキシ、HTTP/3 全体エンドツーエンド、全てのスキームなど)。
  • 本物の Apple Security.framework
  • 含まれていないもの: git / CLT (Command Line Tools)、GUI アプリ、codesign など。
  • 次の製品スライス:
    kh install xcode-tools
    を用いた
    git
    — 詳細は
    docs/git.md
    を参照。

ライブラリ(Crates)一覧

Crateロール
kakehashiバイナリ
kh
(これをインストールする)
kh-loaderMach-O のパース、マッピング、実行
kh-runtimeメモリ管理、トラップ処理、BSD システムコール、ボトル機能;自立型
libSystem.B.dylib
を埋め込みます
kh-libsystemその dylib のソースコード(aarch64-apple-darwin 用のみで、Linux ホスト用の Crate ではありません)

ゲスト用 dylib は

crates/kh-runtime/resources/libSystem.B.dylib
にベンダリングされ、コンパイル時に
include_bytes!
を使用して runtime に組み込まれます。
kh-runtime
を公開すると dylib が含まれるため、エンドユーザーは別途ダウンロードする必要はありません。


要件事項

  • Rust: 1.88 以上
  • ホスト: 実機実行 (
    kh run
    ) /
    kh trace
    には Linux aarch64が必要です
  • ページサイズ: コンテナ用 4 KiB、Asahi クラス機器用 16 KiB
  • オプション:
    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

ボトルのレイアウト

  • デフォルトルート:
    ~/.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 CA)
…/Volumes/linux/…
/Volumes/linux/… → ホスト FS

パフォーマンスに関する正直な評価

Kakehashi はゲストコードを CPU でネイティブに実行します。課税されるのはシステムコール境界(TLS 切り替え、別スタック、NEON の保存/復元、Rust デスパッチなど)であり、ゲストがどれだけ頻繁にその境界を渡るかによって変動します。命令セットエミュレーターではありません

測定結果のギャップ

Ubuntu aarch64 ベアメタル(UTM)環境において、複数ファイルを対象とした 7zz アーカイブ(

-t7z -m0=lzma2 -mx=5 -mmt=4
、約 8k ファイル / 約 240 MiB ツリー)の場合:

メトリックネイティブ Linux 7zzkh 下の Darwin 7zzレーシオ
Wall time (実時間)~22.5 s~118 s~×5.2
  • 圧縮負荷が高くファイル数が少ないサンプルでは、ギャップははるかに小さくなることが多い (~×1.1–1.2)。
  • 大規模なマルチファイルのギャップは、「間違った LZMA アルゴリズム」によるものではなく、パスウォークと各システムコール境界のコストが支配的です。
  • Hypercall はデフォルトで全てのゲストスレッドに対して有効です。デバッグ用のみ
    KAKEHASHI_HYPERCALL=0
    で無効化してください(残存する
    svc→brk
    /
    SIGTRAP
    など)。

なぜ約×5 の遅さでも CI では有用なのか

CI における本製品の目標は「ネイティブ macOS と同じ速さ」ではなく、稀少かつ高価な macOS リソースの代わりに、安価な Linux aarch64 ランナー上で Darwin CLI ツールを実行することです。

GitHub 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 ランナー上で行った場合と比較して約×5 遅いとしても、請求されるコストは依然として低くなる可能性があります(例:

5 × $0.005 ≈ $0.025
vs
1 × $0.062
)。

  • macOS ランナーが優位になるケース: GUI アプリ、codesign/notarization、Xcode UI テスト、または自立型 libSystem 下の純粋な CLI Darwin バイナリではないワークロード。
  • ゲート(Gates)としての位置づけ: CI の正しさは
    cargo test
    / Smoke テスト /
    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 の探索順序

  1. --libsystem
    オプション
  2. 環境変数
    KAKEHASHI_LIBSYSTEM
  3. kh
    の隣にあるパス
  4. Crate の resources/ ディレクトリ
  5. kh-runtime
    に埋め込まれたバイト列

テストマッピング

ゴールコマンドアサート物 (Artifacts)
単体テスト
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 補助スクリプト)

ボトルは Linux FS を

/Volumes/linux/…
としてブリッジします:

ゲストパスホストパス
/Volumes/linux/src/README.md
<repo>/README.md
/Volumes/linux/out/demo.7z
<repo>/.tmp/kh-out/demo.7z
(永続的;デフォルト出力先)
/Volumes/linux/tmp/…
コンテナ内の
/tmp/…
docker run --rm
で消失します

スクリプト参照表

スクリプト目的
scripts/stage-libsystem.sh
製品ビルド →
crates/kh-runtime/resources/
scripts/install-linux.sh
ローカルビルド + kh インストール + ボトル確保
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 フラグスモーク(tier1…tier10、tier9-10、all →
.tmp/kh-curl-options
scripts/docker-git.sh
CLT 下の Apple git(kh 経由で動作;
swscan
+
.kh/data
キャッシュ)
scripts/bench-fair-local.sh
ネイティブ vs kh 圧縮ベンチマーク(アサート物 →
.tmp/kh-bench-fair

ライセンス

Apache License 2.0。

LICENSE.txt
および
NOTICE
を参照してください。

免責事項: このプロジェクトは Darling から派生したものではありません。プロプライエタリな Apple SDK や blobs をベンダリングしないでください。

同じ日のほかのニュース

一覧に戻る →

2026/07/28 23:21

メモTaking とパーソナルナレッジ管理

## Japanese Translation: 本稿の主要な論旨は、ブレンnan ケネス・ブラウンの記事に対し、ノートツール「Obsidian」に独自の知的価値を誤って帰属させ、不均衡な見解を示していることを批判しています。著者は、ソフトウェアが整理を助けることは事実だが、画期的なアイデアそのものの源泉ではないと主張します。証拠によると、ブラウンは Obsidian が複雑なシステムであるかのように誤って描写しており、実際には 1994 年頃の技術に準じるような個人的なウィキとして機能しています。この分析では、PARA やニコラス・ルーマンが使用した歴史的なゼッテルkasten メソッドなど、確立された枠組みを参照して議論の文脈を設定し、そのようなツールは人間の創造性を置き換えるのではなくそれを支援するに過ぎないと指摘します。さらに、Obsidian のダウンロード数が約 75 万回に達しているにもかかわらず、それは 460 億ドル規模の巨大な業界内で運営されており、その現在の影響は限定的であることを示唆しています。この批判は、世界を変えるような貢献を直接ソフトウェアに帰属させることは誤った結論と不確実な引用につながることを警告しています。結局のところ、ユーザーはこのツールを独自性の源泉ではなく、個人的な解決策のための基盤として認識するべきです。 ## Text to translate: The central argument critiques Brennan Kenneth Brown's article for presenting an unbalanced view that wrongly attributes unique intellectual value to the note-taking tool Obsidian. The author asserts that while software facilitates organization, it is not the source of groundbreaking ideas itself. Evidence shows Brown mischaracterizes Obsidian as a complex system when it functions essentially as a personal Wiki, comparable to technologies from 1994. This analysis contextualizes the debate by referencing established frameworks like PARA and the historical Zettelkasten method used by Niklas Luhmann, noting that such tools merely support human creativity rather than replacing it. Furthermore, despite Obsidian having roughly 750,000 downloads, it operates within a vast $46 billion industry, suggesting its current impact is limited. The critique warns that attributing world-changing contributions directly to the software leads to flawed conclusions and inconclusive citations. Ultimately, users should recognize these tools as foundations for personal solutions rather than engines of original thought.

2026/08/03 5:26

FamilyWild を用いたホスト間の X11 サーバー共有

## Japanese Translation: 2026 年 8 月 2 日、隔離環境(コンテナや chroots など)内または非転送された SSH 接続上でグラフィカルな X11 アプリケーションを動作させる際に生じる「Authorization required, but no authorization protocol specified」というエラーを解決するための方法が詳述されました。根本原因は、`.Xauthority` クッキーが family と hostname の双方で鍵付けされており、クライアントが自分のマシン名と一致しない hostname を持つクッキーを拒絶する点にあります。 解決策は、クッキーの family フィールドの最初の 2 バイトを `0100`(`FamilyLocal`)から `0xffff`(`FamilyWild`)に書き換えることです。これには以下のコマンドを使用します:`xauth nlist :0 | sed 's/^..../ffff/' | xauth -f /tmp/portable.Xauthority nmerge -`(`:0` を `$DISPLAY` に置き換えてください)。family を `FamilyWild` に変更することで、クッキーは任意の hostname に対して有効となり、hostname が不一致のクライアントからの接続も可能になりつつ、ホストベースのアクセス制御を完全に無効にすることなく済みます。 これを使用するには、生成された `/tmp/portable.Xauthority` ファイルを bind-mount または SCP でクライアント環境に移動し、`$XAUTHORITY` 変数を指すように設定します。ただし、厳格なセキュリティ上の注意が必要です:`FamilyWild` クッキーはローカルなものよりも特定の情報が少ないため、ソケットアクセスがありファイルを閲覧できるあらゆるユーザーが表示器に接続できるようになります。そのため、ファイルのパーミッションは必ず 0600 を維持し共有マシンにはコピーを残すべきではありません。このアプローチは、ホストベースのセキュリティを完全に無効にする `xhost +` の使用や、全クッキーをクリアしつつ無効なエントリを残そうとする危険な方法よりも優先されます。著者はこのトリックを、特別に非特権 LXC コンテナへの X11 転送のために適用しています。

2026/08/03 4:42

私の個人的な AI ベンチマーク:「ハプスブルク顎を持つカエルの SVG を生成する」

## 日本語訳: AI モデルは、未検証のコンテンツを追加することで元の画像を著しく歪ませました。これには、「Royal Imperial Collar(ロイヤル・イマペリアル・コラー)」や「Imperial Habsburg Crown(インペリアル・ハプスブルク・クラウン)」といった発明された王室の称号、さらに気分に関する編集者の注釈である「Folded Pompously(堂々と折りたたまれた様子)」や「gloomy expression(憂うつな表情)」などが含まれます。システムは、顔の特徴を医療的または王朝的な特性として位置付ける具体的な解剖学的記述を追加しました。例えば、「弱ったマキラー(弱い上顎)」「Habsburg lethargic look(ハプスブルク型の眠気のような様子)」「protruding mandible(突出した下顎)」、いわゆる「Classic Habsburg Feature(クラシック・ハプスブルク特徴)」などが挙げられます。生成された出力に含まれる技術的な詳細では、肌のグラデーションのために「frogSkin」などの例が定義され、巨大な顎、垂れかけた瞼、カエルのような Wart(疣)といった具体的な特徴を描画するために正確な座標が使用されます。その結果、利用者は、事実に基づかない複雑な歴史的背景または臨床的な特性を強いることで、被写体の属性を誤って表現する幻覚的な物語に充満した視覚コンテンツを受け取ることになります。

Show HN: Kakehashi – Linux ARM で macOS バイナリを実行するための実験的なユーザースペース | そっか~ニュース