第36回です。前回はこちら。
[第36回の様子]
2022/04/20に第36回を開催した。
内容としてはRust By Example 日本語版の「12.4. Build Scripts」、「13. アトリビュート」、「13.1. dead_code」、「13.2. クレート」、「13.3. cfg」、「13.3.1. 条件の追加」に取り組んだ。
盛りだくさん!
参加者は7人。少しずつ増えてて嬉しい!
[学んだこと]
- 12.4. Build Scripts
- cargoでビルドする時に、追加の処理を実装したい場合はbuild.rsを実装するといいらしい
- あるいはCargo.tomlに以下のように記述する
[package] ... build = "build.rs"
- The Cargo Bookによると、こういう感じでC言語のソースコードをビルドしたりできるらしい
fn main() {
// Tell Cargo that if the given file changes, to rerun this build script.
println!("cargo:rerun-if-changed=src/hello.c");
// Use the `cc` crate to build a C file and statically link it.
cc::Build::new()
.file("src/hello.c")
.compile("hello");
}
- 13. アトリビュート
- アトリビュートは
#[item_attribute]または#![crate_attribute]のような形で記述する - 用途としては、コンパイル時の条件分岐やリントの無効化などに利用するメタデータとなる
- 確かにこれまでも何度か以下のようなコードが出てきていた
#[derive(Debug, PartialEq)] struct Structure(i32, i32); #[allow(non_camel_case_types)] type u64_t = u64; #[allow(dead_code)] struct Structure(i32);
- 13.1. dead_code
- デッドコードは
warning: function is never usedのような警告がコンパイル時にでる - 上でも出てきたように、
#[allow(dead_code)]をつけると、コンパイル時の警告がでなくなる - ライブラリなどのコードをクリーンに保つために、以下のようにデッドコードになったらコンパイルエラーにすることもできる
#[deny(dead_code)]
fn noisy_unused_function() {}
fn main() {
println!("hello world");
}
// 以下のコンパイルエラー
error: function is never used: `noisy_unused_function`
--> src/main.rs:9:4
|
9 | fn noisy_unused_function() {}
| ^^^^^^^^^^^^^^^^^^^^^
- 13.2. クレート
- アトリビュートを利用して、クレートのビルドを制御することもできる
- 以下のように、クレートの種別やライブラリ名を指定できる:が、cargoを使う場合はほとんど必要ない...
#![crate_type = "lib"] #![crate_name = "rary"]
// Linux OS用にのみコンパイルされる #[cfg(target_os = "linux")] fn are_you_on_linux() { println!("You are running linux!"); } // Linux以外のOS用にのみコンパイルされる #[cfg(not(target_os = "linux"))] fn are_you_on_linux() { println!("You are *not* running linux!"); }
- 実行時にチェックしたい場合は、cfgマクロを利用する
if cfg!(target_os = "linux") { println!("Yes. It's definitely linux!"); } else { println!("Yes. It's definitely *not* linux!"); }
- 13.3.1. 条件の追加
- target_osは、デフォルトでrustcが利用している条件である
- それ以外にも、独自の条件を追加できる
#[cfg(some_condition)]
fn conditional_function() {
println!("condition met!");
}
#[cfg(not(some_condition))]
fn conditional_function() {
println!("condition NOT met!");
}
fn main() {
conditional_function();
}
- 独自の条件を利用する場合はrustcに
--cfgフラグで伝える
$ rustc --cfg some_condition custom.rs
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
ビルド周りの細かい部分が少し理解できた気がする。あまり使わない気はするけど...。
今週のプルリクエストはこちら。