bindgen を使って rust binding を生成する

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