パッケージとクレート
最初に学ぶモジュールシステムの要素は、パッケージとクレートです。
クレート (crate) は、Rustコンパイラが一度に考慮する最小限のコードです。
cargoを実行するのではなく、(ちょうど第1章の「Rustプログラムを書いて走らせる」節でやったように)単一のソースコードファイルを渡してrustcを実行した場合でも、
コンパイラはそのファイルをクレートとしてみなします。
クレートはモジュールを含むことができ、モジュールは、クレートとともにコンパイルされる他のファイル内で定義することができます。
このことについてはこれからの節で見ていきます。
クレートは2種類の形態のうちいずれかです: バイナリクレートか、ライブラリクレートです。
バイナリクレート (binary crate) は、コマンドラインプログラムやサーバなどの実行可能形式にコンパイルされ、実行することができるプログラムです。
どのバイナリクレートも、その実行可能形式が実行されたときに何が起きるかを定義するmainと呼ばれる関数を持たなくてはなりません。
今まで作ってきたクレートはすべてバイナリクレートでした。
ライブラリクレート (library crate) はmain関数を持たず、実行可能形式へとコンパイルされません。
代わりに、複数のプロジェクトで共有されることを想定した機能を定義するものです。
例えば、第2章で使用したrandクレートは乱数を生成する機能を提供します。
Rustaceanが「クレート」と言うときの、ほとんどの場合それはライブラリクレートのことであり、
Rustaceanは「クレート」を一般的なプログラミング概念の「ライブラリ」と同じ意味で使用します。
クレートルート (crate root) とは、Rustコンパイラの開始点となり、クレートのルートモジュールを作るソースファイルのことです(モジュールについて詳しくは「モジュールを定義して、スコープとプライバシーを制御する」のセクションで説明します)。
パッケージ (package) はある機能群を提供する1つ以上のクレートのまとまりです。 パッケージは Cargo.toml という、それらのクレートをどのようにビルドするかを説明するファイルを持っています。 Cargoは実のところパッケージで、今までコードをビルドするために使ってきたコマンドラインツールのためのバイナリクレートを含んでいます。 Cargoパッケージは、このバイナリクレートが依存するライブラリクレートも含んでいます。 他のプロジェクトはCargoライブラリクレートに依存することで、Cargoコマンドラインツールが使用するのと同じロジックを使用することもできます。
パッケージは好きなだけバイナリクレートを持つことができますが、ライブラリクレートは最大で1個しか持つことができません。 パッケージはライブラリクレートかバイナリクレートを問わず、少なくとも1個のクレートを持っていないといけません。
パッケージを作る時に何が起こるか見てみましょう。
まず、cargo newというコマンドを入力します:
$ cargo new my-project
Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs
cargo newを実行した後、Cargoが作成したものを確認するためにlsを使っています。
プロジェクトディレクトリ内には Cargo.toml ファイルがあり、これがパッケージを構成します。
また、main.rs を含む src ディレクトリもあります。
Cargo.toml をテキストエディタで開くと、src/main.rs については何も書いていないことに気づくでしょう。
Cargoは src/main.rs が、パッケージと同じ名前を持つバイナリクレートのクレートルートであるという慣習に従っています。
同じように、Cargoはパッケージディレクトリに src/lib.rs が含まれていたら、パッケージにはパッケージと同じ名前のライブラリクレートが含まれており、src/lib.rs がそのクレートルートなのだと判断します。
Cargoはクレートルートファイルを rustcに渡し、ライブラリやバイナリをビルドします。
今、このパッケージには src/main.rs しか含まれておらず、つまりこのパッケージはmy-projectという名前のバイナリクレートのみを持っているということです。
もしパッケージが src/main.rs と src/lib.rs を持っていたら、クレートは2つになります:どちらもパッケージと同じ名前を持つ、バイナリクレートとライブラリクレートです。
ファイルを src/bin ディレクトリに置くことで、パッケージは複数のバイナリクレートを持つことができます。それぞれのファイルが別々のバイナリクレートになります。