Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
It’s about time to pack Ruby and Ruby scripts in one binary
Search
ahogappa
May 16, 2024
Programming
1
3.3k
It’s about time to pack Ruby and Ruby scripts in one binary
ahogappa
May 16, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
小さな開発会社を作った理由
polidog
0
1.9k
ぼっちを避けて楽しむためのアノテコノテ / Various Tips and Tricks to Avoid Loneliness and Have Fun
nrslib
3
1.7k
今こそ始める、CDKコンストラクトライブラリ開発 ― 入門から実践まで
tmokmss
1
930
日付と正規化
megmogmog1965
0
140
英語
s_shimotori
1
220
CSC307 Lecture 08
javiergs
PRO
0
330
CSC307 Lecture 05
javiergs
PRO
0
210
Polarsの成長: v0.14からv1.0までの変遷と今後の展望
zerebom
1
350
Namespace on read
tagomoris
2
370
Google's Recipe for Scaling (Web) Security – LocoMocoSec 2024
lweichselbaum
0
170
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
160
OpenAI/Gemini APIを使って EPUBを翻訳するCLIツールをつくってみた
tomiyan
0
790
Featured
See All Featured
Scaling GitHub
holman
458
140k
Art, The Web, and Tiny UX
lynnandtonic
291
20k
Designing for humans not robots
tammielis
247
25k
The Pragmatic Product Professional
lauravandoore
29
6.1k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
24
1.8k
GraphQLとの向き合い方2022年版
quramy
36
13k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
149
45k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
90
47k
Mobile First: as difficult as doing things right
swwweet
219
8.8k
Happy Clients
brianwarren
94
6.5k
Building Your Own Lightsaber
phodgson
101
5.9k
The Cost Of JavaScript in 2023
addyosmani
31
4.7k
Transcript
It’s about time to pack Ruby and Ruby scripts in
one binary RubyKaigi 2024 ahogappa
About me • Sho Hirano(@ahogappa) • STORES, Inc. • #FFF613
2
What’s one binary? 3
What’s one binary? Works perfectly with just one file 4
Why one binary? 5
Why one binary in Ruby? 6
Why one binary in Ruby? e.g. distributing a Ruby project
7
Why one binary in Ruby? 💻 💻 developer user 8
Why one binary in Ruby? 💻 a.rb a.rb a.rb a.rb
💻 developer user 9
Why one binary in Ruby? 💻 a.rb a.rb a.rb a.rb
💻 Ruby 3.3.0 Sinatra 4.0.0 Sqlite3 2.0.1 developer user 10
Why one binary in Ruby? 💻 a.rb a.rb a.rb a.rb
💻🚫 Ruby 3.3.0 Sinatra 4.0.0 Sqlite3 2.0.1 Ruby 3.0.0 Sinatra 3.2.0 Sqlite3 Not installed developer user 11
Why one binary in Ruby? 💻 💻 Ruby 3.3.0 Sinatra
4.0.0 Sqlite3 2.0.1 developer user 12 Ruby 3.0.0 Sinatra 3.2.0 Sqlite3 Not installed
Why one binary in Ruby? 💻 💻 one binary developer
user Ruby 3.3.0 Sinatra 4.0.0 Sqlite3 2.0.1 13 Ruby 3.0.0 Sinatra 3.2.0 Sqlite3 Not installed
Why one binary in Ruby? 💻 💻✔ one binary Ruby
3.3.1 Sinatra 4.0.0 Sqlite3 2.0.1 a.rb a.rb a.rb a.rb developer user Ruby 3.3.1 Sinatra 4.0.0 Sqlite3 2.0.1 14 Ruby 3.0.0 Sinatra 3.2.0 Sqlite3 Not installed
Any existing tools? 15
Any existing tools? • ocra(ocran) • exerb • ruby2exe •
ruby-packer 16
🤔 Existing tools look good and useful 17
Existing tools look good and useful, but • No support
for 3.0+ • Patches Ruby • Windows only • Write temporary files 18
Time to make new one! 😄 19
Done 🔧 20
Kompo 📦 21
Kompo • 梱包(こんぽう) ◦ Means packaging, packing • A word
play on “compo” ◦ compose ◦ component ◦ composite ◦ etc… 22 https://github.com/ahogappa0613/kompo
Demo One binary with Sinatra and Sqlite3 23
Features 24
Features • Monkey patch only, not patching Ruby • No
write temporary files • Supports Gemfile • Reads local file as a fallback when failing to read from vfs 25
Demo Reads local file as a fallback when failing to
read from vfs 26
How kompo works 27
How kompo works • Ruby scripts are embedded • Patch
methods that read Ruby scripts ◦ Kernel#require ◦ Kernel#require_relative ◦ Kernel#load ◦ Kernel#autoload, Module#autoload • Native extensions are statically linked 28
29 libruby-static.a
30 libruby-static.a native extensions
main.c 31 libruby-static.a native extensions void Init_gems(void) { ruby_init_ext( "puma/puma_http11.so",
Init_puma_http11 ); ruby_init_ext( "sqlite3/sqlite3_native.so", Init_sqlite3_native ); } int main(int argc, char **argv) { ruby_sysinit(&argc, &argv); ruby_init(); Init_gems(); Init_kompo_fs(); … return ruby_run_node(node); }
main.c 32 kompofs.o +patches libruby-static.a native extensions
33 class Kompo def get_file(abs_path) # return the ruby script
from kompofs(.o) end … end main.c libruby-static.a native extensions kompofs.o +patches libkompo.a
main.c libkompo.a 34 libruby-static.a kompofs.o +patches native extensions one binary
compile and link libruby-static.a
Patches 35
Patches libruby-static.a main.rb b.rb d.rb a.rb Kernel#require Kernel#require_relative c.so 36
Patches libruby-static.a main.rb b.rb d.rb a.rb Kernel#require Kernel#require_relative c.so $
cd /workspace/sample $ kompo a.rb b.rb 37
Patches libruby-static.a main.rb b.rb Kernel#require Kernel#require_relative d.rb a.rb c.so 38
kompofs.o
Patches Ruby main.rb b.rb Kernel#require Kernel#require_relative c.o d.rb a.rb one
binary libkompo.a 39 main.c kompofs.o
Patches Ruby main.rb b.rb 🪡Kernel#require 🪡Kernel#require_relative c.o d.rb a.rb one
binary libkompo.a 40 module Kernel def require(path) eval(Kompo.get_file(path)) rescue => LoadError original_require(path) main.c kompofs.o
Patches Ruby main.rb b.rb 🪡Kernel#require 🪡Kernel#require_relative c.o d.rb a.rb one
binary require ‘a’ require_relative ‘./b’ require ‘c’ require ‘d’ libkompo.a 41 module Kernel def require(path) eval(Kompo.get_file(path)) rescue => LoadError original_require(path) main.c kompofs.o
Patches Ruby main.rb b.rb 🪡Kernel#require 🪡Kernel#require_relative c.o d.rb a.rb one
binary libkompo.a 42 module Kernel def require(path) eval(Kompo.get_file(path)) rescue => LoadError original_require(path) kompofs.o require ‘a’ require_relative ‘./b’ require ‘c’ require ‘d’ main.c
Future Works 43
Future Works • Support ways for users to access kompofs
freely • Cross-compilation • File compression 44
Let’s kompo Ruby! 45
Thank you!! 46