minutus 要件整理
やりたいこと
mruby を Rust に埋め込む
つまり Rust が mruby のコードを解釈できるようにする
mruby 自体は crate の中に含んでいてほしいが、カスタマイズする柔軟性がほしい
具体的には、build_config.rb を何らかの形で渡したい
Rust を mruby に埋め込む
つまり mrbgem の実装手段として Rust を使えるようにする
mruby 自体は crate の中に含む必要がない
やる必要があること
bridge.c を bridge.o に変換する
mruby/includes が必要
crate に含むよりはビルド時に取得するほうが望ましい((可能ならば)任意の環境で動かせるようにするため)
bridge.c から Rust の binding を生成する
mruby/includes が必要
crate に含むよりはビルド時に取得するほうが望ましい((可能ならば)任意の環境で動かせるようにするため)
bridge.o および libmruby.a をリンクして Rust のバイナリをビルドする
bridge.o および libmruby.a が必要
bridge.o および Rust のビルド生成物をリンクして mruby をビルドする
bridge.o および Rust のビルド生成物が必要
現状の戦略
✅ プレーンな mruby をRust に埋め込む
crate が bridge.o、binding、libmruby.a をビルド・リンクする
✅ mruby に Rust を埋め込む
crate が bridge.o、binding をビルドし、リンクを行う。ユーザーが書いた Rakefile が libmruby.a のビルドを行い、諸々のリンクを行う。
❌ カスタマイズした mruby を Rust に埋め込む
crate が bridge.o、binding をビルドし、リンクを行う。ユーザーが書いた build.rs が libmruby.a のビルドを行い、リンクを行う。
Linux でやると死ぬ
カスタマイズした mruby を Rust に埋め込めない件
プレーンな mruby の埋め込みは Linux でも成功するので、カスタムビルド特有の何かしらが悪さをしていると思われる
ここで、そもそも Rust のリンカってどうやって動いてるの(というかRustのビルドってどうやって回ってるの)という疑問が発生する
関連してそうな https://tomoyuki-nakabayashi.github.io/embedded-rust-techniques/01-introduction/introduction.html を読む
↑これはあんまり関係なかった
https://tanakamura.github.io/pllp/docs/linker.html これは割と良かった気がする
https://www.amazon.co.jp/dp/4789838072/ref=cm_sw_r_tw_dp_GVXG3KC4RY77CW5R3JK3 も良さそうな本だったが、ちょっと詳細に入りすぎているように思ったので序盤の数ページ読んでやめた
これだーーー!!!!!
http://thatsdone-j.blogspot.com/2013/03/gnu-ld-as-needed-and-no-as-needed.html
実は、少なくとも現行の Ubuntu ではリンカ (GNU ld) の挙動が変更されており、以下のように、--no-as-needed というオプションを指定しないといけないことが分かった。
https://stackoverflow.com/questions/55886779/how-to-link-a-c-library-without-calling-one-of-its-functions
fix https://github.com/genya0407/minutus/pull/2/commits/1bfcb48d6f39ac44fccecbda81a78dde5f6d7ce3