注:以下の方法はWindows(*-pc-windows-msvc
)では使えません
Rustはアセンブラを生成するためにLLVMのライブラリを使います。これはtoolchainに含まれていて、例えばお手元の~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends
を覗いてみてください(ちなみにlibcoreやlibstdもこの辺にあります)。ここにlibrustc_codegen_llvm-llvm.so
という共有ファイルがあり、これにLLVMのライブラリが含まれています。
一方、ユーザーがRustでLLVMを使う方法としては、例えば以下の記事でも紹介されていますが、llvm-sys
があります。
llvm-sys
は他の*-sys
crateと同様に、システム(/usr
)や他の場所にインストールされているLLVMを使います。しかしLLVMのインストールは存外面倒で、パッケージ管理システム(apt,dnf等)で入るものが古すぎたりします。
私はllvmenvというのを作って管理していたのですが、今回はrustc自体に含まれるLLVMを使う方法を紹介します。
rustc-llvm-proxy
このcrateは実行時にlibloadingを使って動的に共有ライブラリを読み込み、LLVMの関数を呼び出します。RustとのFFIにはllvm-sys
を使います。
[dependencies]
rustc-llvm-proxy = "0.1"
[dependencies.llvm-sys]
version = "60.2"
features = ["no-llvm-linking"]
この様にllvm-sys
にno-llvm-linking
を指定します。これでシステムに(rustc自体と別個に)LLVMがインストールされていなくてもrustc自体の使っているLLVMを使う事ができます。これにより
- rustcのコード生成と同じLLVMのビルドを使うことができる
- システムのLLVMに依存しない
の2点が解決されます。
extern crate llvm_sys;
extern crate rustc_llvm_proxy;
の様にextern crateだけしておけば後はllvm-sys
の場合と同じです。参考に上記の記事のコードをコンパイルできる形にしたものをrustc-llvm-proxy-exampleにおいておきます。
追記
- stableでも使えるのでnightlyな表記を削除
- windowsでは使えない旨を表記 (https://github.com/denzp/rustc-llvm-proxy/issues/1)
-
*-pc-windows-msvc
/*-pc-windows-gnu
の違い
-
追記2
- rustc-llvm-proxy 0.1.3では
LLVM_InitializeAllTarget
等の初期化マクロが呼べません。個別のターゲットごとの初期化を使うか、以下のPRを使ってください https://github.com/denzp/rustc-llvm-proxy/pull/4