Rust dojo第34回を開催した

第34回です。前回はこちら。

kdnakt.hatenablog.com

 

 

[第34回の様子]

2022/04/06に第34回を開催した。

 

内容としてはRust By Example 日本語版の「11. クレート」、「11.1. Creating a Library」、「11.2. Using a Library」に取り組んだ。

 

参加者は7人。久しぶりに参加してくれた人がいてありがたい。

終わった後にSlackでまとめてくれてる人もいた。

f:id:kidani_a:20220407075020p:plain

 

[学んだこと]

  • 11. クレート
  • クレートはRustにおけるコンパイルの単位らしい:モジュールとの明確な違いがようやくわかった気がする
  • rustc some_file.rsコンパイルする時のコンパイル対象ファイルをクレートファイルという(ちょっと違うかも
    • このとき、some_file.rsにmod宣言があると、モジュールファイルの中身がこの位置に挿入されてからコンパイルが行われる
    • 参加者のC言語に詳しい人の説明によると、C言語のincludeと同様らしい
  • クレートはコンパイル時の--crate-typeフラグによって、結果がバイナリかライブラリ形式か変わる
  • 11.1. Creating a Library
  • rary.rsというファイルの中身が次のようになっている:モジュールの章で扱ったのとほぼ同じだ
pub fn public_function() {
    println!("called rary's `public_function()`");
}

fn private_function() {
    println!("called rary's `private_function()`");
}

pub fn indirect_access() {
    print!("called rary's `indirect_access()`, that\n> ");

    private_function();
}
$ rustc --crate-type=lib rary.rs // rary.rsをライブラリ形式でコンパイルする
$ ls lib*
library.rlib // lib+元のファイル名.rlibというファイルが出力される
  • 11.2. Using a Library
  • 作ったライブラリを使う場合はrustcコマンドの--externオプションを利用する
// executable.rsの中身
fn main() {
    rary::public_function();
    rary::indirect_access();
}

// library.rlibを利用してコンパイル
$ rustc executable.rs --extern rary=library.rlib --edition=2018
// バイナリを実行
$ ./executable
// 出力結果
called rary's `public_function()`
called rary's `indirect_access()`, that
> called rary's `private_function()`
  • テキストにはなかったが、ライブラリがライブラリに依存している場合はどうなるか?というのを試してみた
  • rary2.rsを以下の内容で作成する
pub fn public_function() {
    println!("called rary2's `public_function()`");
}
  • rary.rsからrary2.rsを呼び出す
pub fn public_function() {
    rary2::public_function(); // rary2の呼び出し
    println!("called rary's `public_function()`");
}
// rary2をライブラリ形式でコンパイル
$ rustc --crate-type=lib rary2.rs

// rary2を外部ライブラリとして指定して、raryをコンパイル
rustc --crate-type=lib rary.rs --extern rary2=library2.rlib

// 外部ライブラリを指定してコンパイル
rustc executable.rs --extern rary2=library2.rlib --extern rary=library.rlib --edition=2018 && ./executable

// 以下のコンパイルエラー
error[E0463]: can't find crate for `rary2` which `rary` depends on
 --> executable.rs:4:5
  |
4 |     rary::public_function();
  |     ^^^^ can't find crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
  • 同じやり方ではダメらしい
  • 試行錯誤した結果、ドキュメントの記載のある-Lオプションがうまくいった
// rary2をライブラリ形式でコンパイル
$ rustc --crate-type=lib rary2.rs

// rary2を外部ライブラリとして指定して、raryをコンパイル
rustc --crate-type=lib rary.rs --extern rary2=library2.rlib

// -Lオプションを指定してコンパイル
rustc executable.rs --extern rary2 --extern rary -L . --edition=2018 && ./executable

// 出力結果は以下の通り
called rary2's `public_function()`
called rary's `public_function()`
called rary's `indirect_access()`, that
> called rary's `private_function()`
  • そもそもrustcでコンパイルするんじゃなくてCargoとかのパッケージマネージャを使おう、という話ではあるようだ...

 

[まとめ]

モブプログラミングスタイルでRust dojoを開催した。

rustcでライブラリを扱う方法を学んだ。

 

今週のプルリクエストはこちら。

github.com