やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rustのcargoでワークスペースをつくる

 ワークスペースとは、複数のクレートをまとめる単位である。

成果物

参考

手順

1. クレートを作る

cargo new workspace_0 --lib
cd workspace_0

2. ワークスペースを作る

mkdir add
cd add
touch Cargo.toml
vim Cargo.toml

workspace_0/Cargo.toml

[workspace]
members = [
    "adder",
]

3. 1つ目のサブクレートを作る

workspace_0/add/

cargo new --bin adder
cargo build

4. 2つ目のサブクレートを作る

workspace_0/Cargo.toml

[workspace]
members = [
    "adder",
    "add-one",
]

workspace_0/add/

cargo new add-one --lib

workspace_0/add/add_one/src/lib.rs

pub fn add_one(x: i32) -> i32 { x + 1 }

 クレートの依存関係を指定する。

workspace_0/add/adder/Cargo.toml

[dependencies]
add-one = { path = "../add-one" }

 adderクレートのmain.rsからadd-oneadd_one()を呼び出す。なお、クレート名の無効な文字-_に自動で変更される。

fn main() {
    let num = 10;
    // こんにちは世界!{}+1は{}!
    println!("Hello, world! {} plus one is {}!", num, add_one::add_one(num));
}

 ビルド&実行。

workspace_0/add/

cargo build
cargo run

 -pフラグが必要と書いてあったが、不要だった。

workspace_0/add/

$ cargo build
   Compiling add-one v0.1.0 (/tmp/work/Rust.Workspace.20190704100555/src/1/workspace_0/add/add-one)
   Compiling adder v0.1.0 (/tmp/work/Rust.Workspace.20190704100555/src/1/workspace_0/add/adder)
    Finished dev [unoptimized + debuginfo] target(s) in 3.17s
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
     Running `target/debug/adder`
10 plus one is 11!
$ cargo run -p adder
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/adder`
10 plus one is 11!

 ルートで実行するとエラー。

workspace_0/

$ cargo run -p adder
error: package `adder` is not a member of the workspace

外部依存は共有する

 ワークスペース配下のクレートにはCargo.lockがない。ワークスペースの最上位に1つだけ存在する。つまりワークスペース配下のクレートは外部依存を共有できる。

workspace_0/add/add-one/Cargo.toml

[dependencies]
rand = "0.6"

workspace_0/add/add-one/

cargo build
cargo run

 以下を追記する。

workspace_0/add/add-one/src/lib.rs

use rand::Rng;
pub fn get_rand() -> i32 {
    let mut rng = rand::thread_rng(); // デフォルトの乱数生成器を初期化します
    let i: i32 = rng.gen();           // genはRng traitに定義されている
    i
}

workspace_0/add/adder/src/main.rs

fn main() {
    let num = 10;
    println!("{} plus one is {}!", num, add_one::add_one(num));
    println!("random is {}", add_one::get_rand());
}

workspace_0/add/

$ cargo run
10 plus one is 11!
random is -690621049

テストする

workspace_0/add/

$ cargo test

 ワークスペース配下にある全サブクレートのテストを一括実行する。

.gitignore

 ワークスペース配下に.gitignoreをコピペすること。さもなくばtarget/配下にあるオブジェクトファイルなどが候補になってしまう。なお、.gitignoreは最初にcargo newしたときにできたものをコピペする。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで