Text
Page: 1
Goodbye fat gem
Sutou Kouhei
ClearCode Inc.
RubyKaigi Takeout 2020
2020-09-04
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 2
Sutou Kouhei
The president of ClearCode Inc.
クリアコードの社長
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 3
Sutou Kouhei
✓ The maintainer of rake-compiler
rake-compilerのメンテナー
✓ A gem for generating fat gem
fat gemを作るためのgem
✓ The maintainer of Ruby-GNOME
Ruby-GNOMEのメンテナー
✓ A project that used fat gem
fat gemを使っていたプロジェクト
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 4
Fat gem
Gem that includes
pre-built binaries
ビルド済みバイナリー入りのgem
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 5
Why is fat gem needed?
どうしてfat gemが必要なのか
✓ Difficult to build extension library
拡張ライブラリーのビルドが難しい
✓ Extension library:
A Ruby library implemented with C API
拡張ライブラリー:C APIを使って実装されたRubyライブラリー
✓ Fat gem just copies pre-built binaries
fat gemは単にビルド済みバイナリーをコピーするだけ(ビルドしない)
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 6
Why is building it difficult?
どうして拡張ライブラリーのビルドは難しいのか
✓ Users need build environment
ユーザーはビルド環境を用意しないといけない
✓ e.g.: C compiler, make and so on
例:Cコンパイラーやmakeなど
✓ Users need build dependencies
ユーザーが依存するライブラリーを用意しないといけない
✓ e.g.: GTK+ 3 for gtk3 gem
例:gtk3 gemはGTK+ 3が必要
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 7
With fat gem
fat gemを使うと
✓ Users don't need build environment!
ユーザーはビルド環境を用意しなくてもよい
✓ No C compiler
ユーザーはビルド環境がなくてもよい
✓ Users don't fail installation!
ユーザーはインストールに失敗しない
✓ Fat gem just copies pre-built binaries
fat gemは単にビルド済みバイナリーをコピーするだけ
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 8
With fat gem
fat gemを使うと
Happy!
...Really?
…ほんとに?
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 9
A fat gem maintainer says...
あるfat gemメンテナー曰く…
Thanks fat gem!
Goodbye fat gem!
ありがとうfat gem!
さよならfat gem!
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 10
Fat gem problem 1
fat gemの問題1
Can't use
the latest Ruby
immediately
いち早く最新のRubyを使えない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 11
Details
詳細
✓ Ruby is released every Christmas
Rubyは毎年クリスマスにリリースされる
✓ To use fat gems with the latest Ruby:
最新のRubyでfat gemを使うには
✓ Need to release fat gems for it
最新のRuby用のfat gemがリリースされていないといけない
✓ Users can't use the latest Ruby while:
ユーザーは↓の間は最新のRubyを使えないまま
✓ Any of fat gems doesn't support it
使っているfat gemのどれか1つでも最新のRubyをサポートしていない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 12
From fat gem maintainer view
fat gemメンテナー視点
Not all fat gem
maintainers
can do it
immediately
すべてのfat gemメンテナーがすぐに対応できるわけじゃない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 13
Fat gem problem 2
fat gemの問題2
Vulnerability
response
may get delayed
脆弱性対応が遅れがち
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 14
Details
詳細
✓ Only bindings fat gem case
バインディングのfat gemだけのケース
✓ Bindings:
A extension library to use an external library
バインディング:外部のライブラリーを使う拡張ライブラリー
✓ Includes the external library binary
fat gem内に外部ライブラリーのバイナリーも含む
✓ When a vulnerability of the external
library is found:
外部ライブラリーに脆弱性が見つかった場合:
✓ Should be released immediately with fix
すぐに修正を含んだバージョンをリリースするべき
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 15
From fat gem maintainer view
fat gemメンテナー視点
Not all fat gem
maintainers
can do it
immediately
すべてのfat gemメンテナーがすぐに対応できるわけじゃない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 16
Fat gem problem 3
fat gemの問題3
Can't control
the external
library version
外部ライブラリーのバージョンをコントロールできない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 17
Details
詳細
✓ Only bindings fat gem case
バインディングのfat gemだけのケース
✓ Maintainers choose one external
library version
メンテナーが外部ライブラリーのどのバージョンを使うかを選ぶ
✓ If old external library is chosen,
users can't use the latest version
古い外部ライブラリーを選んだら、ユーザーは最新バージョンを使えない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 18
Fat gem problem 4
fat gemの問題4
require is slower
requireが遅くなる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 19
require for fat gem
fat gem用のrequire
Fat gem needs the following code:
fat gemでは次のようなコードが必要:
begin
# Try the bundled binary in fat gem
require "#{RUBY_VERSION[/\d+\.\d+/]}/io/console.so"
rescue LoadError
# Use the local built binary
require 'io/console.so'
end
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 20
Why slower?
なぜ遅くなるか
✓ For not fat gem install:
fat gemを使わない環境:
✓ Such as on GNU/Linux and macOS
たとえばGNU/LinuxやmacOS
✓ require for fat gem is always failed
fat gem用のrequireは必ず失敗
✓ Can't ignore with large $LOAD_PATH:
$LOAD_PATHが大きい場合は無視できない
✓ e.g.: +0.1s with Ruby on Rails application
例:Ruby on Railsアプリケーションでは0.1秒遅くなる
https://github.com/ruby/io-console/pull/4
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 21
Fat gem problem 5
fat gemの問題5
Fat gem release
may be forgotten
fat gemのリリースを忘れられる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 22
Details
詳細
✓ Normal release is easy
通常のリリースは簡単
✓ rake release is done in a few seconds
rake releaseは数秒で終わる
✓ Fat gem release isn't easy
fat gemのリリースは簡単じゃない
✓ rake-compiler-dock help maintainers but...
rake-compiler-dockを使えばマシになるけど…
✓ It will take at least a few minutes...
少なくとも数分かかる…
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 23
From fat gem maintainer view
fat gemメンテナー視点
✓ Don't want to release a new version...
新しいバージョンをリリースしたくないな…
✓ Ruby-GNOME case: 10+ related gems
Ruby-GNOMEの場合:10以上の関連gemがある
✓ It takes at least 30 minutes
順調にいった場合でも少なくとも30分はかかる
✓ Forget to release a fat gem
fat gemをリリースするのを忘れる
✓ io-console 0.4.8 case
https://github.com/ruby/bigdecimal/pull/148#issuecomment-512075494
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 24
Fat gem problem 6
fat gemの問題6
High
maintenance
cost
メンテナンスが大変
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 25
Details
詳細
✓ Especially binding fat gem case
特にバインディングのfat gemのケース
✓ Normally, cross-compiling is used
通常、クロスコンパイルしてfat gemを作る
✓ Most external libraries don't do it
多くの外部ライブラリーはクロスコンパイルなんてしない
✓ There are some problems on upgrading
外部ライブラリーのバージョンをあげるたびになにかしら問題が見つかる
✓ Ruby-GNOME has 10+ related external libraries
Ruby-GNOMEは10以上の関連外部ライブラリーがあって大変だった
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 26
How to solve these problems?
これらの問題を解決するには?
Thanks fat gem!
Goodbye fat gem!
ありがとうfat gem!
さよならfat gem!
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 27
Why is fat gem needed
fat gemが必要だった理由
✓ Users don't have build environment
ユーザーがビルド環境を持っていない
✓ Especially, Windows users
特にWindowsユーザー
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 28
Windows users and build env
Windowsユーザーとビルド環境
✓ RubyInstaller for Windows provides
build env by default since 2.4
RubyInstaller for Windows 2.4以降はデフォルトでビルド環境を提供
✓ Ruby 2.3 reached EOL
Ruby 2.3はEOLになっている
✓ Most Windows users must use 2.4 or later
I know some Windows users don't use RubyInstaller for Windows
ほとんどのWindowsユーザーは2.4以降を使っているはず
✓ Most Ruby users have build env now!
ほとんどのユーザーはビルド環境を持っている!
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 29
Ruby-GNOME said goodbye fat gem!
Ruby-GNOMEはfat gemにさようならをした!
✓ Since 2018-10-31
2018-10-31から
✓ Install related issues isn't increased
インストール関連のissueは増えていない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 30
Resolve fat gem problem 1
fat gem関連の問題の解決1
Can use
the latest Ruby
immediately
いち早く最新のRubyを使える
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 31
Details
詳細
✓ Don't need a new release for new Ruby
新しいRuby用にgemをリリースする必要がない
✓ Until new Ruby doesn't change C API
新しいRubyでC APIが変わっていない限り
✓ Can release a new version
before new Ruby release
新しいRubyがリリースされる前に新しいバージョンのgemをリリースできる
✓ Can test with preview release Ruby on CI
CIでpreviewリリースのRubyをテストできる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 32
Resolve fat gem problem 2
fat gem関連の問題の解決2
Vulnerability
response
can be done by
each system
脆弱性は各システムが対応してくれる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 33
Details
詳細
✓ Especially, binding fat gem case
特にバインディングfat gemの場合
✓ Packaging system will update soon than
binding fat gem maintainers
バインディングfat gemのメンテナーよりもパッケージングシステムの方がすぐに
更新することが多い
✓ The # of packaging system maintainers
is larger than
the # of maintainers of each fat gem
各fat gemのメンテナーの数よりもパッケージングシステムのメンテナーの数
の方が多いから
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 34
Resolve fat gem problem 3
fat gem関連の問題の解決3
Can control
the external
library version
外部ライブラリーのバージョンをコントロールできる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 35
Details
詳細
✓ Packaging system may provide the
latest external library
パッケージングシステムは最新の外部ライブラリーを提供してくれるかもしれない
✓ Users can build suitable version of
the external library
ユーザーは適切なバージョンの外部ライブラリーをビルドできる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 36
Resolve fat gem problem 4
fat gem関連の問題の解決4
require isn't slower
requireが遅くならない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 37
Details
詳細
No fallback require:
フォールバック用のrequireがいらない
# Always use the local built binary
require 'io/console.so'
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 38
bigdecimal said goodbye fat gem!
bigedimalはfat gemにさようならをした!
✓ Because of this
これが理由
✓ ruby/bigdecimal#149
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 39
Resolve fat gem problem 5, 6
fat gem関連の問題の解決5,6
Easy to maintain
メンテナンスしやすくなる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 40
Details
詳細
✓ No fat gem release process
fat gemをリリースする作業がなくなる
✓ Don't forget fat gem release
fat gemのリリースも忘れない
✓ No cross compiling
クロスコンパイルしなくてもよい
✓ No rake-compiler
rake-compilerもいらない
✓ Maintainers can use their time for others
メンテナーは別のことに時間を使える
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 41
Stop fat gem
fat gemをやめると
✓ All problems can be solved!
すべての問題を解決できる!
✓ Additional good points
さらにいいことも
✓ Enable optimization for each user's env
各ユーザーの環境ごとに最適化できる
✓ e.g.: -O3 -march=native GCC options
例:GCCの-O3 -march=nativeオプションを使う
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 42
Stop fat gem
fat gemをやめると
Happy!
...Really?
…ほんとに?
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 43
Stop fat gem problem 1
fat gemをやめたときの問題1
Long install time
インストール時間が長くなる
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 44
Details
詳細
✓ Fat gem:
✓ Just copy pre-built binaries
単にビルド済みバイナリーをコピー
✓ Gem:
✓ Build and install binaries
バイナリーをビルドしてインストール
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 45
How to resolve this?
解決法は?
No idea...
なんかある?
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 46
Stop fat gem problem 2
fat gemをやめたときの問題2
Fail to install
インストールに失敗する
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 47
Details
詳細
✓ Only bindings gem case
バインディングのgemだけのケース
✓ Needs the external library to build
ビルドするために外部ライブラリーが必要
✓ If it doesn't exist, gem install is failed
外部ライブラリーがないとgem installが失敗
✓ e.g.: gem install rmagick is failed without
ImageMagick
例:ImageMagickがないとgem install rmagickが失敗
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 48
How to resolve this?
解決法は?
Install
the external library
automatically
自動で外部ライブラリーをインストール
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 49
RubyInstaller for Windows
Put the external library package name to
the gem's metadata:
gemのメタデータに外部ライブラリーのパッケージ名を設定
gemspec.metadata["msys2_mingw_dependencies"] = "cairo"
MSYS2 library dependencies - For gem developers - onclick/rubyinstaller2 Wiki
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 50
native-package-installer
rcairo case:
require "pkg-config"
require "native-package-installer"
unless PKGConfig.have_package("cairo")
# Install cairo from packaging system automatically
unless NativePackageInstaller.install(:arch_linux => "cairo",
:debian => "libcairo2-dev",
:homebrew => "cairo",
:macports => "cairo",
:redhat => "cairo-devel")
exit(false)
end
exit(false) unless PKGConfig.have_package("cairo")
end
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 51
Stop fat gem problem 3
fat gemをやめたときの問題3
Bundler's
dependency
resolution
may fail
Bundlerの依存関係解決が失敗するかもしれない
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 52
Bundler may use wrong dependency
Bundlerは間違った依存情報を使ってしまうかもしれない
git clone https://github.com/rails/rails.git
cd rails
bundle install
bundle update # Error
Bundle Update Fails for Rails 6.1 if Ruby >= 2.6 · Issue #37224 · rails/rails
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 53
Actual
Bundler could not find compatible versions for gem "ruby":
In Gemfile:
ruby
mysql2 (~> 0.5) was resolved to 0.5.2, which depends on
ruby (< 2.6) x64-mingw32
mysql2 (~> 0.5) was resolved to 0.5.2, which depends on
ruby (< 2.6) x86-mingw32
nokogiri (>= 1.8.1) was resolved to 1.10.4, which depends on
ruby (>= 2.3) x64-mingw32
nokogiri (>= 1.8.1) was resolved to 1.10.4, which depends on
ruby (>= 2.3) x86-mingw32
Goodbye fat gem
rails was resolved to 6.1.0.alpha, which depends on
Powered by Rabbit 3.0.1
Page: 54
Details
詳細
Omit
省略
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 55
How to resolve this?
解決法は?
✓ I've been fixed this
直しておいた
✓ rubygems/bundler#7522
✓ If you're interested in fixing problems in
upstream, ClearCode is a good corporation:
問題をアップストリームで直すことが好きな人はクリアコードといういい会社
があるよ!
https://www.clear-code.com/recruitment/
✓ Use Bundler 2.2.0 or later (not released yet)
未リリースだけどBundler 2.2.0以降を使えば解決する
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 56
Wrap up
まとめ
✓ Fat gem was useful until Ruby 2.3
Ruby 2.3まではfat gemは有用だった
✓ We can stop using fat gem now!
今はfat gemをやめられる!
Goodbye fat gem
Powered by Rabbit 3.0.1
Page: 57
Wrap up
まとめ
Thanks fat gem!
Goodbye fat gem!
ありがとうfat gem!
さよならfat gem!
Goodbye fat gem
Powered by Rabbit 3.0.1