Rust は C API をゼロオーバーヘッドで呼び出せたりして便利なんだけど、当然バインディングは行わないといけない。 crates.io を探せばおおよそのものは見つかるけど、見つからなかったり、見つかっても古かったりして更新したいときがある。
そんなときは、bindgen (https://github.com/Yamakaky/rust-bindgen) をつかってヘッダーファイルから生成すると便利。 ただし Yamakaky の方は Clang 3.9 に対応していなくて実行するとエラーが出たりする。 手元の環境は Arch Linux で Clang が 3.9 なので残念ながらうまく行かなかった。
一方、Servo の方に fork があって (https://github.com/servo/rust-bindgen) そちらは 3.9 に対応している。
ただし Yamakaky の方と微妙に使い勝手が違う。具体的には --match
オプションがない。
(でも --whitelist-*
オプションがないから実は困らない気がしてきた。)
そんなわけで、Clang 3.8 をいれて bindgen をビルドする方法を書いておく。
LLVM/CLang のオフィシャルページから 3.8.1 の llvm と clang のソースをダウンロードして、 手順通り (https://clang.llvm.org/get_started.html) にビルドする。 llvm の tools/clang に clang のソースを展開して、configure && make で OK。
あとは llvm のビルドディレクトリに lib/libclang.so
ができるのでそいつを指定して以下を実行。
$ LIBCLANG_PATH=$BUILD/lib/ cargo install bindgen
あとはライブラリパスを指定して、bindgen が実行できる。
$ LD_LIBRARY_PATH=$BUILD/lib/ ~/.cargo/bin/bindgen foo.h > foo.rs