yikegaya’s blog

仕事関連(Webエンジニア)と資産運用について書いてます

写経しながら実践Rustプログラミング入門を読んだ(クレートとモジュール、Cargo)

前回に続いて写経しながら要点だけこの記事に書き起こす形で実践Rustプログラミング入門のPart1のCharpter3-3~を読んでみる。

www.shuwasystem.co.jp

クレートとモジュール

Rustでは、ソースコードのまとまりを表す構成要素として、クレートとモジュールがある。 クレートとは、他のプログラミング言語でいう「ライブラリ」や「パッケージ」と同義の言葉である。

外部クレートの導入

外部クレートはcargo.ioというレジストリなどで見つけることができる。 cargo searchコマンドにキーワードを付与して検索すれば関連のあるクレートを検索することもできる。

外部のクレートを利用するときには、プロジェクトファイル内のCargo.tomlに利用したいクレートの情報を追記する。 Cargo.tomlの編集が終わったら、あとはcargoコマンドがビルド時に外部クレートの依存関係を解決し、必要なものをダウンロードしてくれる。

クレートの作成

自分でクレートを作成する際には、cargo new --libsにプロジェクト名を付与して実行することで、必要最低限のテンプレートを準備することができる。

このコマンドでプロジェクトディレクトリを作成するとsrcディレクトリの中にはmain.rsではなくlib.rsが作成される。

入門モジュール

1つのファイルに複数のモジュールを作る

mod module_a {
    fn calc() {
    }
}

mod module_b {
    fn calc() {
    }
}

この方法を使うと1つのファイルに複数のモジュールを書くことができる。 しかしソースコードが長くなってくればファイルが混み合ってくるのでファイルを分割する。

lib.rs

mod module_a;
mod module_b;

さらにファイルが大きくなってきた場合はサブモジュールに分割する

src/module_b.rs

mod module_c;
mod module_d;

外のソースコードからモジュールの関数や構造体を使うにはpubキーワードをつける

pub mod module_a;
mod module_b;

外部クレート内のモジュールを利用する

use new_crate::module_a;

fn main() {
}

外部クレート名をルートディレクトリと見立てて、目的までのパスを「::」でつないで指定する。

これはルートディレクトリからの絶対パス指定だが相対パス指定する際はsuperやselfを使う。

use super::super::module_a;
use self::module_c::func_c;

Cargo

Cargoはビルドシステムの役割とパッケージマネージャの役割を持つ便利ツール

Cargo.tomlの中にパッケージの情報が含まれる。使用する外部クレートはCargo.tomlの[dependencies]の下に追記していく。

cargo init

cargo newコマンドとほとんど同じ。ディレクトリ内に既にRustのソースコードがあれば今後はそれらを使ってバイナリファイルを作る。存在しなければサンプルのソースコードを生成する。

cargo build

すべての外部クレートの依存関係を解決し、必要なクレートをダウンロードした上で、ビルドを行う。

オプションで--releaseを指定すると、releaseプロファイルでビルドされる。

cargo check

パッケージと全てのクレートに対して、コードのエラーチェックを行う。

cargo run

パッケージ内のバイナリファイルを実行する。もしビルドが必要な場合はビルドを行なった後にバイナリファイルを実行する。

cargo fix

ソースコードの中にある不備や改善点を発見し、修正を自動で適用する。

cargo clean

ビルドで作られた生成物を削除する。

オプションを何も設定せずにコマンドを実行すれば、そのディレクトリごと、全ての生成物を削除する。 --releaseオプションを指定すればreleaseプロファイルの生成物のみが、-p SPECもしくは--package SPECを追加すれば指定したSPECの生成物のみが削除できる。 --docを追加すればドキュメント関連のみが削除できる。

cargo doc

cargo docコマンドはパッケージに含まれているソースコードと全ての依存関係にあるクレートについてのドキュメントを生成する。

--openオプションを追加するとドキュメント作成完了後に自動でブラウザを開いてくれる。 依存関係のあるライブラリまでドキュメントを作成したくないときには--no-depsオプションを追加する。

cargo buildすると、開発したクレートはcrates.ioに公開されるが、ドキュメントに関してはDocs.rsに公開される。

cargo install

公開されているパッケージをインストールする。

デフォルトではcrates.ioからパッケージをダウンロードするが、--gitや--pathや--registryを使うことでダウンロード元を変更できる。 インストール先のディレクトリも、デフォルトでは~/.cargoだが--root DIRオプションで変更できる。

また、環境変数CARGO_INSTALL_ROOT、Cargo.toml内のinstall.root、環境変数CARGO_HOME内にパスを指定している場合はデフォルトのパスではなく変数で指定したパスにインストールされる。

cargo uninstall

cargo uninstallコマンドはcargo installでインストールしたバイナリファイルをアンインストールする。

creates.ioで公開されているクレートを検索できる。

cargo publish

ソースコードのパッケージを.crateファイルに圧縮し、クレートをcreates.ioにアップロードして公開する。

--dry-runオプションを追加すると、アップロードはせずに全てのチェックのみが走る。

Cargo.toml

Cargo.tomlはTOMLフォーマットで書かれたパッケージの設定ファイル。 内容はセクションごとに分かれており、パッケージ情報や依存クレート、コンパイラの設定などを記述することができる。

packageセクション

パッケージ自体の情報を記述することができる。

ターゲット関連セクション

指定したターゲットによって作れられるバイナリファイルをどのようにビルドするのかを設定できる。

セクション名 設定対象のバイナリファイル
lib ライブラリ形式のバイナリファイル
bin 実行形式のバイナリファイル
example exampleのバイナリファイル
test testのバイナリファイル
lib benchのバイナリファイル

libセクションは[lib]と大括弧で囲んでセクションを開始するが他のセクションは大括弧を二重で囲みbinと記して開始する。 このような二重で囲んだセクションはCargo.toml内で複数回書くことができ複数回書くことで、複数のバイナリファイルを作ることができる。

dependencies関連セクション

セクション名 説明
dependencies パッケージの依存関係
dev-dependencies example、tests、benchmarksのための依存関係
build-dependencies ビルドスクリプトの依存関係
target プラットフォーム特有の依存関係

Cargo.tomlとCargo.lock

cargo checkやcargo buildをするとCargo.tomlの他にCargo.lockというファイルが生成される。 Cargo.lockは外部クレートの依存関係に関する具体的な情報を含んでいる。

Cargo.lockははたくさんのクレートのバージョンが記録されているためエディタでファイルを開いて編集するようなものではない。