Rust 公式の cc-rs クレートを利用することで、C++ のソースコードもひっくるめて cargo ビルドすることができます。
簡単なサンプルで利用方法を紹介します。
C++ を含めた Cargo ビルド方法
プロジェクトの作成
まず、cargo new
で新規プロジェクトを作成します。
$ cargo new sample
C++ ソースコードの準備
Cargo でビルドする C++ のソースコードを用意しておきます。
2つの int を足し合わせるような簡単なメソッドです。
ファイルの保存場所に制約はないですが、ここでは src/add.cc
として保存しておきます。
// src/add.cc
extern "C" int add(int a, int b)
{
return a + b;
}
Cargo.toml にビルド用依存関係を記述
Cargo.toml に cc-rs への依存関係を追記します。
注意点として、[dependencies]
ではなく、[build-dependencies]
を新規追加してここに定義します。
# Cargo.toml
[package]
name = "sample"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[build-dependencies]
cc = "1.0"
build.rs の作成
ビルド用の main 関数を準備します。
この例では、src/add.cc
を読み込んで、add
ライブラリを出力しろ、という命令になります。
Linux で実行する場合には、libadd.a
ファイルが出力されることになります。
// build.rs
fn main() {
cc::Build::new().file("src/add.cc").compile("add");
}
なお、build.rs
は、src
配下ではなくプロジェクト直下に配置します。
Rust の main.rs を作成
msin.rs を修正して、C++ の add 関数を呼び出すようにします。
// src/main.rs
extern "C" {
fn add(a: i32, b: i32) -> i32;
}
fn main() {
let res = unsafe { add(1, 2) };
println!("1 + 2 = {}", res);
}
ポイントは以下のとおりです。
- extern “C” のもとで、C++ のメソッド定義を記述しておく。
- C++ の int 型は、Rust の i32 に相当する。
- C++ メソッドは unsafe ブロックで呼び出す必要あり。
ここまでのディレクトリツリー構造
ここまでで、sample プロジェクトの配下は次のようなファイル構成になっているはずです。
$ tree .
.
├── Cargo.lock
├── Cargo.toml
├── build.rs
└── src
├── add.cc
└── main.rs
ビルドして実行
cargo run によって、ビルドからランまで実行します。
問題なければ、1 + 2 の計算結果として 3 が返ってきます。
$ cargo run
Compiling libc v0.2.147
Compiling cc v1.0.82
Compiling sample v0.1.0 (/home/gari/sandbox/sample)
Finished dev [unoptimized + debuginfo] target(s) in 2.95s
Running `target/debug/sample`
1 + 2 = 3
cc1plus が見つからないエラーが発生する場合
環境の状態によっては、次のようなエラーが発生する可能性があります。
$ cargo run
Compiling sample v0.1.0 (/home/gari/sandbox/sample)
The following warnings were emitted during compilation:
warning: cc: fatal error: cannot execute ‘cc1plus’: execvp: No such file or directory
warning: compilation terminated.
error: failed to run custom build command for `sample v0.1.0 (/home/gari/sandbox/sample)`
これは C++ のコンパイラがインストールされていない場合に発生します。
Ubuntu 22.04 の場合は、 sudo apt install g++
で解決することができました。
コメント