Rustのcargo.tomlを見ればパッケージがわかる

Rustのパッケージ管理についてはcrates.ioがあります。よく間違えてcrate.ioと入力してしまって違うページに飛んでしまう経験がありますよね(ない)。ややこしいんですが、ドメイン名にはcrateを冠しているものの、実際に管理している単位は「パッケージ」なのです。勉強がてら、ちょっと整理します。

モジュールとクレートとパッケージ

プログラムの構成要素としては、モジュールが最も小さい。モジュールはそれだけで木構造を作ることができる。 クレートは、「ターゲット」をコンパイルした結果、できるもの。と書いてあるのを見て、「ターゲット」?と思ったあなた、大丈夫、わたしはあなたの味方です。 以下を見よう。

doc.rust-lang.org

並べてみると

  • Library
  • Binaries
  • Examples
  • Tests
  • Benchmarks

とあります。Benchmarksってあるんだ。。。LibraryとBinariesは割とおなじみですよね。Libraryはlib.rsを起点にしたソースコード群で、Binariesはmain.rsを起点にしたものになります。で、lib.rsから作られるのが「ライブラリクレート」、main.rsから作られるのが「バイナリクレート」ということになるわけです。なるほど!(自分で書いて自分で納得するタイプ)

1つのターゲットはcargo.tomlでいう1つのセクションに対応していますが、examplesのように複数設定できるものもたくさんありますね。というかライブラリクレート以外は複数作れるのか。バイナリクレートが複数作れると便利ですよね、きっと。柔軟なパッケージ構成ができそう。

そして「パッケージ」は、クレートの元になる「ターゲット」やその他の依存ライブラリ(こちらは正確にはクレートですかね)が集まったものたち、という感じなんでしょうか。パッケージの設定はcargo.tomlに集まっているので、裏を返すとこのファイルに書けることがパッケージでできること、になるわけですね、きっと。

doc.rust-lang.org

name

今回の件を調べる直接のきっかけになったのは、クレート名ってどこできめられるんだっけ、というのがよくわからなくなってしまったからです。普段、lib.rsmain.rsも両方作るようにしていて、main側からlib側のクレートをuseするというふうに作っていたんですが、use文で指定している名前がおかしいというエラーが出てしまったんですよ。結局、libターゲットとmainターゲットにあるnameフィールドに設定するのだとわかったんですが、罠っぽいのは、両方のセクションが存在しない場合は、デフォルトとしてpackageセクションにあるname fieldが使われるということです。lib.rsmain.rsも両方作る人はちゃんと対応したlibセクションとbinセクションを作った方がいいですね。