Rustでプログラミングを始めようと思ったとき、「どうやってプロジェクトを作るの?」「ライブラリはどう管理するの?」「ビルドはどうするの?」と疑問だらけになったことはありませんか?
「他の言語みたいに、いろんなツールを覚えないといけないの?」「複雑な設定ファイルを書かないとダメ?」と不安に思った方も多いはずです。
実は、Cargoは、Rustの公式パッケージマネージャー兼ビルドシステムで、プロジェクトの作成・依存関係の管理・ビルド・テスト・ドキュメント生成まで、すべてを一つのツールで完結できる超便利なツールなんです。まるで、料理に必要な材料の調達から調理、盛り付けまで全部やってくれる万能アシスタントのようなものですね。
この記事では、Cargoの基本から実践的な使い方まで、Rust初心者の方にも分かりやすく丁寧に解説していきます。
具体的なコマンドや設定例をたくさん見ながら、Rustプロジェクトの管理をマスターしていきましょう!
Cargoとは?その基本を知ろう

基本的な説明
Cargo(カーゴ)は、Rustの公式パッケージマネージャー兼ビルドシステムです。
2014年にRust 1.0と同時にリリースされ、Rustエコシステムの中核を担っています。
名前の由来:
「Cargo」は英語で「貨物」の意味。プロジェクトに必要なものを運んでくる、というイメージなんです。
何ができるの?
主な機能:
プロジェクト管理:
新しいプロジェクトを簡単に作成できます。
依存関係の管理:
外部ライブラリ(クレート)を自動でダウンロード・管理します。
ビルドシステム:
ソースコードをコンパイルして実行ファイルを作ります。
テストの実行:
ユニットテストや統合テストを簡単に実行できます。
ドキュメント生成:
コードから自動でドキュメントを生成します。
パッケージの公開:
作ったライブラリをcrates.ioに公開できます。
一つのツールで、すべてが完結するんですね!
他の言語との比較
Node.js: npm(パッケージ管理)+ webpack(ビルド)
Python: pip(パッケージ管理)+ setuptools(ビルド)
Java: Maven/Gradle(すべて統合)
Rust: Cargo(すべて統合)
Cargoは、JavaのMavenやGradleのように、最初から統合されているんです。
日常の例で理解しよう
レストランの支配人:
プロジェクト作成 = 店舗の開店準備
必要な設備や道具を揃える
依存関係管理 = 食材の仕入れ
必要な材料を適切な業者から調達
ビルド = 料理の調理
材料を組み合わせて料理を完成させる
テスト = 味見
料理が正しくできているか確認
ドキュメント = メニュー作成
どんな料理があるか説明書を作る
Cargoは、このすべてを一人でこなす有能な支配人なんです。
インストール方法
Rustと一緒にインストール
Cargoは、Rustをインストールすると自動的に入ります。
公式インストーラー(rustup)を使用:
Linux/macOS:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Windows:
https://rustup.rs/ からインストーラーをダウンロードして実行します。
インストールの確認
Rustのバージョン確認:
rustc --version
Cargoのバージョン確認:
cargo --version
出力例:
cargo 1.75.0 (1d8b05cdd 2024-01-10)
バージョンが表示されれば、インストール成功です!
PATHの設定
インストールが完了すると、自動的にPATHに追加されます。
確認方法:
which cargo
# Linux/macOS: /home/ユーザー名/.cargo/bin/cargo
# Windows: C:\Users\ユーザー名\.cargo\bin\cargo.exe
もしPATHが通っていない場合は、以下を~/.bashrcや~/.zshrcに追加します:
export PATH="$HOME/.cargo/bin:$PATH"
新しいプロジェクトを作成する
実行可能プロジェクトの作成
コマンド:
cargo new hello_world
何が起きる?
hello_worldディレクトリが作成される- 必要なファイルが自動生成される
- Gitリポジトリが初期化される(自動)
作成されるファイル構造:
hello_world/
├── Cargo.toml # プロジェクト設定ファイル
├── .git/ # Gitリポジトリ
├── .gitignore # Git除外設定
└── src/
└── main.rs # メインのソースコード
ライブラリプロジェクトの作成
コマンド:
cargo new my_library --lib
違い:--libオプションを付けると、実行ファイルではなくライブラリプロジェクトになります。
ファイル構造:
my_library/
├── Cargo.toml
├── .git/
├── .gitignore
└── src/
└── lib.rs # ライブラリのメインファイル(main.rsではない)
初期コードを見てみよう
Cargo.toml(設定ファイル):
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
[dependencies]
シンプルな設定ファイルですね。
src/main.rs(ソースコード):
fn main() {
println!("Hello, world!");
}
最初から動くコードが用意されています。
基本的なコマンド
cargo build(ビルド)
プロジェクトをコンパイルします。
cd hello_world
cargo build
何が起きる?
- 依存関係をダウンロード(初回のみ)
- ソースコードをコンパイル
target/debug/に実行ファイルを生成
出力:
Compiling hello_world v0.1.0 (/path/to/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
実行ファイルの場所:
target/debug/hello_world # Linux/macOS
target/debug/hello_world.exe # Windows
cargo run(ビルド+実行)
ビルドして、すぐに実行します。
cargo run
出力:
Compiling hello_world v0.1.0 (/path/to/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
Running `target/debug/hello_world`
Hello, world!
開発中は、これが一番便利ですね。
cargo build –release(最適化ビルド)
リリース用の最適化されたビルドを作成します。
cargo build --release
違い:
- デバッグビルド(
cargo build):コンパイルが速い、実行が遅い、デバッグ情報あり - リリースビルド(
--release):コンパイルが遅い、実行が速い、サイズが小さい
出力先:
target/release/hello_world
性能差:
リリースビルドは、デバッグビルドの2〜10倍速く実行されることがあります。
cargo check(構文チェック)
コンパイルせずに、エラーチェックだけを行います。
cargo check
利点:
- ビルドより圧倒的に速い
- コードを書きながら頻繁にチェックできる
開発フロー:
コードを書く
↓
cargo check(エラー確認、数秒)
↓
修正
↓
cargo run(動作確認)
cargo test(テスト実行)
プロジェクト内のすべてのテストを実行します。
cargo test
詳しくは後述します。
cargo doc(ドキュメント生成)
コードからHTMLドキュメントを生成します。
cargo doc --open
--openオプションで、生成後にブラウザで自動的に開きます。
cargo clean(クリーンアップ)
targetディレクトリを削除します。
cargo clean
ビルド結果を削除して、ディスク容量を節約したいときに使います。
プロジェクト構造を理解する
Cargo.tomlファイル
Cargo.tomlは、プロジェクトの設定ファイルです(TOML形式)。
基本構造:
[package]
name = "my_project" # プロジェクト名
version = "0.1.0" # バージョン
edition = "2021" # Rustのエディション
authors = ["Your Name <you@example.com>"]
description = "A sample project"
license = "MIT"
# ここに依存ライブラリを追加
srcディレクトリ
ソースコードを格納するディレクトリです。
実行可能プロジェクト:
src/
└── main.rs # エントリーポイント(main関数)
ライブラリプロジェクト:
src/
└── lib.rs # ライブラリのルート
複数ファイルの構成:
src/
├── main.rs # メイン
├── lib.rs # ライブラリ部分
└── utils.rs # ユーティリティモジュール
targetディレクトリ
ビルド結果が格納されるディレクトリです。
target/
├── debug/ # デバッグビルド
│ ├── hello_world # 実行ファイル
│ └── deps/ # 依存関係のビルド結果
└── release/ # リリースビルド
└── hello_world
注意: .gitignoreに含まれているので、Gitには追加されません。
依存関係の管理

外部クレートの追加
crates.ioは、Rustの公式パッケージレジストリです。
例:乱数生成ライブラリ「rand」を追加
方法1:Cargo.tomlに直接書く
[dependencies]
rand = "0.8"
方法2:cargo addコマンド(Rust 1.62以降)
cargo add rand
自動的にCargo.tomlに追加されます。
バージョンの指定方法
完全一致:
rand = "=0.8.5"
互換バージョン(デフォルト):
rand = "0.8" # 0.8.0 〜 0.9.0未満
rand = "0.8.5" # 0.8.5 〜 0.9.0未満
範囲指定:
rand = ">=0.8, <0.9"
ワイルドカード:
rand = "0.8.*"
最新版:
rand = "*" # 非推奨(予期しない変更が入る)
依存関係のダウンロード
自動ダウンロード:
cargo build
初回ビルド時に、必要な依存関係が自動的にダウンロードされます。
手動ダウンロード:
cargo fetch
ビルドせずに、依存関係だけをダウンロードします。
Cargo.lockファイル
Cargo.lockは、実際に使用されたバージョンを記録したファイルです。
特徴:
- 自動生成される
- 依存関係の正確なバージョンを固定
- チーム開発で全員が同じバージョンを使用できる
扱い方:
- 実行可能プロジェクト: Gitにコミットする
- ライブラリプロジェクト: Gitにコミットしない(
.gitignoreに追加)
依存関係の更新
小規模な更新(互換範囲内):
cargo update
Cargo.tomlの範囲内で、最新版に更新します。
特定のクレートのみ更新:
cargo update -p rand
メジャーバージョンアップ:
# Cargo.tomlを手動で変更
rand = "0.9"
その後、cargo buildで新しいバージョンがダウンロードされます。
実践例:簡単なプロジェクトを作ろう
例1:乱数ゲーム
プロジェクト作成:
cargo new guessing_game
cd guessing_game
依存関係を追加:
cargo add rand
src/main.rs:
use rand::Rng;
use std::io;
fn main() {
println!("数当てゲーム!");
// 1〜100のランダムな数を生成
let secret_number = rand::thread_rng().gen_range(1..=100);
loop {
println!("数を入力してください(1-100):");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("読み込みエラー");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("数字を入力してください!");
continue;
}
};
match guess.cmp(&secret_number) {
std::cmp::Ordering::Less => println!("もっと大きいです!"),
std::cmp::Ordering::Greater => println!("もっと小さいです!"),
std::cmp::Ordering::Equal => {
println!("正解!おめでとう!");
break;
}
}
}
}
実行:
cargo run
動作するゲームが完成しました!
例2:Webスクレイピング
プロジェクト作成:
cargo new web_scraper
cd web_scraper
依存関係を追加:
cargo add reqwest --features blocking
cargo add scraper
Cargo.toml(確認):
[dependencies]
reqwest = { version = "0.11", features = ["blocking"] }
scraper = "0.18"
src/main.rs:
use reqwest::blocking::get;
use scraper::{Html, Selector};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Webページを取得
let url = "https://example.com";
let response = get(url)?;
let body = response.text()?;
// HTMLをパース
let document = Html::parse_document(&body);
// h1タグを抽出
let h1_selector = Selector::parse("h1").unwrap();
println!("見つかったh1タグ:");
for element in document.select(&h1_selector) {
println!("- {}", element.text().collect::<String>());
}
Ok(())
}
実行:
cargo run
Webページから情報を取得できました!
例3:コマンドラインツール
プロジェクト作成:
cargo new file_counter
cd file_counter
依存関係を追加:
cargo add clap --features derive
src/main.rs:
use clap::Parser;
use std::fs;
#[derive(Parser)]
#[command(name = "file_counter")]
#[command(about = "指定ディレクトリ内のファイル数をカウント")]
struct Args {
/// カウント対象のディレクトリ
#[arg(short, long, default_value = ".")]
dir: String,
}
fn main() -> std::io::Result<()> {
let args = Args::parse();
let mut count = 0;
for entry in fs::read_dir(&args.dir)? {
let entry = entry?;
if entry.file_type()?.is_file() {
count += 1;
}
}
println!("{}内のファイル数: {}", args.dir, count);
Ok(())
}
実行:
# デフォルト(カレントディレクトリ)
cargo run
# ディレクトリ指定
cargo run -- --dir /path/to/directory
コマンドラインオプションが使えるツールができました!
テストの実行
ユニットテストの書き方
src/lib.rs(または任意の.rsファイル):
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, 1), 0);
}
}
テスト実行:
cargo test
出力:
running 2 tests
test tests::test_add ... ok
test tests::test_add_negative ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
統合テスト
testsディレクトリに配置:
project/
├── Cargo.toml
├── src/
│ └── lib.rs
└── tests/
└── integration_test.rs
tests/integration_test.rs:
use my_library::add;
#[test]
fn test_add_integration() {
assert_eq!(add(10, 20), 30);
}
テストのフィルタリング
特定のテストだけ実行:
cargo test test_add
特定のモジュールのみ:
cargo test tests::
テストオプション
並列実行を無効化:
cargo test -- --test-threads=1
出力を表示:
cargo test -- --nocapture
通常は成功したテストのprintln!は表示されませんが、これで表示されます。
ドキュメントの生成
ドキュメントコメントの書き方
関数のドキュメント:
/// 2つの数を足し算します。
///
/// # 例
///
/// ```
/// let result = my_library::add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
モジュールのドキュメント:
//! このクレートは数学関数を提供します。
//!
//! # 使い方
//!
//! ```
//! use my_library::add;
//!
//! let sum = add(1, 2);
//! ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
ドキュメント生成
生成:
cargo doc
生成して開く:
cargo doc --open
ブラウザでtarget/doc/プロジェクト名/index.htmlが開きます。
依存関係のドキュメントも含める
cargo doc --no-deps # 自分のプロジェクトのみ
cargo doc # 依存関係も含める(デフォルト)
ワークスペース
ワークスペースとは
複数のパッケージを一つのプロジェクトで管理する仕組みです。
使用例:
- 本体アプリとCLIツールを同じリポジトリで管理
- ライブラリと使用例を一緒に管理
ワークスペースの作成
ディレクトリ構造:
my_workspace/
├── Cargo.toml # ワークスペースの設定
├── app/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
└── library/
├── Cargo.toml
└── src/
└── lib.rs
my_workspace/Cargo.toml:
[workspace]
members = [
"app",
"library"
]
app/Cargo.toml:
[package]
name = "app"
version = "0.1.0"
edition = "2021"
library = { path = “../library” }
ワークスペースでのビルド
すべてビルド:
cargo build
特定のパッケージのみ:
cargo build -p app
cargo build -p library
特定のパッケージを実行:
cargo run -p app
設定とカスタマイズ
ビルドプロファイル
Cargo.tomlでカスタマイズ:
[profile.dev]
opt-level = 0 # 最適化レベル(0-3)
opt-level = 3 # 最大最適化 lto = true # Link Time Optimization codegen-units = 1 # 並列コンパイル数(少ないほど最適化される)
フィーチャーフラグ
条件付きコンパイル:
Cargo.toml:
[features]
default = ["json"]
json = ["serde_json"]
xml = ["quick-xml"]
serde_json = { version = “1.0”, optional = true } quick-xml = { version = “0.31”, optional = true }
使用側:
# デフォルトフィーチャー(json)
cargo build
# xmlフィーチャーを有効化
cargo build --features xml
# すべてのフィーチャーを有効化
cargo build --all-features
# デフォルトフィーチャーを無効化
cargo build --no-default-features
カスタムコマンド
cargo-expandのインストール:
cargo install cargo-expand
マクロ展開を表示:
cargo expand
よく使うサブコマンドまとめ
| コマンド | 説明 |
|---|---|
cargo new | 新規プロジェクト作成 |
cargo build | ビルド |
cargo run | ビルド+実行 |
cargo check | エラーチェックのみ |
cargo test | テスト実行 |
cargo doc | ドキュメント生成 |
cargo clean | ビルド結果を削除 |
cargo add | 依存関係を追加 |
cargo update | 依存関係を更新 |
cargo publish | crates.ioに公開 |
cargo install | バイナリをインストール |
cargo search | crates.ioを検索 |
cargo tree | 依存関係ツリー表示 |
トラブルシューティング
問題1:ビルドが遅い
原因:
依存関係が多い、フルビルドしている。
解決策:
インクリメンタルコンパイルを有効化(通常は有効):
[profile.dev]
incremental = true
cargo checkを活用:
cargo check # フルビルドより速い
並列コンパイル数を増やす:
cargo build -j 8 # 8並列
問題2:依存関係の競合
症状:
error: failed to select a version for `serde`
解決策:
依存関係ツリーを確認:
cargo tree
バージョンを明示的に指定:
[dependencies]
serde = "=1.0.150"
問題3:古いバージョンが使われる
解決策:
Cargo.lockを削除して再ビルド:
rm Cargo.lock
cargo build
強制的に最新版に更新:
cargo update
問題4:ディスク容量不足
原因:targetディレクトリが肥大化。
解決策:
クリーンアップ:
cargo clean
古いプロジェクトを一括クリーン:
cargo install cargo-cache
cargo cache --autoclean
よくある質問
Q1: cargo buildとcargo runの違いは?
A:
cargo build: ビルドのみ(実行ファイルを生成)
cargo run: ビルド+実行(開発中に便利)
実行だけしたい場合は、直接実行ファイルを起動することもできます:
./target/debug/プロジェクト名
Q2: releaseビルドはどれくらい速い?
A: 用途によりますが、2〜10倍速くなることがあります。
数値計算や画像処理など、CPU負荷の高い処理ほど差が大きくなります。
ベンチマーク時は必ずreleaseビルドを使いましょう。
Q3: Cargo.lockはGitにコミットすべき?
A:
実行可能プロジェクト: YES(コミットする)
ライブラリプロジェクト: NO(.gitignoreに追加)
実行可能プロジェクトでは、全員が同じバージョンの依存関係を使うべきです。ライブラリは、使う側が依存関係を決定します。
Q4: crates.ioにない非公開ライブラリを使いたい
A: Gitリポジトリやローカルパスを指定できます。
Gitリポジトリから:
[dependencies]
my_lib = { git = "https://github.com/user/my_lib" }
特定のブランチ:
my_lib = { git = "https://github.com/user/my_lib", branch = "develop" }
ローカルパス:
my_lib = { path = "../my_lib" }
Q5: ビルドのキャッシュはどこに?
A: targetディレクトリと~/.cargoディレクトリです。
target/: プロジェクトごとのビルド結果
~/.cargo/registry/: ダウンロードした依存関係
~/.cargo/git/: Gitから取得した依存関係
ディスク容量が気になる場合は、cargo cleanやcargo cacheで削除できます。
まとめ
Cargoは、Rustのプロジェクト管理・ビルド・テスト・ドキュメント生成をすべて一つで行える、強力で便利なツールです。
この記事のポイント:
- CargoはRustの公式パッケージマネージャー兼ビルドシステム
cargo newで簡単にプロジェクト作成cargo runでビルド+実行が一発- 依存関係は
Cargo.tomlに書くだけで自動管理 - crates.ioに100万以上のライブラリが公開されている
cargo testでテストが簡単に実行できるcargo docでドキュメントを自動生成- リリースビルド(
--release)で実行速度が大幅向上 - ワークスペースで複数パッケージを管理可能
- フィーチャーフラグで条件付きコンパイル
- Rust開発に必要なものがすべて揃っている
Cargoは、Rustプログラミングをする上で欠かせないツールです。他の言語のように、パッケージ管理とビルドツールを別々に学ぶ必要がなく、Cargoひとつですべてが完結するのが大きな魅力なんです。
最初は覚えることが多いように感じるかもしれませんが、基本的なコマンド(new、run、build、test)を使えるようになれば、快適に開発できるようになりますよ。
まずはcargo newでプロジェクトを作って、簡単なコードを書いてcargo runで実行してみてください。Rustプログラミングの楽しさを実感できるはずです!
Cargoをマスターして、効率的なRust開発を楽しんでいきましょう!

コメント