トップ «前の日記(2023/04/04 (火) ) 最新 次の日記(2023/04/06 (木) )» 編集 RSS feed

HsbtDiary


2023/04/05 (水) [長年日記]

erb などのリポジトリで bundle exec irb すると missing extension となるバグを直した

本当に細かすぎて伝わらない上に困っているのが世界で @k0kubun くんと僕くらいというバグなのだが、ruby/erb のリポジトリの直下で bundle exec irb で irb を起動すると

$ bundle exec irb
Ignoring erb-4.0.2 because its extensions are not built. Try: gem pristine erb --version 4.0.2
>>

というような warning が出て、実際には rake-compiler によってビルドされているのに、RubyGems 的には erb の C extension がビルドされていないという状態になる不具合を直した。

最初は RubyGems の missing_extension? の判定処理がおかしいので、その判定処理を直すことにしたのだが、このメソッドはあらゆる gem を require する時に呼ばれるメソッドで、その度に full_require_paths, すなわち gemspec で指定されている、ロード対象となるパスすべてを操作するのはコストが高い、ということで最終的には bundler の方に処理を移動して、bundle exec して、直下に gemspec がある時だけ判定を行うということにした。

この判定というのがものすごく微妙な状態になっていて、普通に gem install をした時は rubygems は gem.build_complete というファイルを extension_dir に作成し、そのファイルがある時はビルドされているという判定をしているのだけど、ruby/erb などリポジトリの下で rake-compiler を使ってビルドする、irb を起動する、テストするというようなときは gem.build_complete ファイルがないので C extension がビルド済みなのかを判定できない。

なので、ヒューリスティックに、lib ディレクトリの下に gem と同名のバイナリ、または namespace の下に何かしらのバイナリがあるかなどで判定している。これ、rake-compiler の方と共同で同じようなビルド済みを判定するファイルを置くようにするのがいいんだろうけど、rake-compiler は tmp ディレクトリを使うなどしているので、上手なアーキテクチャが思いつかず一旦はこんな感じで直すことにした。