Rustのcargo newとcargo initの違いを徹底解説!プロジェクト作成コマンドの使い分け完全ガイド
生徒
「Rustでプロジェクトを作るときにcargo newとcargo initの2つがあるって聞いたんですが、何が違うんですか?」
先生
「どちらもRustのプロジェクトを作成するCargoのコマンドですが、使う場面が異なります。cargo newは新しいディレクトリを作ってプロジェクトを初期化し、cargo initは既存のディレクトリをプロジェクト化します。」
生徒
「なるほど。じゃあ、どういう時にどちらを使えばいいんですか?」
先生
「通常はcargo newを使ってゼロからプロジェクトを作ることが多いです。でも、すでにフォルダがあってそこをRustプロジェクトにしたい場合はcargo initが便利です。詳しく見ていきましょう!」
1. Cargoとは?Rustのビルドツールとパッケージマネージャー
Rustの開発ではCargoという公式ツールを使ってプロジェクト管理とビルドを行います。Cargoは、プロジェクトの作成、依存関係の管理、コンパイル、テストの実行など、Rust開発に必要な機能をすべて統合したビルドツールであり、パッケージマネージャーでもあります。
Cargoを使うことで、Cargo.tomlというファイルにプロジェクトのメタデータや依存ライブラリ(クレート)の情報を記述し、一貫した方法でRustプロジェクトを管理できます。このCargoには、プロジェクトを初期化するための2つのコマンドcargo newとcargo initがあり、初心者はこの違いに戸惑うことがあります。
Rustでは、プロジェクトディレクトリ構造やファイル配置に一定の規約があり、Cargoがその規約に従ったプロジェクトを自動生成してくれます。これにより、開発者は環境設定に悩むことなく、すぐにコーディングを始められるのがRustの大きな利点です。
2. cargo newコマンドの基本的な使い方とプロジェクト作成
cargo newは、新しいRustプロジェクトを作成するための最も基本的なコマンドです。このコマンドを実行すると、指定した名前の新しいディレクトリが作成され、その中にRustプロジェクトの基本構造が自動的に生成されます。
実際にプロジェクトを作成してみましょう。ターミナルやコマンドプロンプトで次のコマンドを実行します。
cargo new hello_rust
このコマンドを実行すると、hello_rustという名前のディレクトリが作成され、その中に以下のファイルとディレクトリが生成されます。
Cargo.toml- プロジェクトの設定ファイル(マニフェストファイル)src/main.rs- メインのRustソースコードファイル.gitignore- Gitの除外設定ファイル(自動的にGitリポジトリとして初期化)
生成されたsrc/main.rsには、シンプルなHello Worldプログラムが既に書かれています。
fn main() {
println!("Hello, world!");
}
このプロジェクトは、cd hello_rustでディレクトリに移動してからcargo runを実行すれば、すぐにビルドして実行できます。
Compiling hello_rust v0.1.0
Finished dev [unoptimized + debuginfo] target(s)
Running `target/debug/hello_rust`
Hello, world!
cargo newの特徴は、プロジェクト名のディレクトリを新規作成する点です。既存のディレクトリがある場合は、このコマンドではエラーになります。
3. cargo initコマンドの基本的な使い方と既存ディレクトリの活用
cargo initは、既に存在するディレクトリをRustプロジェクトとして初期化するコマンドです。新しいディレクトリを作成するのではなく、現在のディレクトリ、または指定したディレクトリ内にプロジェクトファイルを生成します。
まず、任意のディレクトリを作成して、その中でcargo initを実行してみましょう。
mkdir my_project
cd my_project
cargo init
このコマンドを実行すると、my_projectディレクトリの中にcargo newと同じようにCargo.tomlやsrc/main.rsが生成されます。既にディレクトリが存在していても、その中にファイルがない場合や、Rustプロジェクトとして競合しないファイルしかない場合は問題なく初期化できます。
また、カレントディレクトリではなく、特定のディレクトリを指定して初期化することも可能です。
cargo init existing_folder
この場合、existing_folderというディレクトリが既に存在していれば、その中にプロジェクトファイルが生成されます。もしディレクトリが存在しない場合は、cargo newと同じように新規作成されます。
cargo initは、既にREADMEファイルやドキュメントファイルがあるディレクトリをRustプロジェクトにしたい場合や、Gitリポジトリを先に作成してからRustプロジェクトを追加したい場合に便利です。
4. cargo newとcargo initの具体的な違いと使い分けのポイント
cargo newとcargo initの最も大きな違いは、新しいディレクトリを作成するかどうかです。しかし、それ以外にも細かな違いがあります。
| 項目 | cargo new | cargo init |
|---|---|---|
| ディレクトリ作成 | 新しいディレクトリを作成する | 既存のディレクトリを使用する |
| 実行場所 | 親ディレクトリから実行 | 対象ディレクトリ内で実行可能 |
| 使用シーン | 新規プロジェクトをゼロから作成 | 既存フォルダをプロジェクト化 |
| Git初期化 | 自動的に初期化される | 自動的に初期化される |
実際の開発では、cargo newを使うケースが圧倒的に多いです。新しいプロジェクトを始めるときは、名前を決めてcargo new プロジェクト名とするだけで、すべての初期設定が完了するからです。
一方、cargo initが役立つのは、次のような場面です。
- 既にGitリポジトリを作成済みで、そこにRustプロジェクトを追加したい
- ドキュメントやREADMEを先に作成してから、Rustコードを追加したい
- 既存のディレクトリ構造を維持しながらRustプロジェクト化したい
- 複数のサブプロジェクトを管理するワークスペース環境を構築したい
どちらのコマンドも、最終的に生成されるプロジェクト構造は同じです。違いは、ディレクトリをどう扱うかという点だけなので、状況に応じて使い分けましょう。
5. バイナリプロジェクトとライブラリプロジェクトの作り方
Rustのプロジェクトには、実行可能なプログラムを作るバイナリプロジェクトと、他のプロジェクトから利用されるライブラリを作るライブラリプロジェクトの2種類があります。デフォルトでは、cargo newもcargo initもバイナリプロジェクトを作成します。
ライブラリプロジェクトを作成したい場合は、--libオプションを付けて実行します。
cargo new my_library --lib
このコマンドを実行すると、src/main.rsの代わりにsrc/lib.rsが生成されます。lib.rsには、ライブラリのエントリーポイントとなる関数やモジュールを定義します。
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
同様に、cargo initでもライブラリプロジェクトを作成できます。
cargo init --lib
バイナリプロジェクトとライブラリプロジェクトの違いは、プログラムとして実行できるかどうかです。バイナリプロジェクトはcargo runで実行でき、ライブラリプロジェクトは他のプロジェクトから依存関係として利用されます。開発するソフトウェアの種類に応じて、適切なプロジェクトタイプを選択しましょう。
6. バージョン管理システムとの連携とGit初期化の制御
cargo newとcargo initは、デフォルトでプロジェクトをGitリポジトリとして初期化します。これにより、.gitディレクトリと.gitignoreファイルが自動的に作成され、すぐにバージョン管理を始められます。
しかし、場合によってはGit初期化を行いたくないこともあります。例えば、既にGitリポジトリの中にサブプロジェクトを作成する場合や、別のバージョン管理システムを使用する場合です。そのような時は、--vcs noneオプションを使います。
cargo new my_project --vcs none
このコマンドを実行すると、Git関連のファイルが生成されず、純粋なRustプロジェクトのファイル構造だけが作成されます。また、Cargoは親ディレクトリを確認し、既にGitリポジトリ内にいる場合は自動的にGit初期化をスキップする賢い挙動も持っています。
Gitの代わりに他のバージョン管理システムを使いたい場合は、--vcsオプションで指定できます。
cargo new my_project --vcs hg
この例では、Mercurial(hg)をバージョン管理システムとして使用するプロジェクトが作成されます。ただし、実際の開発現場ではGitが圧倒的に多く使われているため、特別な理由がない限りデフォルトのGit設定で問題ありません。
7. プロジェクト名の命名規則とRustの慣習
Rustのプロジェクト名には、いくつかの命名規則と慣習があります。cargo newやcargo initでプロジェクトを作成する際、プロジェクト名は小文字とアンダースコアを使ったスネークケースで指定するのが一般的です。
例えば、my_awesome_projectやweb_serverのような名前が推奨されます。ハイフン(-)を使ったmy-projectのような名前も許可されていますが、Rustのコード内でクレート名を参照する際にはアンダースコアに変換されるため、最初からアンダースコアを使う方が混乱が少ないです。
Cargoは、不適切な名前を指定するとワーニングを表示します。例えば、大文字を含む名前や、数字で始まる名前などは避けるべきです。プロジェクト名は、そのままクレート名として使用されるため、Rustのパッケージレジストリであるcrates.ioで公開する可能性も考慮して、わかりやすく一意な名前を選びましょう。
また、プロジェクト名には予約語を使用できません。testやcoreなど、Rustの標準ライブラリで使用されている名前は避けてください。Cargoが自動的にエラーを表示してくれるので、間違った名前を付けてしまう心配はほとんどありませんが、最初から適切な名前を考える習慣をつけることが重要です。
8. エディション指定とRustのバージョン管理
Rustにはエディションという概念があり、言語仕様の大きな変更を管理しています。現在、Rust 2015、Rust 2018、Rust 2021、そしてRust 2024の各エディションが存在します。cargo newやcargo initで作成されるプロジェクトは、実行時点での最新エディションが自動的に設定されます。
エディションの設定は、生成されたCargo.tomlファイルに記述されます。
[package]
name = "my_project"
version = "0.1.0"
edition = "2021"
[dependencies]
特定のエディションを指定してプロジェクトを作成したい場合は、--editionオプションを使います。
cargo new my_project --edition 2018
エディションは後方互換性を保ちながら、新しい機能や改善を導入するための仕組みです。古いエディションで書かれたコードも、新しいバージョンのRustコンパイラで問題なくコンパイルできます。プロジェクトのエディションはCargo.tomlを編集すれば後から変更できますが、エディション間の違いによってコードの修正が必要になることもあるため、プロジェクト開始時に適切なエディションを選択することが望ましいです。
最新のエディションを使うことで、Rustの最新機能や言語改善の恩恵を受けられるため、特別な理由がない限りデフォルト設定で問題ありません。
9. 実践的な使い分けシナリオとプロジェクト作成のベストプラクティス
実際の開発現場では、cargo newとcargo initをどのように使い分けるべきでしょうか。いくつかの典型的なシナリオを見てみましょう。
最も一般的なケースです。新しいコマンドラインツールやWebアプリケーションを作る場合は、迷わずcargo new project_nameを使いましょう。これだけで、すぐに開発を始められる環境が整います。
例えば、ドキュメントやスクリプトが既にあるリポジトリに、Rustで書かれたツールを追加したい場合です。この場合、リポジトリのルートディレクトリでcargo initを実行すれば、既存のファイルを残したままRustプロジェクトを追加できます。
大規模なプロジェクトでは、複数のクレートを1つのリポジトリで管理するワークスペースを使うことがあります。親ディレクトリにCargo.tomlを配置し、サブディレクトリに複数のプロジェクトを作成する場合、cargo init --libやcargo new sub_projectを組み合わせて使います。
また、プロジェクト作成後に必ず確認すべきポイントもあります。Cargo.tomlファイルには、プロジェクトのメタデータとして名前、バージョン、著者情報などが記述されています。公開ライブラリを作る場合は、descriptionやlicenseフィールドも追加しておきましょう。
さらに、開発環境の設定として.cargo/config.tomlを作成すれば、ビルドオプションやリンカー設定をプロジェクト固有にカスタマイズできます。これはcargo newやcargo initでは自動生成されないため、必要に応じて手動で作成します。
10. トラブルシューティングとよくあるエラーへの対処法
cargo newやcargo initを使う際に、いくつかの典型的なエラーに遭遇することがあります。それらの原因と解決方法を理解しておきましょう。
cargo newで既存のディレクトリ名を指定すると、このエラーが表示されます。解決策は2つあります。1つは別の名前を使うこと、もう1つはcargo initを使って既存ディレクトリを初期化することです。
プロジェクト名に使用できない文字が含まれている場合のエラーです。プロジェクト名は、小文字のアルファベット、数字、アンダースコア、ハイフンのみが使用でき、数字で始めることはできません。適切な名前に変更して再実行しましょう。
既にRustプロジェクトとして初期化されているディレクトリでcargo initを実行すると、このエラーが出ます。このディレクトリは既にプロジェクトなので、再初期化する必要はありません。
これらのエラーは、Cargoがプロジェクトの整合性を保つための安全機構です。エラーメッセージをよく読めば、問題の原因と解決方法がわかるようになっています。
また、Cargoのバージョンが古い場合、一部のオプションや機能が使えないことがあります。rustup updateを実行して、Rustツールチェーンを最新版に更新することで、多くの問題が解決します。Rustは活発に開発が続いており、定期的なアップデートによって新機能の追加やバグ修正が行われているため、常に最新版を使うことをお勧めします。