LoginSignup
19
11

More than 5 years have passed since last update.

Rustcに付随しているLLVMを使う

Last updated at Posted at 2018-09-16

注:以下の方法は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を使います。

Cargo.toml
[dependencies]
rustc-llvm-proxy = "0.1"

[dependencies.llvm-sys]
version = "60.2"
features = ["no-llvm-linking"]

この様にllvm-sysno-llvm-linkingを指定します。これでシステムに(rustc自体と別個に)LLVMがインストールされていなくてもrustc自体の使っているLLVMを使う事ができます。これにより

  • rustcのコード生成と同じLLVMのビルドを使うことができる
  • システムのLLVMに依存しない

の2点が解決されます。

main.rs
extern crate llvm_sys;
extern crate rustc_llvm_proxy;

の様にextern crateだけしておけば後はllvm-sysの場合と同じです。参考に上記の記事のコードをコンパイルできる形にしたものをrustc-llvm-proxy-exampleにおいておきます。

追記

追記2

  • rustc-llvm-proxy 0.1.3ではLLVM_InitializeAllTarget等の初期化マクロが呼べません。個別のターゲットごとの初期化を使うか、以下のPRを使ってください https://github.com/denzp/rustc-llvm-proxy/pull/4
19
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
11