世界を動かす技術を、日本語で。

Solo – 静的Linuxバイナリ用の.soローダー

2026年8月19日原文(github.com)

概要

SoLo は、静的にリンクされたLinuxバイナリから動的なGPUドライバ(glibc依存)を直接ロード可能にする .soローダーmuslでリンク された単一実行ファイルで配布し、 ホストのグラフィックドライバ を利用。 コンテナやAppImage不要、プロセス内に二重libcも不要。 Vulkan/OpenGLドライバ の利用時に発生する静的バイナリの壁を突破。 x86-64/aarch64対応、さまざまなGPU・ディストリビューションで実証済み。

SoLoとは何か

  • SoLo は、静的Linuxバイナリ(muslリンク)から glibc依存のGPUドライバ(.so) を直接ロードできる独自ローダー
  • アプリケーション配布 は1ファイルのみ、追加依存関係や破損リスクを最小化
  • IXビルドシステム で完全静的バイナリを生成
  • Vulkan/OpenGLドライバ は通常glibc依存の共有オブジェクトとしてホストに存在
  • 通常のmusl静的バイナリは dlopen() でこれらを利用不可
    • SoLoはこの制約を突破し、 独自ELFローダー+glibc ABIブリッジ で実現

SoLoの仕組み

  • dlfcn風API を提供し、SoLo経由で dlopen/dlsym 操作を実現
  • elf_loader.cpp :ELFセグメントのマッピング、DT_NEEDED解決、シンボル・バージョン管理、リロケーション、TLS、IFUNC、RELRO、初期化子実行
  • glibc_shim.cpp :glibc関数のABI互換アダプタをmusl上で実装
  • glibc_stubs.cpp :未実装関数はシンボル名+バージョンで明示的にエラー
  • 同期オブジェクト (pthread_mutex_t等)は glibc/musl間で共用
  • 静的プロバイダレジストリ でWayland等の依存を実行ファイル内で満たすことも可能
  • LD_LIBRARY_PATHDL_ELF_LIBRARY_PATH で標準外ディレクトリの.soも探索

実行例・デモ

  • 事前ビルドバイナリ をダウンロード、実行のみで動作
    • x86-64:
      curl -LO https://github.com/pg83/solo/releases/latest/download/vulkan-x86_64
      chmod +x vulkan-x86_64
      ./vulkan-x86_64 hello.png
      
    • aarch64:
      ./vulkan-aarch64 hello.png
      
  • ドライバ強制指定 も可能
    ./vulkan-x86_64 --driver /usr/share/vulkan/icd.d/radeon_icd.x86_64.json radeon.png
    
  • バイナリが動的リンクされていないことの確認
    readelf -lW ./vulkan-x86_64 | grep INTERP # 出力なし
    readelf -dW ./vulkan-x86_64 # "There is no dynamic section"
    
  • ソースからのビルド
    git clone https://github.com/pg83/solo.git
    cd solo
    ./build vulkan
    ./vulkan hello.png
    

デモ内容の詳細

  • 静的Khronos Vulkanローダー 経由でホストのVulkan ICD+依存.soをSoLoでロード
  • デバイス・バッファ・パイプライン作成、SPIR-Vシェーダ実行、PNG出力 まで一連の実用処理
  • AMD radv, radeonsi, Intel, NVIDIA, Apple M1 (Asahi Linux) 等で動作検証済み

SoLoの技術的特徴

  • C++例外伝播 :静的/動的フレーム間で例外が双方向に伝播、単一unwinderで処理
  • 全TLSモデル対応 :ラッパやコードパッチ不要、musl TLS空間で一貫管理
  • ld.so互換のバインディング :RTLD_DEEPBIND、DT_SYMBOLIC、シンボルバージョン、PLT遅延解決、GNU/SysVハッシュ、ifunc対応
  • クロスワールドインスペクション :backtrace, dl_iterate_phdr, dladdr1等で静的/動的両方のイメージ解析
  • glibc状態管理 :getcontext/makecontext/swapcontext、pthread ABI、GNU obstack、_chk系、inline-stdio ABI等にも対応
  • CIでDebian上位1000ライブラリDSOをロード検証

他手法との比較

  • gcompat :glibcバイナリをmuslで動かすshim、SoLoのような静的バイナリの自己完結型ローダーではない
  • Detour/Cosmopolitan Libc :ホストld-linux+libcを起動、二重libc/TLS世界が混在
  • ClickHouse/graphics.gd :ELFローダー実装だがglibc自体はロード、TLSトランポリン必要
  • Flatpak/AppImage/コンテナ :小型Linuxディストリ同梱、巨大なバイナリ・重複・デバッグ困難
    • SoLoは ホストのハードウェアドライバのみ借用、他は自己完結

利用方法・ビルド

  • ライブラリとして利用 :lib/dlfcn.hをインクルード、libdlfcn.aをmusl静的バイナリにリンク
  • ソースツリーは自己完結型、他の静的ビルドグラフにも容易に組み込み可能
  • build.py で全ソースを直接ビルド、外部CMake/Meson/Make等は不要
  • バージョン固定のvendored依存 :musl, LLVM runtimes, Vulkan Headers/Loader, zlib, libpng等を同梱

サポート範囲・制限

  • Linux専用、x86-64/aarch64対応
  • ELFローダー、TLS、リロケーション、glibcシンボル管理 はアーキごとに最適化
  • 今後の拡張や他アーキ対応は未定

このように SoLo は、 静的バイナリ配布のシンプルさホストGPUドライバとの柔軟な連携 を両立するための革新的なソリューション。 ドライバ以外は全て自己完結、かつ 最小限の実行ファイルのみで運用可能 な点が最大の特長。

Hackerたちの意見

muslについてはあまり詳しくないんだ。

GPU: VulkanとOpenGLのドライバーはホストによって共有オブジェクトとして提供されていて、通常はglibcに対してビルドされてるんだ。完全に静的なmuslバイナリは、通常それらをdlopen()できない。なんで?古い共有ライブラリの概念を壊すことに成功した人がいるのかな?それがその修正なの?

muslはglibcのすべての側面を完璧にエミュレートしてるわけじゃないから、glibcを前提にしたライブラリを使おうとすると、時々問題が起きることがあるよ。

glibcとGNUはひどい前例を作ったからね。GNU/Linuxシステムでは、共有バイナリインタープリター/ローダー、GCCコンパイラ、Cライブラリ、システムのC/C++ ABIが互いに依存してる。どれか一つを独立して変更することはできないんだ。すべての共有ライブラリは、特定のglibcバージョンに依存して、それをメモリにロードして、その特定のglibcバージョンをCライブラリとして使って、dlopenみたいな呼び出しをする必要がある。Linuxでは共有ライブラリはずっと壊れてる。残念ながら、GPUドライバーやグラフィックスライブラリ、NSSみたいなものは、特定のランタイムを動的にロードするために共有ライブラリを必要とする(すべてのGPUドライバーをRAMにロードしたくないからね)。だから、ひどいABIとアーキテクチャの上にエコシステムが発展してしまったんだ。

muslは共有ライブラリをビルドして使うのには問題ないよ。ただ、muslで静的にビルドしたものを、glibcでビルドされた共有ライブラリをdlopenするのは信頼できないってことだね。

なんで?古い共有ライブラリの概念を壊せた人がいるの?ここで共有ライブラリを壊したり削除したりすると、ソースから何かをコンパイルできなくなるかもしれないよ。昔、もっと静的にコンパイルされたプログラムを使うようになる前に、そういうことがあった。共有ライブラリを使って常にすべてが動くと仮定するのは、すべてのLinuxシステムにとってあまり意味がないよね。例えば、glibcを手動でアップグレードする人もいるし、その場合はコンパイルを再開するために動作する基本システムが必要になる。自分のカスタマイズしたgobolinuxシステムではそうしてるから、どんなプログラムのバージョンやglibcのバージョンでも使えるんだ(プログラムがまだコンパイルできる前提だけど、古いプログラムはもうコンパイルできないことが多い)。

たくさんの人がUNIXシステムを理解していないから、いろんな理由で動的リンクが導入されたんだよね。実際、UNIXがベル研究所の外で知られるようになってから、ほぼ20年間は静的リンクしかなかったし。他の多くのOSも初期の頃から両方のアプローチを持ってたし、Xerox PARCのものもそうだった。なんでか知らないけど、彼らは研究者たちよりも自分たちの方がよく知ってると思ってるみたい。

これが以前の技術とどう違うのか(そして良いのか) - https://github.com/pg83/solo#how-this-differs-from-prior-wor...

注意: あのmdファイルはLLMのゴミ(コードベースのほとんどがそうだけど)。 https://github.com/pg83/solo/commits/main/README.md https://github.com/pg83/solo/commits/main/

このプロジェクトのメンテナンスについての計画はどうなってるの? soloをgraphics.gdのmuslビルドに組み込むことについてどう思う?

人々は「so」って言うの?それとも「ess-oh」?「a .so」ってタイトルは「ess-oh」派にはちょっと不格好だよね。

自分は人生で声に出して言ったのは数回しかないと思う。でも一般的には、ファイル拡張子の「dot」は文脈から明らかじゃない限り、ちゃんと発音するようにしてるよ。

まあ、.soは共有オブジェクトの略だから、「a .so」は正しいと思うよ。

Hacker Newsで議論の続きを見る