Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RubyKaigi 2024 followup

ahogappa
September 03, 2024
40

RubyKaigi 2024 followup

ahogappa

September 03, 2024
Tweet

Transcript

  1. © 2020 Coiney, Inc. • RubyKaigiでFuture Worksとしていた部分 ◦ 内部ファイルシステムへの自由なアクセス ◦

    クロスコンパイル ◦ ファイルの圧縮 • STORES Tech Blogに書いた記事を元に発表資料にしてい ます ◦ https://product.st.inc/entry/2024/06/25/100008 ◦ この記事以降に更新があった内容も含まれています 今日話すこと 4 4
  2. © 2020 Coiney, Inc. • お手軽であること ◦ 簡単にワンバイナリ化できて欲しい ◦ 複雑なオプションはなるべくいらないようにしたい

    • それなりに速度が出ること ◦ 簡単にできても遅くなってしまうと、元のコードを チューニングする必要があったり、諦めてしまう ◦ クロスコンパイルできること kompoのコンセプト 5 5
  3. © 2020 Coiney, Inc. • requireの代わりに `eval File.read(“hoge.rb”)` を実行す るようなコードが対応できない

    ◦ 例えばRubyGems gem ◦ デモの時は誤魔化していた • 内部ファイルにアクセスできる手段をrequire以外にも開 放する ◦ 内部ファイルを取得したい!を明示的にできるような 何かを作る必要がある 内部ファイルシステムへの自由なアクセス 7 7
  4. © 2020 Coiney, Inc. • 実現するためにやらないといけないこと • “ちゃんとした”ファイルシステムの構築 • open,

    readなどの関数をパッチする => パッチした関数が呼ばれたら内部ファイルシステムに繋げる • “ちゃんとした”ファイルシステムの構築 ◦ 今はファイルの中身を巨大なバイト列として保持している ◦ ディレクトリの情報や更新情報などのfile statに必要な情報を 持っていない • open, readなどの関数をパッチする ◦ ruby-packer gemはこの方法でrailsまで動かしている 内部ファイルシステムへの自由なアクセス 8 8
  5. © 2020 Coiney, Inc. • ファイルシステムとして必要な機能は基本的に読み込みだけ ◦ 書き込みが要求されたら、本物のファイルシステムを使ってあげる ◦ ファイルパスを与えられたらfd(のような何か)を返して、fdでアク

    セスされたらデータを返すような実装をすればいいはず • FUSEも試してみた ◦ macはmacfuse、windowsはそもそもない?ということで、環境差 異がありそう ◦ バイナリを実行する環境にfusermountコマンドのインストールが 必要 “ちゃんとした”ファイルシステムの構築 9 9
  6. © 2020 Coiney, Inc. • 関数をパッチする方法 ◦ #defineを使ってコンパイル時に関数を置き換える ◦ LD_PRELOADを使ってリンクする関数を変える

    ◦ -Wl,--wrapを使ってリンク時に関数を読み替える • ruby-packer では#defineを使ってパッチしている ◦ ruby本体に変更を加える必要がある ◦ rubyの変更に追従する必要がある • LD_PRELOADは共有ライブラリにする必要がある ◦ 動的リンク時に解決 ◦ パッチファイルを共有ライブラリにして配布する必要がある • -Wl,--wrapが使えそう...? ◦ rubyに変更を加える必要がない&静的リンクで解決 ◦ GNU Linker限定のオプション • 別解でIFUNCとかもありそう open, readなどの関数をパッチする 10 10
  7. © 2020 Coiney, Inc. • -Wl,--wrapってどんなことをやっているのかlldとmoldの コードを読む • 意外とやっていることは少ない open,

    readなどの関数をパッチする 11 11 ref: https://github.com/rui314/mold/blob/ed4cae93542350c863eff7e10131272b4c01fe0e/src/input-files.cc#L641-L652
  8. © 2020 Coiney, Inc. • リンカの種類に依存せずにこれを実現できないか • とはいえリンカを作るのは大変すぎる • シンボルを読み替えればいいだけなので、コンパイル後バ

    イナリを編集したらできそう? ◦ libstatic-ruby.aに対してバイナリ編集する ◦ rubyだけで実現できれば、rustを使う必要がなくなる ◦ LIEFのruby版みたいなのを作る必要がある open, readなどの関数をパッチする 12 12
  9. © 2020 Coiney, Inc. • こちらも何も考えられていない ◦ 発表した当初から変わらずzlibで固めるかな... • そもそもどんなデータをワンバイナリに含めるか

    ◦ minifyしたもの ◦ ASTを小さく表現するほうが小さくなる? ◦ boot snapのように事前コンパイルしたもののほうが速 度は出そう • ただのminifyだったらminifyrbでいいじゃないかな ファイルの圧縮 14 14
  10. © 2020 Coiney, Inc. • namespace ◦ 拡張ライブラリは静的リンクしたいのでリンク時に シンボルが重なってこけそう ◦

    マングリングする??? ◦ ワンバイナリに含めておいて、それをいい感じに参照 する??? おまけ 17 17