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

RubyKaigi 2024 followup

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for ahogappa ahogappa
September 03, 2024
89

RubyKaigi 2024 followup

Avatar for ahogappa

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