Cargo:Rust のビルドとパッケージマネージャー

Intermediate

This tutorial is from open-source community. Access the source code

はじめに

Hello, Cargoへようこそ。この実験はRust Bookの一部です。LabEx で Rust のスキルを練習することができます。

この実験では、Rust のビルドシステム兼パッケージマネージャである Cargo について学びます。Cargo は、Rust プロジェクトのコードビルド、依存関係管理、ライブラリのダウンロードなどのタスクを簡素化します。

これは Guided Lab です。学習と実践を支援するためのステップバイステップの指示を提供します。各ステップを完了し、実践的な経験を積むために、指示に注意深く従ってください。過去のデータによると、この 中級 レベルの実験の完了率は 80%です。学習者から 100% の好評価を得ています。

Hello, Cargo

Cargo は Rust のビルドシステム兼パッケージマネージャです。ほとんどの Rust プログラマはこのツールを使って Rust プロジェクトを管理しています。なぜなら、Cargo はコードのビルド、コードが依存するライブラリのダウンロード、そしてそれらのライブラリのビルドなど、たくさんのタスクを代行してくれるからです。(コードが必要とするライブラリを「依存関係」と呼びます。)

これまでに書いたような最もシンプルな Rust プログラムには、依存関係はありません。もし「Hello, world!」プロジェクトを Cargo でビルドした場合、Cargo のうちコードのビルドを担当する部分のみが使われます。より複雑な Rust プログラムを書くようになると、依存関係を追加するようになりますが、Cargo を使ってプロジェクトを始めると、依存関係の追加がはるかに簡単になります。

ほとんどの Rust プロジェクトが Cargo を使っているため、この本の残りの部分では、あなたも Cargo を使っていると仮定しています。もし「インストール」で説明した公式インストーラを使って Rust をインストールした場合、Cargo も一緒にインストールされます。もし他の方法で Rust をインストールした場合は、ターミナルに次のコマンドを入力して Cargo がインストールされているかどうかを確認してください。

cargo --version

バージョン番号が表示されれば、インストールされています!「コマンドが見つかりません」などのエラーが表示された場合は、インストール方法のドキュメントを見て、Cargo を個別にインストールする方法を確認してください。

Cargo を使ってプロジェクトを作成する

Cargo を使って新しいプロジェクトを作成し、最初の「Hello, world!」プロジェクトとどのように異なるか見てみましょう。projectディレクトリ(またはコードを保存する場所)に移動します。そして、どのオペレーティングシステムでも、次のコマンドを実行します。

cd ~/project
cargo new hello_cargo
cd hello_cargo

最初のコマンドは、新しいディレクトリと「hello_cargo」という名前のプロジェクトを作成します。私たちはプロジェクト名を「hello_cargo」とし、Cargo は同じ名前のディレクトリにファイルを作成します。

hello_cargoディレクトリに移動して、ファイルを一覧表示します。Cargo が私たちのために 2 つのファイルと 1 つのディレクトリを生成していることがわかります。Cargo.tomlファイルと、中にmain.rsファイルがあるsrcディレクトリです。

また、新しい Git リポジトリと.gitignoreファイルも初期化されています。既存の Git リポジトリ内でcargo newを実行すると、Git ファイルは生成されません。cargo new --vcs=gitを使うことで、この動作をオーバーライドできます。

注:Git は一般的なバージョン管理システムです。--vcsフラグを使うことで、cargo newを使って異なるバージョン管理システムまたはバージョン管理システムを使わないように変更できます。利用可能なオプションを見るには、cargo new --helpを実行してください。

好きなテキストエディタでCargo.tomlを開きます。リスト 1-2 のコードに似ているはずです。

ファイル名:Cargo.toml

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

[dependencies]

リスト 1-2:cargo newによって生成されたCargo.tomlの内容

このファイルはTOML(_Tom's Obvious, Minimal Language_)形式で、Cargo の設定形式です。

最初の行の[package]は、セクションの見出しで、次の文がパッケージを設定していることを示しています。このファイルにさらに情報を追加するにつれて、他のセクションを追加します。

次の 3 行は、Cargo がプログラムをコンパイルするために必要な設定情報を設定しています。名前、バージョン、および使用する Rust のエディションです。付録 E でeditionキーについて説明します。

最後の行の[dependencies]は、プロジェクトの依存関係をリストするセクションの始まりです。Rust では、コードのパッケージを「クレート」と呼びます。このプロジェクトでは他のクレートは必要ありませんが、第 2 章の最初のプロジェクトでは必要になりますので、そのときにこの依存関係セクションを使います。

次に、src/main.rsを開いて見てみましょう。

ファイル名:src/main.rs

fn main() {
    println!("Hello, world!");
}

Cargo があなたのために「Hello, world!」プログラムを生成してくれました。リスト 1-1 で書いたものと同じです!これまでのところ、私たちのプロジェクトと Cargo が生成したプロジェクトの違いは、Cargo がコードをsrcディレクトリに配置し、トップディレクトリにCargo.toml設定ファイルがあることです。

Cargo はソースファイルをsrcディレクトリの中に置くことを期待しています。トップレベルのプロジェクトディレクトリは、README ファイル、ライセンス情報、設定ファイル、その他コードに関係のないもの用の場所です。Cargo を使うことで、プロジェクトを整理するのが助けられます。物にはそれぞれ場所があり、すべてがその場所にあります。

「Hello, world!」プロジェクトのように、Cargo を使わないで始めたプロジェクトも、Cargo を使うプロジェクトに変換できます。プロジェクトコードをsrcディレクトリに移動し、適切なCargo.tomlファイルを作成します。

Cargo プロジェクトのビルドと実行

次に、Cargo を使って「Hello, world!」プログラムをビルドして実行するときの違いを見てみましょう!hello_cargoディレクトリから、次のコマンドを入力してプロジェクトをビルドします。

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

このコマンドは、実行可能ファイルを現在のディレクトリではなくtarget/debug/hello_cargoに作成します。デフォルトのビルドはデバッグビルドなので、Cargo はバイナリをdebugという名前のディレクトリに置きます。このコマンドで実行可能ファイルを実行できます。

$./target/debug/hello_cargo
Hello, world!

すべてがうまくいけば、「Hello, world!」がターミナルに表示されるはずです。最初にcargo buildを実行すると、Cargo がトップレベルに新しいファイルCargo.lockを作成することもあります。このファイルは、プロジェクトの依存関係の正確なバージョンを追跡します。このプロジェクトには依存関係がないので、ファイルは少し空っぽです。このファイルを手動で変更する必要はありません。Cargo がその内容を管理してくれます。

私たちは先ほどcargo buildでプロジェクトをビルドし、./target/debug/hello_cargoで実行しましたが、cargo runを使ってコードをコンパイルしてから、結果の実行可能ファイルを 1 つのコマンドで実行することもできます。

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

cargo runを使う方が、cargo buildを実行してからバイナリの完全なパスを使う必要を覚えるよりも便利なので、ほとんどの開発者はcargo runを使っています。

今回は、Cargo がhello_cargoをコンパイルしていることを示す出力が見られなかったことに注意してください。Cargo はファイルが変更されていないことを判断したので、再ビルドせずにバイナリを実行しました。ソースコードを変更していた場合、Cargo は実行前にプロジェクトを再ビルドし、次の出力が表示されました。

$ cargo run
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/hello_cargo`
Hello, world!

Cargo にはcargo checkというコマンドもあります。このコマンドは、コードがコンパイルできるかどうかを迅速に確認しますが、実行可能ファイルは生成しません。

$ cargo check
   Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

なぜ実行可能ファイルが必要ないのでしょうか?たいていの場合、cargo checkcargo buildよりもはるかに高速です。なぜなら、実行可能ファイルを生成するステップを省略するからです。コードを書いている間に作業を継続的に確認している場合、cargo checkを使うことで、プロジェクトがまだコンパイルできるかどうかを知らせるプロセスが高速化されます!そのため、多くの Rust プログラマは、プログラムを書いている間に定期的にcargo checkを実行して、コンパイルできることを確認します。そして、実行可能ファイルを使う準備ができたらcargo buildを実行します。

ここまでで学んだ Cargo についてのことをまとめましょう。

  • cargo newを使ってプロジェクトを作成できます。
  • cargo buildを使ってプロジェクトをビルドできます。
  • cargo runを使って 1 つのステップでプロジェクトをビルドして実行できます。
  • cargo checkを使って、エラーをチェックするためにバイナリを生成せずにプロジェクトをビルドできます。
  • ビルドの結果をコードと同じディレクトリに保存する代わりに、Cargo はそれをtarget/debugディレクトリに保存します。

Cargo を使うもう 1 つの利点は、どのオペレーティングシステムを使っているかに関係なく、コマンドが同じであることです。これ以降、Linux と macOS と Windows に関する特定の指示は不再提供します。

リリース用にビルドする

あなたのプロジェクトがついにリリースの準備ができたら、最適化を行ってコンパイルするにはcargo build --releaseを使うことができます。

cargo build --release

このコマンドは、実行可能ファイルをtarget/debugではなくtarget/releaseに作成します。最適化により、あなたの Rust コードがより速く実行されるようになりますが、最適化を有効にするとプログラムのコンパイルに時間がかかります。これが、2 つの異なるプロファイルがある理由です。1 つは、頻繁に再ビルドしたい開発用で、もう 1 つは、ユーザーに提供する最終的なプログラムをビルドするためのもので、これは繰り返し再ビルドされず、できるだけ速く実行されます。コードの実行時間をベンチマーク測定している場合は、必ずcargo build --releaseを実行し、target/releaseにある実行可能ファイルを使ってベンチマーク測定を行ってください。

慣例としての Cargo

シンプルなプロジェクトでは、Cargo はrustcを単に使うだけでは大きな価値を提供しませんが、プログラムがより複雑になるにつれてその価値が実証されるでしょう。プログラムが複数のファイルに成長したり、依存関係が必要になったりすると、Cargo がビルドを調整する方がはるかに簡単になります。

hello_cargoプロジェクトはシンプルですが、これまでに Rust キャリアの残りの部分で使う本格的なツールの多くを使っています。実際、既存の任意のプロジェクトを作業する場合、次のコマンドを使って Git を使ってコードをチェックアウトし、そのプロジェクトのディレクトリに移動してビルドすることができます。

git clone example.org/someproject
cd someproject
cargo build

Cargo に関する詳細は、https://doc.rust-lang.org/cargoのドキュメントを参照してください。

まとめ

おめでとうございます!あなたは Hello, Cargo の実験を完了しました。あなたの技術を向上させるために、LabEx でさらに多くの実験を行うことができます。