Rust – Cargo で C++ ソースコードをまとめてビルドする

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++ で解決することができました。

  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次