Rustでアプリケーションを開発する際、最も頻繁に利用するコマンドの一つがcargo runです。
ソースコードの変更を検知し、コンパイルを行い、そのまま実行ファイルを起動するという一連の流れを自動化してくれるこのコマンドは、Rust開発者のワークフローにおいて中心的な役割を果たしています。
しかし、単純にプログラムを動かすだけでなく、コマンドライン引数の渡し方や、ビルドプロファイルの切り替え、さらにはワークスペース内での特定のバイナリの実行など、cargo runには開発効率を劇的に向上させるための多彩なオプションが備わっています。
本記事では、2026年現在のRust開発シーンに即した、cargo runの基礎から応用、そして最適化のテクニックまでを詳しく解説します。
cargo runの基本動作と内部メカニズム
cargo runコマンドの役割は、単に「プログラムを実行する」だけではありません。
Cargoは実行前にプロジェクトの状態を確認し、必要であれば依存関係の解決とコンパイルを自動的に行います。
コンパイルと実行の自動連携
Rustのソースコードを変更した後にcargo runを入力すると、Cargoはまず指紋(Fingerprint)を確認します。
これはソースファイルやCargo.tomlに変更があったかを判定する仕組みです。
変更があればインクリメンタルビルドが走り、変更がなければ前回のビルド済みバイナリを即座に実行します。
これにより、開発者は「コンパイルコマンドを打ってから実行コマンドを打つ」という手間から解放されます。
特に大規模なプロジェクトでは、どのバイナリが最新の状態であるかを意識せずに済むため、開発サイクル(Edit-Compile-Run)の高速化に大きく貢献します。
ターゲットディレクトリの管理
ビルドされたバイナリは通常、プロジェクトルートにあるtarget/debug/ディレクトリに格納されます。
cargo runはこのディレクトリ内にある実行ファイルを自動的に探し出し、パスを通さずとも起動してくれます。
アプリケーションへの引数の渡し方
コマンドラインツールを開発している場合、プログラムに対して引数(Arguments)を渡したい場面が多々あります。
しかし、単にcargo run arg1 arg2と入力すると、その引数がCargo自体への引数なのか、実行されるプログラムへの引数なのかをCargoが判別できなくなります。
セパレータ「–」の活用
プログラムに引数を渡す際は、ハイフン2つのセパレータ(–)を使用するのがRustの標準的な作法です。
# cargo run [cargoへのオプション] -- [プログラムへの引数]
cargo run -- --help
このコマンドでは、--helpはCargoに対してではなく、実行されるRustバイナリに対して渡されます。
もし--を付けずにcargo run --helpと実行した場合、Cargo自体のヘルプ画面が表示されてしまいます。
プログラム側での引数の受け取り
Rustプログラム内でこれらの引数を受け取るには、標準ライブラリのstd::env::argsを使用します。
use std::env;
fn main() {
// コマンドライン引数をVectorとして収集
let args: Vec<String> = env::args().collect();
// 最初の要素は実行ファイルのパスなので、1番目以降を表示
if args.len() > 1 {
println!("受け取った引数: {:?}", &args[1..]);
} else {
println!("引数は渡されませんでした。");
}
}
cargo run -- hello rust 2026
# 出力結果
# 受け取った引数: ["hello", "rust", "2026"]
ビルド最適化とプロファイルの切り替え
cargo runはデフォルトでデバッグプロファイルを使用してビルドを行います。
しかし、パフォーマンス測定や本番環境に近い動作確認を行いたい場合には、最適化設定を変更する必要があります。
Releaseモードでの実行
最適化を有効にした状態でプログラムを実行するには、--releaseフラグを付与します。
cargo run --release
Releaseモードでは、コンパイラが高度な最適化(デッドコードの削除、関数のインライン化など)を行うため、実行速度が劇的に向上します。
一方で、ビルド時間はデバッグモードよりも長くなり、パニック時のバックトレース情報が簡略化されるという特徴があります。
デバッグモードとリリースモードの比較
| 項目 | デバッグモード (デフォルト) | リリースモード (–release) |
|---|---|---|
| 最適化レベル | 低 (0) | 高 (3) |
| コンパイル速度 | 高速 | 低速 |
| 実行速度 | 低速 | 高速 |
| デバッグ情報 | 完全に保持 | 最小限 |
| 整数オーバーフロー | ランタイムチェックあり | チェックなし (ラップ) |
開発中は素早いフィードバックを得るためにデフォルト設定を使い、計算負荷の高い処理の検証時のみリリースモードを利用するのが効率的です。
ワークスペースと複数バイナリの制御
プロジェクトが成長し、複数のバイナリターゲットを持つようになると、単なるcargo runでは「どのプログラムを動かすべきか」をCargoが判断できなくなることがあります。
実行バイナリの指定
プロジェクト内に複数のsrc/bin/*.rsが存在する場合や、Cargo.tomlで複数の[[bin]]セクションを定義している場合は、--binオプションで名前を指定します。
cargo run --bin server_app
ワークスペース内での特定パッケージの実行
Rustのワークスペース機能を利用して複数のクレートを管理している場合、ルートディレクトリから特定のパッケージを実行するには-p(または--package)フラグを使用します。
cargo run -p auth-service -- --port 8080
サンプルコードの実行
ライブラリ開発において、examples/ディレクトリ配下に作成したサンプルコードを実行したい場合は、--exampleオプションが便利です。
cargo run --example basic_usage
これにより、ライブラリの利用シーンを想定した動作確認が容易になります。
条件付きコンパイルと機能(Features)の制御
Rustには「Features」という、コンパイル時に含める機能を切り替える仕組みがあります。
cargo run実行時にも、これらの機能を動的に有効化できます。
特定機能の有効化
例えば、特定のロギング機能や実験的なAPIをexperimentalというFeatureで管理している場合、次のように実行します。
cargo run --features experimental
複数の機能を有効にしたい場合は、カンマ区切りで指定するか、--all-featuresを使用してすべての機能を有効にすることも可能です。
# 特定の機能を複数有効化
cargo run --features "feature_a,feature_b"
# すべての機能を有効化して実行
cargo run --all-features
開発効率を高めるための応用テクニック
cargo runをより便利に使いこなすために、周辺ツールや環境変数の活用についても触れておきます。
cargo-watchによる自動実行
コードを保存するたびに手動でcargo runを打ち込むのは非効率です。
サードパーティ製ツールのcargo-watchを導入すると、ファイルの変更を検知して自動的に再実行してくれます。
# cargo-watchのインストール(未導入の場合)
cargo install cargo-watch
# ファイル変更時に自動で run を実行
cargo watch -x run
このツールを併用することで、Webサーバーの開発やGUIアプリケーションのプレビューが格段にスムーズになります。
環境変数の注入
実行時に環境変数を動的に渡したい場合は、コマンドの先頭に変数を記述します。
これはRustのdotenvなどのクレートを使わず、OSの機能を利用する方法です。
RUST_LOG=debug cargo run
特にRUST_BACKTRACE=1を付与して実行することは、エラー発生時の原因究明において非常に重要です。
# パニック発生時に詳細なスタックトレースを表示
RUST_BACKTRACE=1 cargo run
コンパイル時間の短縮に向けたアプローチ
Rustは強力な型システムと最適化の代償として、コンパイル時間が長くなりがちです。
cargo runを待つ時間を減らすために、いくつかの設定を見直す価値があります。
リンカの変更
2026年現在、多くのプラットフォームでデフォルトのリンカよりも高速なリンカ(MoldやLLDなど)が利用可能です。
.cargo/config.tomlを設定し、リンクフェーズを高速化することで、cargo runの待ち時間を短縮できます。
ターゲットディレクトリの共有化
複数のプロジェクトで同じ依存関係を使用している場合、共有のビルドキャッシュを利用することで、初回のコンパイル時間を大幅に削減できる場合があります。
これはCARGO_TARGET_DIR環境変数で設定可能です。
まとめ
cargo runは、Rust開発における「ビルド」と「実行」の橋渡しをする非常に強力なコマンドです。
基本的な使い方をマスターするだけでなく、セパレータ「–」を用いた引数の受け渡しや、Releaseプロファイルの適切な使い分け、そしてFeaturesやワークスペースの管理を習得することで、開発効率は飛躍的に向上します。
また、cargo-watchのような周辺ツールを組み合わせることで、Rustの堅牢さを享受しながら、LL言語のような軽快なフィードバックサイクルを実現することも可能です。
本記事で紹介したテクニックを活用し、2026年のモダンなRust開発をより快適に進めていきましょう。
