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 ...
Search
ahogappa
May 16, 2024
Programming
1
4.7k
It’s about time to pack Ruby and Ruby scripts in one binary
ahogappa
May 16, 2024
Tweet
Share
More Decks by ahogappa
See All by ahogappa
RubyKaigi 2024 followup
ahogappa0613
0
40
Other Decks in Programming
See All in Programming
CSC509 Lecture 13
javiergs
PRO
0
110
watsonx.ai Dojo #4 生成AIを使ったアプリ開発、応用編
oniak3ibm
PRO
1
140
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
Amazon Bedrock Agentsを用いてアプリ開発してみた!
har1101
0
340
Flutterを言い訳にしない!アプリの使い心地改善テクニック5選🔥
kno3a87
1
200
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
900
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
4
1.5k
Jakarta EE meets AI
ivargrimstad
0
670
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
3
690
Jakarta EE meets AI
ivargrimstad
0
220
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
Featured
See All Featured
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Navigating Team Friction
lara
183
14k
A Modern Web Designer's Workflow
chriscoyier
693
190k
A Philosophy of Restraint
colly
203
16k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Writing Fast Ruby
sferik
627
61k
The Cost Of JavaScript in 2023
addyosmani
45
6.8k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
420
It's Worth the Effort
3n
183
27k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Typedesign – Prime Four
hannesfritz
40
2.4k
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